From 85ed45e377e0ee7bc193a95df732d75fcde880cc Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 22 Aug 1998 19:03:56 +0000 Subject: [PATCH] Release 980822 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sat Aug 22 17:46:19 1998 Ulrich Weigand * [include/dosexe.h] [include/module.h] [include/pe_image.h] [include/process.h] [include/windows.h] [loader/dos/module.c] [loader/module.c] [loader/ne/module.c] [loader/pe_image.c] [scheduler/process.c] [win32/process.c] Partially implemented CreateProcess32. * [win32/device.c] [relay32/kernel32.spec] [scheduler/k32obj.c] [misc/registry.c] [win32/file.c] Partially implemented VxDCall (VMM registry services). * [files/dos_fs.c] DOSFS_FindNext made thread-safe. * [include/sig_context.h] [include/syslevel.h] [loader/signal.c] [scheduler/syslevel.c] [tools/build.c] Replaced CALLTO16_Current_fs by SYSLEVEL_Win16CurrentTeb. * [win32/kernel32.c] Bugfix: QT_Thunk/FT_Thunk should return 'long' in DX:AX, not EAX. * [if1632/relay.c] [relay32/builtin32.c] [windows/msgbox.c] [msdos/int20.c] [msdos/int21.c] Use ExitProcess instead of TASK_KillCurrentTask. * [include/task.h] [include/thread.h] [loader/task.c] [scheduler/thread.c] [include/queue.h] [windows/message.c] [windows/queue.c] [windows/win.c] Prevent Win32 threads from entering the TASK_Reschedule loop. (Note: Win32 messaging still doesn't work correctly; this patch is just preventing the system from crashing when Win32 threads call messaging functions. Messages will probably still get lost.) * [scheduler/critsection.c] Deactivated the use of SEM_UNDO for the SYSTEM_LOCK semaphore; for some reason, this leads to problems after threads terminate... Sat Aug 22 15:00:00 1998 Jürgen Schmied * [include/authors.h] New file, includes all names of the developer (former shell.c) * [Makefile.in][configure][configure.in][dlls/Makefile.in] [dlls/shell32/Makefile.in][shres.rc] Created dlls/shell32 and moved the shell32 stuff in it. Started to create internal resources. * [dlls/shell32/*] Split the shell32 implementation into smaller files. New classes: IContextMenu, IExtractIcon, IShellView. Implemented Shell_GetImageList(). shell32 links to comctl32 now dynamically so it can use internal/external implementations. * [documentation/internal-dll] [documentation/shell32] New, could anybody do a spellcheck? * [include/commctrl.h] Many new LV constants, structures, functions. * [controls/comctl32undoc.c] Rewrote the DSA* functions. * [windows/winpos.c] SetShellWindow32, GetShellWindow32. Sat Aug 22 14:02:15 1998 Alexander Lukyanov * [loader/resource.c] Mark last accelerator as such in LoadAccelerators32W. * [relay32/shell32.spec] [misc/shell.c] Add stubs for SHGetSpecialFolderPath[AW]. Sat Aug 22 02:07:42 1998 Adrian Harvey * [include/file.h] [file/file.c] [msdos/int21.c] [msdos/vxd.c] [misc/lzexpand.c] [win32/kernel32.c] [documentation/filehandles] Fixed file handle handling. Created universal HFILE16 to HFILE32 translation macro from msdos/int21 code by Ove Kaaven. Used macro in all Win16 functions so that win32 handles are translated to avoid DOS/Win16 stdxx handles. Removed handle translation from int21.c where Win16 functions are called. Changed remaining calls to use new macro names. Documented filehandle handling and differences between win 16 & 32. Fri Aug 21 20:32:49 1998 Alexandre Julliard * [server/process.c] [server/thread.c] Implemented object wait queues and synchronization. Fri Aug 21 18:40:02 1998 Huw D M Davies * [graphics/psdrv/*] DEVMODE dmPaper{Width|Length} fields are in 0.1mm. Select a 100 pixel default font in CreateDC. Thu Aug 20 22:47:39 1998 Uwe Bonnes * [objects/bitmap.c] Handle bits=32 in SetBitmapBits32 and GetBitmapBits32. * [msdos/int21.c] Add handling of Int21 0A and 37. * [misc/commdlg.c] Use MapHModuleLS and MapHModuleSL when translating HINSTANCE16 to HINSTANCE32 and vice versa. * [win32/file.c] CreateFile32A: Abort if filename == NULL. Thu Aug 20 12:28:31 1998 Marcus Meissner * [*/*] Lots of missing prototypes added, some parameter types adapted to match SDK. * [debugger/stabs.c] Don't loop forever if we don't find wine or one of the libxxx.so. * [loader/ne/module.c] Implemented MapHModuleLS,MapHModuleSL,MapHinstLS,MapHinstSL. * [misc/network.c] Implemented WNetGetUser32A. * [misc/shellord.c] Implemented ILRemoveLastID. * [multimedia/dsound.c] Fixed StarCraft memory leak. * [graphics/ddraw.c] Removed some unnecessary simple relaying functions, tried polishing up the Xlib implementation (still doesn't work), temp. removed Xshm code (to be remerged with working Xlib code). Tue Aug 18 22:29:17 1998 Ove Kaaven * [multimedia/mmio.c] [multimedia/mmsystem.c] Fixed most mmio bugs, fully implementing mmioSetBuffer buffering, ability to read memory files, and the sndPlaySound() SND_MEMORY flag. Most mmio-using programs now work fine. * [include/dosexe.h] [include/miscemu.h] [include/module.h] [loader/module.c] [loader/task.c] [msdos/dosmem.c] Improved DOS VM flexibility and portability somewhat. (Did I get the #ifdefs right this time, BSD-ers?) * [msdos/int21.c] Made "Get Current PSP address" work as expected in a DOS VM. * [loader/dos/*] Began improving flexibility and portability somewhat. It should be easier to add DPMI RMCB callbacks now. The DOS VM no longer leaves big files lying around in /tmp after a crash. Tue Aug 18 12:38:31 1998 Turchanov Sergey * [relay32/winmm.spec] This patch allows WinAmp to play WAV files (at least in PCM format). Sun Aug 16 05:34:13 1998 Pablo Saratxaga * [windows/keyboard.c] Corrected keyboard code to properly handle keys : ? ~ and " on non US keyboards. Sat Aug 15 18:47:14 1998 Brian Craft * [windows/win.c] Fixed severe bug in EnumChildWindwos(). Thu Aug 13 21:05:35 1998 Eric Kohl * [controls/tooltips.c] Fixed some bugs. Added subclassing support. * [controls/toolbar.c] Improved tooltip integration. Fixed some bugs. * [controls/commctrl.c] Changed control registration and added some documentation. Fixed ShowHideMenuCtl. * [controls/rebar.c][include/rebar.h][include/commctrl.h] Improved rebar implementation (still no display). * [controls/pager.c][include/pager.h][include/commctrl.h] Improved pager implementation (still no display). * [misc/imagelist.c] Fixed a bug. * [documentation/common_controls] Updated. Sun Aug 9 19:50:20 1998 James Juran * [Makefile.in] [documentation/Makefile.in] [programs/Makefile.in] [programs/*/Makefile.in] Added uninstall rules, cleaned up install rules a little bit. Sun Aug 9 13:21:35 1998 Andreas Mohr <100.30936@germany.net> * [loader/ne/module.c] [if1632/kernel.spec] Added the undocumented HIWORD of GetModuleHandle (hFirstModule). * [loader/ne/segment.c] Wine forgot to set some NE_SEGFLAGS_*. Combined with another loader change, this fixed the "BLINKER -- error in loading module" or ghost MessageBox problem that about 1% of all Windows programs have. Some BLINKER programs still don't work, though. But I'm working on it, with great help from Blinkinc. * [loader/task.c] InitTask needs to decrement the SP register by two as Win95 does. Sun Aug 9 02:41:28 1998 Ulrich Weigand * [if1632/kernel.spec] [relay32/kernel32.spec] [scheduler/syslevel.c] [loader/main.c] [win32/ordinals.c] [include/syslevel.h] [scheduler/Makefile.in] Implemented Win95 'syslevel' routines (including Win16Lock). * [if1632/relay.c] [if1632/thunk.c] [tools/build.c] [loader/task.c] [loader/ne/segment.c] [win32/kernel32.c] [memory/selector.c] [include/stackframe.h] [include/thread.h] 16-bit %fs handling revised. Use Win16Lock where appropriate. * [include/thread.h] [scheduler/synchro.c] [windows/message.c] [windows/queue.c] [win32/process.c] Implemented MsgWaitForMultipleObjects. * [files/change.c] [files/Makefile.in] [scheduler/k32obj.c] [win32/newfns.c] Implemented (dummy) file change notification objects. * [debugger/dbg.y] [scheduler/process.c] [scheduler/thread.c] [include/process.h] [include/thread.h] Suspend all threads except current when hitting debugger break point. * [objects/dib.c] Bugfix for CreateDIBSection. --- ANNOUNCE | 21 +- ChangeLog | 236 +++ Makefile.in | 32 +- configure | 4 + configure.in | 2 + controls/comctl32undoc.c | 443 +++--- controls/commctrl.c | 165 ++- controls/menu.c | 4 +- controls/pager.c | 71 +- controls/rebar.c | 567 +++++++- controls/toolbar.c | 203 ++- controls/tooltips.c | 278 +++- debugger/stabs.c | 2 +- dlls/Makefile.in | 21 + dlls/shell32/Makefile.in | 30 + dlls/shell32/contmenu.c | 383 +++++ dlls/shell32/enumidlist.c | 357 +++++ dlls/shell32/folders.c | 224 +++ dlls/shell32/pidl.c | 846 +++++++++++ dlls/shell32/pidl.h | 31 + dlls/shell32/shell32_main.c | 962 +++++++++++++ dlls/shell32/shell32_main.h | 31 + dlls/shell32/shellole.c | 346 +++++ {misc => dlls/shell32}/shellord.c | 342 +---- dlls/shell32/shlfolder.c | 782 ++++++++++ dlls/shell32/shlview.c | 1185 +++++++++++++++ dlls/shell32/shres.rc | 21 + dlls/shell32/shresdef.h | 21 + documentation/Makefile.in | 6 + documentation/common_controls | 31 +- documentation/filehandles | 26 + documentation/internal-dll | 75 + documentation/shell32 | 71 + files/dos_fs.c | 206 +-- files/file.c | 20 +- files/profile.c | 8 +- graphics/ddraw.c | 1068 ++++---------- graphics/painting.c | 4 +- graphics/psdrv/driver.c | 6 +- graphics/psdrv/init.c | 16 +- graphics/x11drv/graphics.c | 2 +- if1632/gdi.spec | 2 +- if1632/keyboard.spec | 2 +- if1632/relay.c | 2 +- if1632/user.spec | 2 +- include/authors.h | 147 ++ include/commctrl.h | 403 +++++- include/ddraw.h | 30 +- include/debug.h | 105 +- include/debugdefs.h | 4 +- include/dosexe.h | 15 +- include/file.h | 11 + include/gdi.h | 2 +- include/header.h | 38 +- include/miscemu.h | 5 + include/module.h | 5 +- include/pager.h | 3 +- include/pe_image.h | 5 +- include/process.h | 2 +- include/queue.h | 2 + include/rebar.h | 30 +- include/server.h | 31 + include/server/object.h | 9 +- include/server/request.h | 6 + include/server/thread.h | 35 +- include/shell.h | 50 +- include/shlobj.h | 395 ++++- include/sig_context.h | 4 +- include/syslevel.h | 2 + include/task.h | 1 + include/thread.h | 2 + include/toolbar.h | 16 +- include/tooltips.h | 10 +- include/tweak.h | 4 +- include/version.h | 2 +- include/winbase.h | 4 +- include/windows.h | 133 +- include/winerror.h | 3 + include/wintypes.h | 2 + include/x11drv.h | 2 +- loader/dos/Makefile.in | 4 +- loader/dos/dosmod.c | 33 +- loader/dos/dosvm.c | 98 +- loader/dos/module.c | 133 +- loader/module.c | 296 +++- loader/ne/module.c | 55 + loader/ne/resource.c | 6 +- loader/pe_image.c | 33 +- loader/resource.c | 15 +- loader/signal.c | 3 - loader/task.c | 230 ++- misc/Makefile.in | 1 - misc/commdlg.c | 24 +- misc/imagelist.c | 12 +- misc/lstr.c | 1 + misc/lzexpand.c | 2 +- misc/network.c | 28 + misc/registry.c | 19 +- misc/shell.c | 1097 +------------- msdos/dosmem.c | 9 +- msdos/int20.c | 2 +- msdos/int21.c | 127 +- msdos/vxd.c | 2 +- multimedia/dsound.c | 3 +- multimedia/mmio.c | 289 +++- multimedia/mmsystem.c | 22 +- objects/bitmap.c | 33 +- objects/color.c | 2 + objects/dc.c | 21 + objects/font.c | 15 +- ole/Makefile.in | 1 - ole/folders.c | 2215 ----------------------------- ole/nls/nor.nls | 8 +- ole/ole2.c | 12 +- programs/Makefile.in | 3 + programs/clock/Makefile.in | 3 + programs/notepad/Makefile.in | 3 + programs/progman/Makefile.in | 3 + programs/regtest/Makefile.in | 5 +- programs/view/Makefile.in | 3 + programs/winhelp/Makefile.in | 3 + programs/winver/Makefile.in | 5 +- relay32/builtin32.c | 2 +- relay32/comctl32.spec | 6 +- relay32/gdi32.spec | 4 +- relay32/kernel32.spec | 28 +- relay32/mpr.spec | 2 +- relay32/ole32.spec | 2 +- relay32/shell32.spec | 11 +- relay32/snoop.c | 3 +- relay32/winmm.spec | 6 +- scheduler/client.c | 43 +- scheduler/critsection.c | 4 +- scheduler/k32obj.c | 3 +- scheduler/process.c | 65 +- scheduler/synchro.c | 50 +- scheduler/sysdeps.c | 2 + scheduler/syslevel.c | 6 + scheduler/thread.c | 44 +- server/object.c | 5 + server/process.c | 68 +- server/request.c | 34 +- server/socket.c | 6 +- server/thread.c | 244 ++++ server/trace.c | 32 + tools/build.c | 8 +- tools/make_requests | 6 +- tools/testrun | 25 - win32/device.c | 581 +++++++- win32/file.c | 7 +- win32/kernel32.c | 12 +- win32/newfns.c | 26 - win32/ordinals.c | 1 - win32/process.c | 44 - win32/time.c | 10 - windows/keyboard.c | 26 +- windows/mdi.c | 20 + windows/message.c | 15 +- windows/msgbox.c | 4 +- windows/queue.c | 78 +- windows/win.c | 47 +- windows/winpos.c | 14 +- windows/winproc.c | 2 + 163 files changed, 11364 insertions(+), 5786 deletions(-) create mode 100644 dlls/Makefile.in create mode 100644 dlls/shell32/Makefile.in create mode 100644 dlls/shell32/contmenu.c create mode 100644 dlls/shell32/enumidlist.c create mode 100644 dlls/shell32/folders.c create mode 100644 dlls/shell32/pidl.c create mode 100644 dlls/shell32/pidl.h create mode 100644 dlls/shell32/shell32_main.c create mode 100644 dlls/shell32/shell32_main.h create mode 100644 dlls/shell32/shellole.c rename {misc => dlls/shell32}/shellord.c (71%) create mode 100644 dlls/shell32/shlfolder.c create mode 100644 dlls/shell32/shlview.c create mode 100644 dlls/shell32/shres.rc create mode 100644 dlls/shell32/shresdef.h create mode 100644 documentation/filehandles create mode 100644 documentation/internal-dll create mode 100644 documentation/shell32 create mode 100644 include/authors.h delete mode 100644 ole/folders.c diff --git a/ANNOUNCE b/ANNOUNCE index 303c5bd474b..5c0bea14207 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,16 +1,15 @@ -This is release 980809 of Wine, the MS Windows emulator. This is still a +This is release 980822 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-980809: (see ChangeLog for details) - - Preliminary DOS executables support. - - Postscript driver improvements. - - More client/server stuff. - - Better shell32.dll builtin support. - - Proper Win16 mutex locking. +WHAT'S NEW with Wine-980822: (see ChangeLog for details) + - Improved mmio support. + - VxDCall support. + - More common controls and shell32 stuff. + - Better DOS executables support. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -19,10 +18,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-980809.tar.gz - ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980809.tar.gz - ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980809.tar.gz - ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980809.tar.gz + ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980822.tar.gz + ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980822.tar.gz + ftp://ftp.infomagic.com/pub/mirrors/linux/sunsite/ALPHA/wine/development/Wine-980822.tar.gz + ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980822.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index bd9cb45e943..b6e4c549adb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,212 @@ +---------------------------------------------------------------------- +Sat Aug 22 17:46:19 1998 Ulrich Weigand + + * [include/dosexe.h] [include/module.h] [include/pe_image.h] + [include/process.h] [include/windows.h] [loader/dos/module.c] + [loader/module.c] [loader/ne/module.c] [loader/pe_image.c] + [scheduler/process.c] [win32/process.c] + Partially implemented CreateProcess32. + + * [win32/device.c] [relay32/kernel32.spec] [scheduler/k32obj.c] + [misc/registry.c] [win32/file.c] + Partially implemented VxDCall (VMM registry services). + + * [files/dos_fs.c] + DOSFS_FindNext made thread-safe. + + * [include/sig_context.h] [include/syslevel.h] [loader/signal.c] + [scheduler/syslevel.c] [tools/build.c] + Replaced CALLTO16_Current_fs by SYSLEVEL_Win16CurrentTeb. + + * [win32/kernel32.c] + Bugfix: QT_Thunk/FT_Thunk should return 'long' in DX:AX, not EAX. + + * [if1632/relay.c] [relay32/builtin32.c] [windows/msgbox.c] + [msdos/int20.c] [msdos/int21.c] + Use ExitProcess instead of TASK_KillCurrentTask. + + * [include/task.h] [include/thread.h] [loader/task.c] + [scheduler/thread.c] [include/queue.h] [windows/message.c] + [windows/queue.c] [windows/win.c] + Prevent Win32 threads from entering the TASK_Reschedule loop. + (Note: Win32 messaging still doesn't work correctly; this patch + is just preventing the system from crashing when Win32 threads + call messaging functions. Messages will probably still get lost.) + + * [scheduler/critsection.c] + Deactivated the use of SEM_UNDO for the SYSTEM_LOCK semaphore; + for some reason, this leads to problems after threads terminate... + +Sat Aug 22 15:00:00 1998 Jürgen Schmied + + * [include/authors.h] + New file, includes all names of the developer (former shell.c) + + * [Makefile.in][configure][configure.in][dlls/Makefile.in] + [dlls/shell32/Makefile.in][shres.rc] + Created dlls/shell32 and moved the shell32 stuff in it. + Started to create internal resources. + + * [dlls/shell32/*] + Split the shell32 implementation into smaller files. + New classes: IContextMenu, IExtractIcon, IShellView. + Implemented Shell_GetImageList(). + shell32 links to comctl32 now dynamically so it can use + internal/external implementations. + + * [documentation/internal-dll] [documentation/shell32] + New, could anybody do a spellcheck? + + * [include/commctrl.h] + Many new LV constants, structures, functions. + + * [controls/comctl32undoc.c] + Rewrote the DSA* functions. + + * [windows/winpos.c] + SetShellWindow32, GetShellWindow32. + +Sat Aug 22 14:02:15 1998 Alexander Lukyanov + + * [loader/resource.c] + Mark last accelerator as such in LoadAccelerators32W. + + * [relay32/shell32.spec] [misc/shell.c] + Add stubs for SHGetSpecialFolderPath[AW]. + +Sat Aug 22 02:07:42 1998 Adrian Harvey + + * [include/file.h] [file/file.c] [msdos/int21.c] [msdos/vxd.c] + [misc/lzexpand.c] [win32/kernel32.c] [documentation/filehandles] + Fixed file handle handling. Created universal HFILE16 to HFILE32 + translation macro from msdos/int21 code by Ove Kaaven. + Used macro in all Win16 functions so that win32 handles are translated + to avoid DOS/Win16 stdxx handles. + Removed handle translation from int21.c where Win16 functions are + called. Changed remaining calls to use new macro names. + Documented filehandle handling and differences between win 16 & 32. + +Fri Aug 21 20:32:49 1998 Alexandre Julliard + + * [server/process.c] [server/thread.c] + Implemented object wait queues and synchronization. + +Fri Aug 21 18:40:02 1998 Huw D M Davies + + * [graphics/psdrv/*] + DEVMODE dmPaper{Width|Length} fields are in 0.1mm. + Select a 100 pixel default font in CreateDC. + +Thu Aug 20 22:47:39 1998 Uwe Bonnes + + * [objects/bitmap.c] + Handle bits=32 in SetBitmapBits32 and GetBitmapBits32. + + * [msdos/int21.c] + Add handling of Int21 0A and 37. + + * [misc/commdlg.c] + Use MapHModuleLS and MapHModuleSL when translating HINSTANCE16 to + HINSTANCE32 and vice versa. + + * [win32/file.c] + CreateFile32A: Abort if filename == NULL. + +Thu Aug 20 12:28:31 1998 Marcus Meissner + + * [*/*] + Lots of missing prototypes added, some parameter types adapted to match + SDK. + + * [debugger/stabs.c] + Don't loop forever if we don't find wine or one of the libxxx.so. + + * [loader/ne/module.c] + Implemented MapHModuleLS,MapHModuleSL,MapHinstLS,MapHinstSL. + + * [misc/network.c] + Implemented WNetGetUser32A. + + * [misc/shellord.c] + Implemented ILRemoveLastID. + + * [multimedia/dsound.c] + Fixed StarCraft memory leak. + + * [graphics/ddraw.c] + Removed some unnecessary simple relaying functions, tried polishing + up the Xlib implementation (still doesn't work), temp. removed Xshm + code (to be remerged with working Xlib code). + +Tue Aug 18 22:29:17 1998 Ove Kaaven + + * [multimedia/mmio.c] [multimedia/mmsystem.c] + Fixed most mmio bugs, fully implementing mmioSetBuffer + buffering, ability to read memory files, and the + sndPlaySound() SND_MEMORY flag. Most mmio-using programs + now work fine. + + * [include/dosexe.h] [include/miscemu.h] [include/module.h] + [loader/module.c] [loader/task.c] [msdos/dosmem.c] + Improved DOS VM flexibility and portability somewhat. (Did + I get the #ifdefs right this time, BSD-ers?) + + * [msdos/int21.c] + Made "Get Current PSP address" work as expected in a DOS VM. + + * [loader/dos/*] + Began improving flexibility and portability somewhat. It + should be easier to add DPMI RMCB callbacks now. The + DOS VM no longer leaves big files lying around in /tmp + after a crash. + +Tue Aug 18 12:38:31 1998 Turchanov Sergey + + * [relay32/winmm.spec] + This patch allows WinAmp to play WAV files (at least in PCM + format). + +Sun Aug 16 05:34:13 1998 Pablo Saratxaga + + * [windows/keyboard.c] + Corrected keyboard code to properly handle keys : ? ~ and " + on non US keyboards. + +Sat Aug 15 18:47:14 1998 Brian Craft + + * [windows/win.c] + Fixed severe bug in EnumChildWindwos(). + +Thu Aug 13 21:05:35 1998 Eric Kohl + + * [controls/tooltips.c] + Fixed some bugs. Added subclassing support. + + * [controls/toolbar.c] + Improved tooltip integration. Fixed some bugs. + + * [controls/commctrl.c] + Changed control registration and added some documentation. + Fixed ShowHideMenuCtl. + + * [controls/rebar.c][include/rebar.h][include/commctrl.h] + Improved rebar implementation (still no display). + + * [controls/pager.c][include/pager.h][include/commctrl.h] + Improved pager implementation (still no display). + + * [misc/imagelist.c] + Fixed a bug. + + * [documentation/common_controls] + Updated. + +Sun Aug 9 19:50:20 1998 James Juran + + * [Makefile.in] [documentation/Makefile.in] + [programs/Makefile.in] [programs/*/Makefile.in] + Added uninstall rules, cleaned up install rules a little bit. + ---------------------------------------------------------------------- Sun Aug 9 13:21:35 1998 Andreas Mohr <100.30936@germany.net> @@ -15,6 +224,33 @@ Sun Aug 9 13:21:35 1998 Andreas Mohr <100.30936@germany.net> * [loader/task.c] InitTask needs to decrement the SP register by two as Win95 does. +Sun Aug 9 02:41:28 1998 Ulrich Weigand + + * [if1632/kernel.spec] [relay32/kernel32.spec] [scheduler/syslevel.c] + [loader/main.c] [win32/ordinals.c] [include/syslevel.h] + [scheduler/Makefile.in] + Implemented Win95 'syslevel' routines (including Win16Lock). + + * [if1632/relay.c] [if1632/thunk.c] [tools/build.c] [loader/task.c] + [loader/ne/segment.c] [win32/kernel32.c] [memory/selector.c] + [include/stackframe.h] [include/thread.h] + 16-bit %fs handling revised. Use Win16Lock where appropriate. + + * [include/thread.h] [scheduler/synchro.c] [windows/message.c] + [windows/queue.c] [win32/process.c] + Implemented MsgWaitForMultipleObjects. + + * [files/change.c] [files/Makefile.in] [scheduler/k32obj.c] + [win32/newfns.c] + Implemented (dummy) file change notification objects. + + * [debugger/dbg.y] [scheduler/process.c] [scheduler/thread.c] + [include/process.h] [include/thread.h] + Suspend all threads except current when hitting debugger break point. + + * [objects/dib.c] + Bugfix for CreateDIBSection. + Sat Aug 8 19:11:46 1998 Marcus Meissner * [*/*] diff --git a/Makefile.in b/Makefile.in index 52a3b6ac8ef..3f88e15e2f6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5,6 +5,7 @@ # clean: remove all intermediate files # distclean: also remove all files created by configure # install: install everything +# uninstall: uninstall everything # depend: create the dependencies # etags: create a TAGS file for Emacs. # manpages: compile manpages for Wine API @@ -26,6 +27,7 @@ LIBSUBDIRS = \ tools \ tools/wrc \ controls \ + dlls/shell32 \ files \ graphics \ graphics/metafiledrv \ @@ -75,6 +77,7 @@ INSTALLSUBDIRS = $(DOCSUBDIRS) LIBOBJS = \ controls/controls.o \ + dlls/shell32/shell32.o \ files/files.o \ graphics/graphics.o \ graphics/metafiledrv/metafiledrv.o \ @@ -112,6 +115,8 @@ all: $(MAIN_TARGET) install:: install_$(MAIN_TARGET) +uninstall:: uninstall_$(MAIN_TARGET) + emu: wine lib: $(LIBSUBDIRS) $(LIB_TARGET) @@ -129,28 +134,47 @@ libwine.so.1.0: $(LIBOBJS) $(CC) -shared -Wl,-soname,libwine.so -o$@ $(LIBOBJS) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) install_emu: install_lib - -mkdirhier $(bindir) - -mkdirhier $(libdir) + [ -d $(bindir) ] || $(MKDIR) $(bindir) $(INSTALL_PROGRAM) wine $(bindir)/wine - $(INSTALL_DATA) wine.sym $(libdir)/wine.sym $(INSTALL_PROGRAM) loader/dos/dosmod $(bindir)/dosmod +uninstall_emu: uninstall_lib + $(RM) $(bindir)/wine $(bindir)/dosmod + install_lib: install_includes + [ -d $(libdir) ] || $(MKDIR) $(libdir) $(INSTALL_DATA) $(LIB_TARGET) $(libdir) + $(INSTALL_DATA) wine.sym $(libdir)/wine.sym + +uninstall_lib: uninstall_includes + cd $(libdir); $(RM) $(LIB_TARGET) + $(RM) $(libdir)/wine.sym install_includes: dummy - if [ -d $(includedir) ]; then : ; else $(MKDIR) $(includedir); fi + [ -d $(includedir) ] || $(MKDIR) $(includedir) cd $(TOPSRCDIR)/include; $(INSTALL_DATA) windows.h wintypes.h $(includedir) +# Don't just do a rm -rf on $(includedir) -- don't want to wipe out +# anything extra the user may have put there. +uninstall_includes: dummy + $(RM) $(includedir)/windows.h $(includedir)/wintypes.h + -rmdir $(includedir) + $(ALLSUBDIRS): dummy @cd $@; $(SUBMAKE) install_programs: dummy @cd programs; $(SUBMAKE) install +uninstall_programs: dummy + @cd programs; $(SUBMAKE) uninstall + install:: for i in $(INSTALLSUBDIRS); do (cd $$i && $(MAKE) install) || exit 1; done +uninstall:: + for i in $(INSTALLSUBDIRS); do (cd $$i && $(MAKE) uninstall) || exit 1; done + depend:: dummy for i in $(DEPENDSUBDIRS); do (cd $$i && $(MAKE) depend) || exit 1; done diff --git a/configure b/configure index 840938e6dc9..4c6f44cdcf5 100755 --- a/configure +++ b/configure @@ -3396,6 +3396,8 @@ Make.rules Makefile controls/Makefile debugger/Makefile +dlls/Makefile +dlls/shell32/Makefile documentation/Makefile files/Makefile graphics/Makefile @@ -3531,6 +3533,8 @@ CONFIG_FILES=\${CONFIG_FILES-"Make.rules Makefile controls/Makefile debugger/Makefile +dlls/Makefile +dlls/shell32/Makefile documentation/Makefile files/Makefile graphics/Makefile diff --git a/configure.in b/configure.in index 19731dfbd84..cf1d4147543 100644 --- a/configure.in +++ b/configure.in @@ -460,6 +460,8 @@ Make.rules Makefile controls/Makefile debugger/Makefile +dlls/Makefile +dlls/shell32/Makefile documentation/Makefile files/Makefile graphics/Makefile diff --git a/controls/comctl32undoc.c b/controls/comctl32undoc.c index 7027960582d..aa5c83dc97b 100644 --- a/controls/comctl32undoc.c +++ b/controls/comctl32undoc.c @@ -2,7 +2,7 @@ * Undocumented functions from COMCTL32.DLL * * Copyright 1998 Eric Kohl - * + * 1998 Juergen Schmied * NOTES * All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!! * Do NOT rely on names or contents of undocumented structures and types!!! @@ -22,17 +22,6 @@ #include "heap.h" #include "debug.h" - -typedef struct _DSA_DATA -{ - DWORD dwEntryCount; - DWORD dwMaxCount; - DWORD dwInitial; - DWORD dwGrow; - LPSTR *ptrs; -} DSA_DATA, *LPDSA_DATA; - - typedef struct _DPA_DATA { DWORD dwEntryCount; @@ -47,22 +36,30 @@ DWORD WINAPI DPA_GetPtr (DWORD, DWORD); DWORD WINAPI DPA_InsertPtr (DWORD, DWORD, DWORD); - - +CRITICAL_SECTION cs_comctl_alloc; +HANDLE32 hComctl32Heap=0; /************************************************************************** * Alloc [COMCTL32.71] * */ -LPVOID WINAPI -COMCTL32_Alloc (DWORD dwParam) -{ - LPVOID lpPtr; +LPVOID WINAPI COMCTL32_Alloc (DWORD dwParam) +{ LPVOID lpPtr; - lpPtr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, dwParam); + TRACE (commctrl, "(0x%08lx)\n", dwParam); - TRACE (commctrl, "(0x%08lx) ret=0x%08lx\n", dwParam, (DWORD)lpPtr); + if (hComctl32Heap==0) + { EnterCriticalSection((void*)&cs_comctl_alloc); + hComctl32Heap=HeapCreate(0,1,0x4000000); + LeaveCriticalSection((void*)&cs_comctl_alloc); + TRACE (commctrl, "Heap created: 0x%08x\n", hComctl32Heap); + if (! hComctl32Heap) + return FALSE; + } +// lpPtr = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, dwParam); + lpPtr = HeapAlloc (hComctl32Heap, HEAP_ZERO_MEMORY, dwParam); + TRACE (commctrl, "-- ret=%p\n", lpPtr); return lpPtr; } @@ -76,16 +73,16 @@ LPVOID WINAPI COMCTL32_ReAlloc (LPVOID dwParam1, DWORD dwParam2) { LPVOID dwPtr; - + TRACE (commctrl, "(0x%08lx 0x%08lx)\n",(DWORD)dwParam1, dwParam2); + if (dwParam1 == 0) - dwPtr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + dwPtr = HeapAlloc (hComctl32Heap, HEAP_ZERO_MEMORY, dwParam2); else - dwPtr = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + dwPtr = HeapReAlloc (hComctl32Heap, HEAP_ZERO_MEMORY, dwParam1, dwParam2); - TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n", - (DWORD)dwParam1, dwParam2, (DWORD)dwPtr); + TRACE (commctrl, "-- ret=0x%08lx\n", (DWORD)dwPtr); return dwPtr; } @@ -100,7 +97,7 @@ DWORD WINAPI COMCTL32_Free (LPVOID dwParam) { TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam); - HeapFree (GetProcessHeap (), 0, dwParam); + HeapFree (hComctl32Heap, 0, dwParam); return 0; } @@ -115,7 +112,7 @@ DWORD WINAPI COMCTL32_GetSize (LPVOID dwParam) { TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam); - return (HeapSize (GetProcessHeap (), 0, dwParam)); + return (HeapSize (hComctl32Heap, 0, dwParam)); } @@ -155,217 +152,283 @@ COMCTL32_Str_SetPtrA (LPSTR lpStr, LPVOID *lpPtr) return FALSE; } - +/************************************************************************* +* The DSA-API is a set of functions to create and manipulate arrays of +* fix sized memory blocks. This arrays can store any kind of data (strings, +* icons...) so the name "dynamic string array" is a bit misleading. +* +* STATUS +* complete +*/ +typedef struct _DSA_DATA +{ DWORD dwEntryCount; + BYTE * pData; + DWORD dwMaxCount; + DWORD dwElementSize; + DWORD dwGrow; +} DSA_DATA, *LPDSA_DATA; /************************************************************************** * DSA_Create [COMCTL32.320] Creates a dynamic string array * * PARAMS - * dwParam1 [I] - * dwParam2 [I] + * dwSize [I] size of the array elements + * dwGrow [I] + * RETURNS + * pointer to a array control structure. use this like a handle. */ -DWORD WINAPI -DSA_Create (DWORD dwParam1, DWORD dwParam2) -{ - LPDSA_DATA dsaPtr; +LPDSA_DATA WINAPI DSA_Create (DWORD dwSize, DWORD dwGrow) +{ LPDSA_DATA dsaPtr; - dsaPtr = (LPDSA_DATA)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - sizeof(DSA_DATA)); - dsaPtr->dwInitial = dwParam1; - dsaPtr->dwGrow = dwParam2; + TRACE (commctrl, "(size=0x%08lx grow=0x%08lx)\n", dwSize, dwGrow); - TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n", - dwParam1, dwParam2, (DWORD)dsaPtr); - - return (DWORD)dsaPtr; + if ((dsaPtr=(LPDSA_DATA)COMCTL32_Alloc(sizeof(DSA_DATA)))); + { dsaPtr->dwEntryCount=0x00; + dsaPtr->pData=NULL; + dsaPtr->dwMaxCount=0x00; + dsaPtr->dwElementSize=dwSize; + if ( dwGrow == 0 ) + dsaPtr->dwGrow=1; + else + dsaPtr->dwGrow=dwGrow; + return dsaPtr; + } + return FALSE; } - /************************************************************************** * DSA_Destroy [COMCTL32.321] Destroys a dynamic string array * * PARAMS - * dwParam1 [I] + * dsaPtr [I] pointer to the array control structure + * RETURNS + * TRUE if dsaPtr = NULL or success + * FALSE if failure */ -DWORD WINAPI -DSA_Destroy (DWORD dwParam1) -{ - LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1; - DWORD i; +BOOL32 WINAPI DSA_Destroy (const LPDSA_DATA dsaPtr ) +{ TRACE (commctrl, "(%p)\n", dsaPtr); - TRACE (commctrl, "(0x%08lx):semi-stub!\n", dwParam1); + if (! dsaPtr) + return FALSE; - if (dsaPtr->ptrs) { - for (i = 0; i < dsaPtr->dwEntryCount; i++) { - if (dsaPtr->ptrs[i]) - HeapFree (GetProcessHeap (), 0, (LPSTR)dsaPtr->ptrs[i]); - } + if (dsaPtr->pData && (! COMCTL32_Free(dsaPtr->pData))) + { return FALSE; } - - HeapFree (GetProcessHeap (), 0, dsaPtr); - - return 0; + return COMCTL32_Free (dsaPtr); } +/************************************************************************** + * DSA_GetItem [COMCTL32.322] + * + * PARAMS + * dsaPtr [I] pointer to the array control structure + * dwItem [I] number of the Item to get ++ * pDest [O] destination buffer. Has to be >= dwElementSize. + */ -DWORD WINAPI -DSA_GetItem (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) -{ - LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1; +BOOL32 WINAPI DSA_GetItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pDest) +{ BYTE * pSrc; - FIXME (commctrl, "(0x%08lx 0x%08lx 0x%08lx): stub!\n", - dwParam1, dwParam2, dwParam3); - - if (dsaPtr == NULL) - return 0; - if (dsaPtr->ptrs == NULL) - return 0; - if ((dwParam2 < 0) || (dwParam2 >= dsaPtr->dwEntryCount)) - return 0; - -// FIXME (commctrl, "\"%s\"\n", (LPSTR)dsaPtr->ptrs[dwParam2]); - - return (DWORD)lstrcpy32A ((LPSTR)dwParam3, (LPSTR)dsaPtr->ptrs[dwParam2]); + TRACE (commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pDest); + + if ( (!dsaPtr) || (dwItem < 0) || (dwItem >= dsaPtr->dwEntryCount)) + return FALSE; + + pSrc = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem); + memmove(pDest,pSrc,dsaPtr->dwElementSize); + return TRUE; } +/************************************************************************** + * DSA_GetItemPtr [COMCTL32.323] + * + * PARAMS + * dsaPtr [I] pointer to the array control structure + * dwItem [I] number of the Item to get + * RETURNS + * pointer ti a item + */ +LPBYTE WINAPI DSA_GetItemPtr (const LPDSA_DATA dsaPtr, DWORD dwItem) +{ BYTE * pSrc; -DWORD WINAPI -DSA_GetItemPtr (DWORD dwParam1, DWORD dwParam2) -{ - LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1; + TRACE (commctrl, "(%p 0x%08lx)\n", dsaPtr, dwItem); - TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2); + if ((!dsaPtr) || (dwItem < 0) || (dwItem >= dsaPtr->dwEntryCount)) + return FALSE; + pSrc = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem); + + TRACE (commctrl, "-- ret=%p\n", pSrc); - if (dsaPtr == NULL) - return 0; - if (dsaPtr->ptrs == NULL) - return 0; - if ((dwParam2 < 0) || (dwParam2 >= dsaPtr->dwEntryCount)) - return 0; - - TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dsaPtr->ptrs[dwParam2]); - - return (DWORD)dsaPtr->ptrs[dwParam2]; + return pSrc; } +/************************************************************************** + * DSA_SetItem [COMCTL32.325] + * + * PARAMS + * dsaPtr [I] pointer to the array control structure + * dwItem [I] index for the new element + * pSrc [I] the element + */ +BOOL32 WINAPI DSA_SetItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pSrc) +{ LPBYTE pDest; + DWORD dwSize, dwNewItems; + LPBYTE lpTemp; + + TRACE (commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pSrc); -DWORD WINAPI -DSA_InsertItem (DWORD dwParam1, DWORD dwParam2, LPSTR lpString) -{ - LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1; - DWORD dwIndex; - INT32 len; - - TRACE (commctrl, "(0x%08lx 0x%08lx \"%s\"):semi-stub!\n", - dwParam1, dwParam2, lpString); - - if (dsaPtr->ptrs == NULL) { - dsaPtr->ptrs = (LPSTR*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - dsaPtr->dwInitial * sizeof(LPVOID)); - dsaPtr->dwMaxCount = dsaPtr->dwInitial; - dwIndex = 0; - len = lstrlen32A (lpString); - dsaPtr->ptrs[dwIndex] = - (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1); - lstrcpy32A (dsaPtr->ptrs[dwIndex], lpString); + if ((!dsaPtr) || dwItem<0 ) + return FALSE; + + if (dsaPtr->dwEntryCount <= dwItem) /* within the old array */ + { if ( dsaPtr->dwMaxCount > dwItem) + { dsaPtr->dwEntryCount = dwItem; /* within the allocated space, set a new boundary */ + } + else + { /* resize the block of memory*/ + dwNewItems = dsaPtr->dwGrow * ( (WORD)((dwItem-1)/dsaPtr->dwGrow) +1); + dwSize = dsaPtr->dwElementSize * dwNewItems; + lpTemp = (LPBYTE) COMCTL32_ReAlloc(dsaPtr->pData,dwSize); + if (! lpTemp ) + { return FALSE; + } + dsaPtr->dwMaxCount = dwNewItems; + dsaPtr->pData = lpTemp; + } } - else { - TRACE (commctrl, "(0x%08lx 0x%08lx)\n", - dsaPtr->dwEntryCount, dsaPtr->dwMaxCount); - if (dwParam2 >= dsaPtr->dwEntryCount) { - if (dsaPtr->dwEntryCount < dsaPtr->dwMaxCount) { - dwIndex = dsaPtr->dwEntryCount; - len = lstrlen32A (lpString); - dsaPtr->ptrs[dwIndex] = - (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1); - lstrcpy32A (dsaPtr->ptrs[dwIndex], lpString); - } - else { - /* allocate new pointer list and copy all pointers */ - LPSTR *lpOldPtrs = dsaPtr->ptrs; - dsaPtr->ptrs = (LPSTR*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, - (dsaPtr->dwInitial + dsaPtr->dwGrow) * - sizeof(LPVOID)); - memcpy (dsaPtr->ptrs, lpOldPtrs, - dsaPtr->dwMaxCount * sizeof(LPVOID)); - dsaPtr->dwMaxCount += dsaPtr->dwGrow; - HeapFree (GetProcessHeap (), 0, lpOldPtrs); + /* put the new entry in */ + pDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem); + TRACE (commctrl,"move dest=%p src=%p size=%x",pDest,pSrc,dsaPtr->dwElementSize); + memmove(pDest,pSrc,dsaPtr->dwElementSize); + return TRUE; +} - /* add new string */ - dwIndex = dsaPtr->dwEntryCount; - len = lstrlen32A (lpString); - dsaPtr->ptrs[dwIndex] = - (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1); - lstrcpy32A (dsaPtr->ptrs[dwIndex], lpString); - } - } - else { - FIXME (commctrl, "inserting! stub!\n"); +/************************************************************************** + * DSA_InsertItem [COMCTL32.325] + * + * PARAMS + * dsaPtr [I] pointer to the array control structure + * dwItem [I] index for the new element + * pSrc [I] the element + * + * RETURNS + * the position of the new element + */ +DWORD WINAPI DSA_InsertItem (const LPDSA_DATA dsaPtr, DWORD dwItem, LPBYTE pSrc) +{ DWORD dwNewItems, dwSize,i; + LPBYTE lpTemp, lpDest; + LPDWORD p; + + TRACE(commctrl, "(%p 0x%08lx %p)\n", dsaPtr, dwItem, pSrc); - dwIndex = dwParam2; - } + if ( (!dsaPtr) || dwItem<0 ) + return -1; + + for (i=0; idwElementSize;i+=4) + { p = *(DWORD**)(pSrc+i); + if ( IsBadStringPtr32A ((char*)p,256)) + { TRACE(commctrl,"-- 0x%04lx=%p\n",i,(DWORD*)p); + } + else + { TRACE(commctrl,"-- 0x%04lx=%p [%s]\n",i,p,debugstr_a((char*)p)); + } + } + + if (dwItem > dsaPtr->dwEntryCount) /* when dwItem > dwEntryCount then append*/ + dwItem = dsaPtr->dwEntryCount+1; + + if (dwItem >= dsaPtr->dwMaxCount) /* do we need to resize ? */ + { dwNewItems = dsaPtr->dwMaxCount + dsaPtr->dwGrow; + dwSize = dsaPtr->dwElementSize * dwNewItems; + lpTemp = (LPBYTE)COMCTL32_ReAlloc(dsaPtr->pData,dwSize); + if (!lpTemp) + { return -1; + } + dsaPtr->dwMaxCount = dwNewItems; + dsaPtr->pData = lpTemp; } + if (dwItem < dsaPtr->dwEntryCount) /* do we need to move elements ?*/ + { lpTemp = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem); + lpDest = lpTemp + dsaPtr->dwElementSize; + TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,lpTemp,dsaPtr->dwElementSize); + memmove (lpDest,lpTemp,dsaPtr->dwElementSize); + } + /* ok, we can put the new Item in*/ dsaPtr->dwEntryCount++; - - TRACE (commctrl, "ret=0x%08lx\n", dwIndex); - - return (dwIndex); + lpDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem); + TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,pSrc,dsaPtr->dwElementSize); + memmove (lpDest,pSrc,dsaPtr->dwElementSize); + return dsaPtr->dwEntryCount; } +/************************************************************************** + * DSA_DeleteItem [COMCTL32.326] + * + * PARAMS + * dsaPtr [I] pointer to the array control structure + * dwItem [I] index for the element to delete + * RETURNS + * number of the element deleted + */ +DWORD WINAPI DSA_DeleteItem (const LPDSA_DATA dsaPtr, DWORD dwItem) +{ LPBYTE lpDest,lpSrc; + DWORD dwSize; + + TRACE (commctrl, "(%p 0x%08lx)\n", dsaPtr, dwItem); + if ( (! dsaPtr) || dwItem<0 || dwItem>=dsaPtr->dwEntryCount) + return FALSE; - - -DWORD WINAPI -DSA_DeleteItem (DWORD dwParam1, DWORD dwParam2) -{ - LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1; - - TRACE (commctrl, "(0x%08lx 0x%08lx):semi-stub!\n", - dwParam1, dwParam2); - - if (dsaPtr->ptrs) { - if (dsaPtr->dwEntryCount == 1) { - if (dsaPtr->ptrs[dwParam2]) - HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs[dwParam2]); - dsaPtr->dwEntryCount--; + if ( dwItem < dsaPtr->dwEntryCount-1 ) /* do we need to move ?*/ + { lpDest = dsaPtr->pData + (dsaPtr->dwElementSize * dwItem); + lpSrc = lpDest + dsaPtr->dwElementSize; + dwSize = dsaPtr->dwElementSize * (dsaPtr->dwEntryCount-dwItem-1); + TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",lpDest,lpSrc,dwSize); + memmove (lpDest,lpSrc,dwSize); } - else { - LPSTR *oldPtrs = dsaPtr->ptrs; - TRACE (commctrl, "complex delete!\n"); + + dsaPtr->dwEntryCount--; + + if ( (dsaPtr->dwMaxCount-dsaPtr->dwEntryCount) >= dsaPtr->dwGrow) /* free memory ?*/ + { dwSize = dsaPtr->dwElementSize * dsaPtr->dwEntryCount; + lpDest = (LPBYTE) COMCTL32_ReAlloc(dsaPtr->pData,dwSize); + if (!lpDest) + { return FALSE; + } + dsaPtr->dwMaxCount = dsaPtr->dwEntryCount; + dsaPtr->pData = lpDest; - if (dsaPtr->ptrs[dwParam2]) - HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs[dwParam2]); - - dsaPtr->dwEntryCount--; - dsaPtr->ptrs = - (LPSTR*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, - dsaPtr->dwEntryCount * sizeof(LPVOID)); - if (dwParam2 > 0) { - memcpy (&dsaPtr->ptrs[0], &oldPtrs[0], - dwParam2 * sizeof(LPSTR)); - } - - if (dwParam2 < dsaPtr->dwEntryCount) { - memcpy (&dsaPtr->ptrs[dwParam2], &oldPtrs[dwParam2+1], - (dsaPtr->dwEntryCount - dwParam2) * sizeof(LPSTR)); - } - HeapFree (GetProcessHeap (), 0, oldPtrs); - } - - if (dsaPtr->dwEntryCount == 0) { - HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs); - dsaPtr->ptrs = NULL; - } } - - return 0; + return dwItem; } +/************************************************************************** + * DSA_DeleteAllItems [COMCTL32.326] + * deletes all elements and initializes array + * + * PARAMS + * dsaPtr [I] pointer to the array control structure + * + * RETURNS + * TRUE/FALSE + */ +BOOL32 WINAPI DSA_DeleteAllItems (const LPDSA_DATA dsaPtr) +{ TRACE (commctrl, "(%p)\n", dsaPtr); + if (! dsaPtr) + return FALSE; + if (dsaPtr->pData && (! COMCTL32_Free(dsaPtr->pData))) + { return FALSE; + } + dsaPtr->dwEntryCount=0x00; + dsaPtr->pData=NULL; + dsaPtr->dwMaxCount=0x00; + return TRUE; +} +/**************************************************************************/ DWORD WINAPI diff --git a/controls/commctrl.c b/controls/commctrl.c index 4be6540a915..629fc504abb 100644 --- a/controls/commctrl.c +++ b/controls/commctrl.c @@ -22,18 +22,43 @@ #include "updown.h" #include "debug.h" + /*********************************************************************** - * ComCtl32LibMain + * ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'. + * + * PARAMS + * hinstDLL [I] + * fdwReason [I] + * lpvReserved [I] + * */ -BOOL32 WINAPI ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ TRACE(commctrl,"%x,%lx,%p\n",hinstDLL,fdwReason,lpvReserved); - if ( fdwReason == DLL_PROCESS_ATTACH) - { InitCommonControls(); - } - return TRUE; +BOOL32 WINAPI +ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE (commctrl, "%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved); + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + TRACE (commctrl, "No animation class implemented!\n"); + HEADER_Register (); + TRACE (commctrl, "No hotkey class implemented!\n"); + LISTVIEW_Register (); + PROGRESS_Register (); + STATUS_Register (); + TRACE (commctrl, "No tab class implemented!\n"); + TOOLBAR_Register (); + TOOLTIPS_Register (); + TRACKBAR_Register (); + TREEVIEW_Register (); + UPDOWN_Register (); + break; + } + + return TRUE; } + + /*********************************************************************** * DrawStatusText32A [COMCTL32.5][COMCTL32.27] * @@ -73,9 +98,18 @@ DrawStatusText32A (HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style) /*********************************************************************** * DrawStatusText32W [COMCTL32.28] + * + * Draws text with borders, like in a status bar. + * + * PARAMS + * hdc [I] handle to the window's display context + * lprc [I] pointer to a rectangle + * text [I] pointer to the text + * style [I] */ -void WINAPI DrawStatusText32W( HDC32 hdc, LPRECT32 lprc, LPCWSTR text, - UINT32 style ) + +VOID WINAPI +DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style) { LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, text ); DrawStatusText32A(hdc, lprc, p, style); @@ -137,19 +171,14 @@ HWND32 WINAPI CreateUpDownControl( DWORD style, INT32 x, INT32 y, * None. * * NOTES - * Calls InitCommonControlsEx. - * InitCommonControlsEx should be used instead. + * This function is just a dummy. + * The Win95 controls are registered at the DLL's initialization. + * To register other controls InitCommonControlsEx must be used. */ VOID WINAPI InitCommonControls (VOID) { - INITCOMMONCONTROLSEX icc; - - icc.dwSize = sizeof(INITCOMMONCONTROLSEX); - icc.dwICC = ICC_WIN95_CLASSES; - - InitCommonControlsEx (&icc); } @@ -160,6 +189,10 @@ InitCommonControls (VOID) * * PARAMS * lpInitCtrls [I] pointer to a INITCOMMONCONTROLS structure. + * + * NOTES + * Only the additinal common controls are registered by this function. + * The Win95 controls are registered at the DLL's initialization. */ BOOL32 WINAPI @@ -173,49 +206,21 @@ InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls) if (lpInitCtrls == NULL) return FALSE; if (lpInitCtrls->dwSize < sizeof(INITCOMMONCONTROLSEX)) return FALSE; - for (cCount = 0; cCount <= 31; cCount++) { + for (cCount = 0; cCount < 32; cCount++) { dwMask = 1 << cCount; if (!(lpInitCtrls->dwICC & dwMask)) continue; switch (lpInitCtrls->dwICC & dwMask) { - case ICC_LISTVIEW_CLASSES: - LISTVIEW_Register (); - HEADER_Register (); - break; - - case ICC_TREEVIEW_CLASSES: - TREEVIEW_Register (); - TOOLTIPS_Register (); - break; - - case ICC_BAR_CLASSES: - TOOLBAR_Register (); - STATUS_Register (); - TRACKBAR_Register (); - TOOLTIPS_Register (); - break; - - case ICC_TAB_CLASSES: - TRACE (commctrl, "No tab class implemented!\n"); - TOOLTIPS_Register (); - UPDOWN_Register (); - break; - - case ICC_UPDOWN_CLASS: - UPDOWN_Register (); - break; - - case ICC_PROGRESS_CLASS: - PROGRESS_Register (); - break; - - case ICC_HOTKEY_CLASS: - TRACE (commctrl, "No hotkey class implemented!\n"); - break; - + /* dummy initialization */ case ICC_ANIMATE_CLASS: - TRACE (commctrl, "No animation class implemented!\n"); + case ICC_BAR_CLASSES: + case ICC_LISTVIEW_CLASSES: + case ICC_TREEVIEW_CLASSES: + case ICC_TAB_CLASSES: + case ICC_UPDOWN_CLASS: + case ICC_PROGRESS_CLASS: + case ICC_HOTKEY_CLASS: break; /* advanced classes - not included in Win95 */ @@ -267,6 +272,10 @@ InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls) * hInst * hwndStatus * lpwIDs + * + * NOTES + * Some features are still missing because of incomplete WM_MENUSELECT + * messages (16->32 bit conversion). */ VOID WINAPI @@ -528,32 +537,60 @@ GetEffectiveClientRect (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo) /*********************************************************************** - * ShowHideMenuCtl [COMCTL32.3] + * ShowHideMenuCtl [COMCTL32.3] + * + * Shows or hides controls and updates the corresponding menu item. * * PARAMS * hwnd [I] handle to the client window. - * uFlags [I] menu command id - * lpInfo [I] pointer to an array of integers + * uFlags [I] menu command id. + * lpInfo [I] pointer to an array of integers. (See NOTES.) * * NOTES + * The official documentation is incomplete! This has been fixed. + * + * lpInfo + * The array of integers contains pairs of values. BOTH values of + * the first pair must be the handles to application's main menu. + * Each subsequent pair consists of a menu id and control id. */ BOOL32 WINAPI ShowHideMenuCtl (HWND32 hwnd, UINT32 uFlags, LPINT32 lpInfo) { + LPINT32 lpMenuId; FIXME (commctrl, "(0x%08x 0x%08x %p): empty stub!\n", hwnd, uFlags, lpInfo); -#if 0 - if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) { - /* checked -> hide control */ + if (lpInfo == NULL) + return FALSE; + + if (!(lpInfo[0]) || !(lpInfo[1])) + return FALSE; + + /* search for control */ + lpMenuId = &lpInfo[2]; + while (*lpMenuId != uFlags) + lpMenuId += 2; + + if (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) { + /* uncheck menu item */ + CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED); + + /* hide control */ + lpMenuId++; + SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0, + SWP_HIDEWINDOW); } else { - /* not checked -> show control */ + /* check menu item */ + CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED); + /* show control */ + lpMenuId++; + SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0, + SWP_SHOWWINDOW); } -#endif - - return FALSE; + return TRUE; } diff --git a/controls/menu.c b/controls/menu.c index fc01e53de94..45a25c60b7d 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -3852,7 +3852,7 @@ BOOL32 WINAPI SetMenuItemInfo32W(HMENU32 hmenu, UINT32 item, BOOL32 bypos, /********************************************************************** * SetMenuDefaultItem32 (USER32.489) */ -BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, BOOL32 bypos) +BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, UINT32 bypos) { MENUITEM *menuitem = MENU_FindItem(&hmenu, &item, bypos); POPUPMENU *menu; @@ -3938,7 +3938,7 @@ BOOL32 WINAPI InsertMenuItem32W(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos, BOOL32 WINAPI CheckMenuRadioItem32(HMENU32 hMenu, UINT32 first, UINT32 last, UINT32 check, - BOOL32 bypos) + UINT32 bypos) { MENUITEM *mifirst, *milast, *micheck; HMENU32 mfirst = hMenu, mlast = hMenu, mcheck = hMenu; diff --git a/controls/pager.c b/controls/pager.c index 2e335c08df2..60612c2e42a 100644 --- a/controls/pager.c +++ b/controls/pager.c @@ -24,6 +24,17 @@ #define PAGER_GetInfoPtr(wndPtr) ((PAGER_INFO *)wndPtr->wExtra[0]) +static __inline__ LRESULT +PAGER_ForwardMouse (WND *wndPtr, WPARAM32 wParam) +{ + PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr); + + infoPtr->bForward = (BOOL32)wParam; + + return 0; +} + + static __inline__ LRESULT PAGER_GetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { @@ -51,6 +62,28 @@ PAGER_GetButtonSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } +// << PAGER_GetButtonState >> +// << PAGER_GetDropTarget >> + + +static __inline__ LRESULT +PAGER_GetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr); + + return infoPtr->iPos; +} + + +static LRESULT +PAGER_RecalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ +// PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr); + + FIXME (pager, "empty stub!\n"); + + return 0; +} static __inline__ LRESULT @@ -108,6 +141,18 @@ PAGER_SetChild (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } +static __inline__ LRESULT +PAGER_SetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr); + + infoPtr->iPos = (INT32)lParam; + + /* FIXME: redraw */ + + return 0; +} + static LRESULT PAGER_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) @@ -120,7 +165,7 @@ PAGER_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) wndPtr->wExtra[0] = (DWORD)infoPtr; if (infoPtr == NULL) { - ERR (treeview, "could not allocate info memory!\n"); + ERR (pager, "could not allocate info memory!\n"); return 0; } @@ -134,6 +179,7 @@ PAGER_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) infoPtr->clrBk = GetSysColor32 (COLOR_BTNFACE); infoPtr->iBorder = 0; infoPtr->iButtonSize = 0; + infoPtr->iPos = 0; return 0; @@ -148,7 +194,7 @@ PAGER_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) - /* free tree view info data */ + /* free pager info data */ HeapFree (GetProcessHeap (), 0, infoPtr); return 0; @@ -169,15 +215,19 @@ PAGER_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } +// << PAGER_MouseMove >> +// << PAGER_Paint >> + LRESULT WINAPI -PagerWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) +PAGER_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) { WND *wndPtr = WIN_FindWndPtr(hwnd); switch (uMsg) { -// case PGM_FORWARDMOUSE: + case PGM_FORWARDMOUSE: + return PAGER_ForwardMouse (wndPtr, wParam); case PGM_GETBKCOLOR: return PAGER_GetBkColor (wndPtr, wParam, lParam); @@ -190,8 +240,12 @@ PagerWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) // case PGM_GETBUTTONSTATE: // case PGM_GETDROPTARGET: -// case PGM_GETPOS: -// case PGM_RECALCSIZE: + + case PGM_GETPOS: + return PAGER_SetPos (wndPtr, wParam, lParam); + + case PGM_RECALCSIZE: + return PAGER_RecalcSize (wndPtr, wParam, lParam); case PGM_SETBKCOLOR: return PAGER_SetBkColor (wndPtr, wParam, lParam); @@ -205,7 +259,8 @@ PagerWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) case PGM_SETCHILD: return PAGER_SetChild (wndPtr, wParam, lParam); -// case PGM_SETPOS: + case PGM_SETPOS: + return PAGER_SetPos (wndPtr, wParam, lParam); case WM_CREATE: return PAGER_Create (wndPtr, wParam, lParam); @@ -242,7 +297,7 @@ PAGER_Register (void) ZeroMemory (&wndClass, sizeof(WNDCLASS32A)); wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS; - wndClass.lpfnWndProc = (WNDPROC32)PagerWindowProc; + wndClass.lpfnWndProc = (WNDPROC32)PAGER_WindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(PAGER_INFO *); wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A); diff --git a/controls/rebar.c b/controls/rebar.c index 9280cf93fb7..a36bbffbfdd 100644 --- a/controls/rebar.c +++ b/controls/rebar.c @@ -24,18 +24,573 @@ #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)wndPtr->wExtra[0]) +// << REBAR_BeginDrag >> +// << REBAR_DeleteBand >> +// << REBAR_DragMove >> +// << REBAR_EndDrag >> +// << REBAR_GetBandBorders >> + + +__inline__ static LRESULT +REBAR_GetBandCount (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + TRACE (rebar, "band count %u!\n", infoPtr->uNumBands); + + return infoPtr->uNumBands; +} + + +static LRESULT +REBAR_GetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam; + REBAR_BAND *lpBand; + + if (lprbbi == NULL) + return FALSE; + if (lprbbi->cbSize < sizeof (LPREBARBANDINFO32A)) + return FALSE; + if ((UINT32)wParam >= infoPtr->uNumBands) + return FALSE; + + TRACE (rebar, "index %u\n", (UINT32)wParam); + + /* copy band information */ + lpBand = &infoPtr->bands[(UINT32)wParam]; + + if (lprbbi->fMask & RBBIM_STYLE) + lprbbi->fStyle = lpBand->fStyle; + + if (lprbbi->fMask & RBBIM_COLORS) { + lprbbi->clrFore = lpBand->clrFore; + lprbbi->clrBack = lpBand->clrBack; + } + + if ((lprbbi->fMask & RBBIM_TEXT) && + (lprbbi->lpText) && (lpBand->lpText)) { + lstrcpyn32A (lprbbi->lpText, lpBand->lpText, lprbbi->cch); + } + + if (lprbbi->fMask & RBBIM_IMAGE) + lprbbi->iImage = lpBand->iImage; + + if (lprbbi->fMask & RBBIM_CHILD) + lprbbi->hwndChild = lpBand->hwndChild; + + if (lprbbi->fMask & RBBIM_CHILDSIZE) { + lprbbi->cxMinChild = lpBand->cxMinChild; + lprbbi->cyMinChild = lpBand->cyMinChild; + lprbbi->cyMaxChild = lpBand->cyMaxChild; + lprbbi->cyChild = lpBand->cyChild; + lprbbi->cyIntegral = lpBand->cyIntegral; + } + + if (lprbbi->fMask & RBBIM_SIZE) + lprbbi->cx = lpBand->cx; + + if (lprbbi->fMask & RBBIM_BACKGROUND) + lprbbi->hbmBack = lpBand->hbmBack; + + if (lprbbi->fMask & RBBIM_ID) + lprbbi->wID = lpBand->wID; + + /* FIXME: check for size of band info structure */ + + if (lprbbi->fMask & RBBIM_IDEALSIZE) + lprbbi->cxIdeal = lpBand->cxIdeal; + + if (lprbbi->fMask & RBBIM_LPARAM) + lprbbi->lParam = lpBand->lParam; + + if (lprbbi->fMask & RBBIM_HEADERSIZE) + lprbbi->cxHeader = lpBand->cxHeader; + + return TRUE; +} + + +// << REBAR_GetBandInfo32W >> + +// << REBAR_GetBarHeight >> + + +static LRESULT +REBAR_GetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + LPREBARINFO lpInfo = (LPREBARINFO)lParam; + + if (lpInfo == NULL) + return FALSE; + + if (lpInfo->cbSize < sizeof (REBARINFO)) + return FALSE; + + TRACE (rebar, "getting bar info!\n"); + + if (infoPtr->himl) { + lpInfo->himl = infoPtr->himl; + lpInfo->fMask |= RBIM_IMAGELIST; + } + + return TRUE; +} + + +__inline__ static LRESULT +REBAR_GetBkColor (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk); + + return infoPtr->clrBk; +} + + +// << REBAR_GetColorScheme >> + +// << REBAR_GetRowHeight >> + + +__inline__ static LRESULT +REBAR_GetTextColor (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText); + + return infoPtr->clrText; +} + + +// << REBAR_GetToolTips >> +// << REBAR_GetUnicodeFormat >> +// << REBAR_HitTest >> + + +static LRESULT +REBAR_IdToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + UINT32 i; + + if (infoPtr == NULL) + return -1; + + if (infoPtr->uNumBands < 1) + return -1; + + TRACE (rebar, "id %u\n", (UINT32)wParam); + + for (i = 0; i < infoPtr->uNumBands; i++) { + if (infoPtr->bands[i].wID == (UINT32)wParam) + return i; + } + + return -1; +} + + +static LRESULT +REBAR_InsertBand32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam; + UINT32 uIndex = (UINT32)wParam; + REBAR_BAND *lpBand; + + if (infoPtr == NULL) + return FALSE; + if (lprbbi == NULL) + return FALSE; + if (lprbbi->cbSize < sizeof (REBARBANDINFO32A)) + return FALSE; + + if (infoPtr->uNumBands == 0) { + infoPtr->bands = + (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + sizeof (REBAR_BAND)); + uIndex = 0; + } + else { + REBAR_BAND *oldBands = infoPtr->bands; + infoPtr->bands = + (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + (infoPtr->uNumBands+1)*sizeof(REBAR_BAND)); + if ((INT32)uIndex == -1) + uIndex = infoPtr->uNumBands; + + /* pre copy */ + + /* post copy */ + + HeapFree (GetProcessHeap (), 0, &oldBands); + } + + infoPtr->uNumBands++; + + TRACE (rebar, "index %u!\n", uIndex); + + /* initialize band (infoPtr->bands[uIndex])*/ + lpBand = &infoPtr->bands[uIndex]; + + if (lprbbi->fMask & RBBIM_STYLE) + lpBand->fStyle = lprbbi->fStyle; + + if (lprbbi->fMask & RBBIM_COLORS) { + lpBand->clrFore = lprbbi->clrFore; + lpBand->clrBack = lprbbi->clrBack; + } + + if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { + INT32 len = lstrlen32A (lprbbi->lpText); + if (len > 0) { + lpBand->lpText = + (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + lstrcpy32A (lpBand->lpText, lprbbi->lpText); + } + } + + if (lprbbi->fMask & RBBIM_IMAGE) + lpBand->iImage = lprbbi->iImage; + + if (lprbbi->fMask & RBBIM_CHILD) + lpBand->hwndChild = lprbbi->hwndChild; + + if (lprbbi->fMask & RBBIM_CHILDSIZE) { + lpBand->cxMinChild = lprbbi->cxMinChild; + lpBand->cyMinChild = lprbbi->cyMinChild; + lpBand->cyMaxChild = lprbbi->cyMaxChild; + lpBand->cyChild = lprbbi->cyChild; + lpBand->cyIntegral = lprbbi->cyIntegral; + } + + if (lprbbi->fMask & RBBIM_SIZE) + lpBand->cx = lprbbi->cx; + + if (lprbbi->fMask & RBBIM_BACKGROUND) + lpBand->hbmBack = lprbbi->hbmBack; + + if (lprbbi->fMask & RBBIM_ID) + lpBand->wID = lprbbi->wID; + + /* FIXME: check for size of band info structure */ + + if (lprbbi->fMask & RBBIM_IDEALSIZE) + lpBand->cxIdeal = lprbbi->cxIdeal; + + if (lprbbi->fMask & RBBIM_LPARAM) + lpBand->lParam = lprbbi->lParam; + + if (lprbbi->fMask & RBBIM_HEADERSIZE) + lpBand->cxHeader = lprbbi->cxHeader; + + return TRUE; +} + + +// << REBAR_InsertBand32W >> +// << REBAR_MaximizeBand >> +// << REBAR_MinimizeBand >> +// << REBAR_MoveBand >> + + +static LRESULT +REBAR_SetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam; + REBAR_BAND *lpBand; + + if (lprbbi == NULL) + return FALSE; + if (lprbbi->cbSize < sizeof (LPREBARBANDINFO32A)) + return FALSE; + if ((UINT32)wParam >= infoPtr->uNumBands) + return FALSE; + + TRACE (rebar, "index %u\n", (UINT32)wParam); + + /* set band information */ + lpBand = &infoPtr->bands[(UINT32)wParam]; + + if (lprbbi->fMask & RBBIM_STYLE) + lpBand->fStyle = lprbbi->fStyle; + + if (lprbbi->fMask & RBBIM_COLORS) { + lpBand->clrFore = lprbbi->clrFore; + lpBand->clrBack = lprbbi->clrBack; + } + + if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { +/* + INT32 len = lstrlen32A (lprbbi->lpText); + if (len > 0) { + lpBand->lpText = + (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); + lstrcpy32A (lpBand->lpText, lprbbi->lpText); + } +*/ + } + + if (lprbbi->fMask & RBBIM_IMAGE) + lpBand->iImage = lprbbi->iImage; + + if (lprbbi->fMask & RBBIM_CHILD) + lpBand->hwndChild = lprbbi->hwndChild; + + if (lprbbi->fMask & RBBIM_CHILDSIZE) { + lpBand->cxMinChild = lprbbi->cxMinChild; + lpBand->cyMinChild = lprbbi->cyMinChild; + lpBand->cyMaxChild = lprbbi->cyMaxChild; + lpBand->cyChild = lprbbi->cyChild; + lpBand->cyIntegral = lprbbi->cyIntegral; + } + + if (lprbbi->fMask & RBBIM_SIZE) + lpBand->cx = lprbbi->cx; + + if (lprbbi->fMask & RBBIM_BACKGROUND) + lpBand->hbmBack = lprbbi->hbmBack; + + if (lprbbi->fMask & RBBIM_ID) + lpBand->wID = lprbbi->wID; + + /* FIXME: check for size of band info structure */ + + if (lprbbi->fMask & RBBIM_IDEALSIZE) + lpBand->cxIdeal = lprbbi->cxIdeal; + + if (lprbbi->fMask & RBBIM_LPARAM) + lpBand->lParam = lprbbi->lParam; + + if (lprbbi->fMask & RBBIM_HEADERSIZE) + lpBand->cxHeader = lprbbi->cxHeader; + + return TRUE; +} + + +// << REBAR_SetBandInfo32W >> + + +static LRESULT +REBAR_SetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + LPREBARINFO lpInfo = (LPREBARINFO)lParam; + + if (lpInfo == NULL) + return FALSE; + + if (lpInfo->cbSize < sizeof (REBARINFO)) + return FALSE; + + TRACE (rebar, "setting bar info!\n"); + + if (lpInfo->fMask & RBIM_IMAGELIST) + infoPtr->himl = lpInfo->himl; + + return TRUE; +} + + +static LRESULT +REBAR_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + COLORREF clrTemp; + + clrTemp = infoPtr->clrBk; + infoPtr->clrBk = (COLORREF)lParam; + + TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk); + + return clrTemp; +} + + +// << REBAR_SetColorScheme >> +// << REBAR_SetPalette >> +// << REBAR_SetParent >> + + +static LRESULT +REBAR_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + COLORREF clrTemp; + + clrTemp = infoPtr->clrText; + infoPtr->clrText = (COLORREF)lParam; + + TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText); + + return clrTemp; +} + + +// << REBAR_SetTooltips >> +// << REBAR_SetUnicodeFormat >> +// << REBAR_ShowBand >> +// << REBAR_SizeToRect >> + + + +static LRESULT +REBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr; + + /* allocate memory for info structure */ + infoPtr = (REBAR_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, + sizeof(REBAR_INFO)); + wndPtr->wExtra[0] = (DWORD)infoPtr; + + if (infoPtr == NULL) { + ERR (rebar, "could not allocate info memory!\n"); + return 0; + } + + if ((REBAR_INFO*)wndPtr->wExtra[0] != infoPtr) { + ERR (rebar, "pointer assignment error!\n"); + return 0; + } + + + infoPtr->clrText = CLR_NONE; + infoPtr->clrText = RGB(0, 0, 0); + + TRACE (rebar, "created!\n"); + return 0; +} + + +static LRESULT +REBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + REBAR_BAND *lpBand; + INT32 i; + + + /* free rebar bands */ + if ((infoPtr->uNumBands > 0) && infoPtr->bands) { + /* clean up each band */ + for (i = 0; i < infoPtr->uNumBands; i++) { + lpBand = &infoPtr->bands[i]; + + /* delete text strings */ + if (lpBand->lpText) { + HeapFree (GetProcessHeap (), 0, lpBand->lpText); + lpBand->lpText = NULL; + } + } + + /* free band array */ + HeapFree (GetProcessHeap (), 0, infoPtr->bands); + infoPtr->bands = NULL; + } + + /* free rebar info data */ + HeapFree (GetProcessHeap (), 0, infoPtr); + + TRACE (rebar, "destroyed!\n"); + return 0; +} + + + + LRESULT WINAPI -RebarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) +REBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) { WND *wndPtr = WIN_FindWndPtr(hwnd); switch (uMsg) { -// case WM_CREATE: -// return REBAR_Create (wndPtr, wParam, lParam); +// case RB_BEGINDRAG: +// case RB_DELETEBAND: +// case RB_DRAGMOVE: +// case RB_ENDDRAG: +// case RB_GETBANDBORDERS: -// case WM_DESTROY: -// return REBAR_Destroy (wndPtr, wParam, lParam); + case RB_GETBANDCOUNT: + return REBAR_GetBandCount (wndPtr); + +// case RB_GETBANDINFO32: /* outdated, just for compatibility */ + + case RB_GETBANDINFO32A: + return REBAR_GetBandInfo32A (wndPtr, wParam, lParam); + + +// case RB_GETBANDINFO32W: +// case RB_GETBARHEIGHT: + + case RB_GETBARINFO: + return REBAR_GetBarInfo (wndPtr, wParam, lParam); + + case RB_GETBKCOLOR: + return REBAR_GetBkColor (wndPtr); + +// case RB_GETCOLORSCHEME: +// case RB_GETDROPTARGET: +// case RB_GETPALETTE: +// case RB_GETRECT: +// case RB_GETROWCOUNT: +// case RB_GETROWHEIGHT: + + case RB_GETTEXTCOLOR: + return REBAR_GetTextColor (wndPtr); + +// case RB_GETTOOLTIPS: +// case RB_GETUNICODEFORMAT: +// case RB_HITTEST: + + case RB_IDTOINDEX: + return REBAR_IdToIndex (wndPtr, wParam, lParam); + + case RB_INSERTBAND32A: + return REBAR_InsertBand32A (wndPtr, wParam, lParam); + +// case RB_INSERTBAND32W: +// case RB_MAXIMIZEBAND: +// case RB_MINIMIZEBAND: +// case RB_MOVEBAND: + + case RB_SETBANDINFO32A: + return REBAR_SetBandInfo32A (wndPtr, wParam, lParam); + +// case RB_SETBANDINFO32W: + + case RB_SETBARINFO: + return REBAR_SetBarInfo (wndPtr, wParam, lParam); + + case RB_SETBKCOLOR: + return REBAR_SetBkColor (wndPtr, wParam, lParam); + +// case RB_SETCOLORSCHEME: +// case RB_SETPALETTE: +// case RB_SETPARENT: + + case RB_SETTEXTCOLOR: + return REBAR_SetTextColor (wndPtr, wParam, lParam); + +// case RB_SETTOOLTIPS: +// case RB_SETUNICODEFORMAT: +// case RB_SHOWBAND: +// case RB_SIZETORECT: + + + case WM_CREATE: + return REBAR_Create (wndPtr, wParam, lParam); + + case WM_DESTROY: + return REBAR_Destroy (wndPtr, wParam, lParam); // case WM_GETFONT: @@ -70,7 +625,7 @@ REBAR_Register (void) ZeroMemory (&wndClass, sizeof(WNDCLASS32A)); wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS; - wndClass.lpfnWndProc = (WNDPROC32)RebarWindowProc; + wndClass.lpfnWndProc = (WNDPROC32)REBAR_WindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(REBAR_INFO *); wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A); diff --git a/controls/toolbar.c b/controls/toolbar.c index 6a883d55f1a..142ffb6ee1a 100644 --- a/controls/toolbar.c +++ b/controls/toolbar.c @@ -10,7 +10,7 @@ * - Notifications. * - Fix TB_GETBITMAPFLAGS. * - Fix TB_GETROWS and TB_SETROWS. - * - Tooltip support (under contruction). + * - Tooltip support (almost complete). * - Unicode suppport. * - Internal COMMCTL32 bitmaps. * - Fix TOOLBAR_Customize. (Customize dialog.) @@ -22,7 +22,7 @@ * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe, * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe, * setparnt.exe, setrows.exe, toolwnd.exe. - * - additional features. + * - Microsofts controlspy examples. */ #include "windows.h" @@ -248,20 +248,29 @@ TOOLBAR_CalcToolbar (WND *wndPtr) INT32 x, y, cx, cy; BOOL32 bVertical; SIZE32 sizeString; + RECT32 rect = {0, 0, 0, 0}; TOOLBAR_CalcStrings (wndPtr, &sizeString); if (sizeString.cy > 0) infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6; + else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6) + infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6; if (sizeString.cx > infoPtr->nBitmapWidth) infoPtr->nButtonWidth = sizeString.cx + 6; + else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6) + infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6; x = infoPtr->nIndent; y = TOP_BORDER; cx = infoPtr->nButtonWidth; cy = infoPtr->nButtonHeight; nRows = 1; + rect.top = y; + rect.left = x; + rect.bottom = y + cy; + rect.right = x; btnPtr = infoPtr->buttons; for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) { @@ -279,14 +288,14 @@ TOOLBAR_CalcToolbar (WND *wndPtr) x = 0; y += cy; cx = infoPtr->nWidth; - cy = ((btnPtr->iBitmap == 0) ? - SEPARATOR_WIDTH : btnPtr->iBitmap) * 2 / 3; + cy = ((btnPtr->iBitmap > 0) ? + btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3; nRows++; bVertical = TRUE; } else - cx = (btnPtr->iBitmap == 0) ? - SEPARATOR_WIDTH : btnPtr->iBitmap; + cx = (btnPtr->iBitmap > 0) ? + btnPtr->iBitmap : SEPARATOR_WIDTH; } else { /* this must be a button */ @@ -299,6 +308,13 @@ TOOLBAR_CalcToolbar (WND *wndPtr) btnPtr->rect.right = x + cx; btnPtr->rect.bottom = y + cy; + if (rect.left > x) + rect.left = x; + if (rect.right < x + cx) + rect.right = x + cx; + if (rect.bottom < y + cy) + rect.bottom = y + cy; + if (infoPtr->hwndToolTip) { TTTOOLINFO32A ti; @@ -322,6 +338,8 @@ TOOLBAR_CalcToolbar (WND *wndPtr) } infoPtr->nHeight = y + cy + BOTTOM_BORDER; + infoPtr->maxSize.cx = rect.right - rect.left; + infoPtr->maxSize.cy = rect.bottom - rect.top; TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight); } @@ -541,13 +559,13 @@ TOOLBAR_AddButtons32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) infoPtr->buttons[nOldButtons+nCount].dwData = lpTbb[nCount].dwData; infoPtr->buttons[nOldButtons+nCount].iString = lpTbb[nCount].iString; - if (infoPtr->hwndToolTip) { + if ((infoPtr->hwndToolTip) && !(lpTbb[nCount].fsStyle & TBSTYLE_SEP)) { TTTOOLINFO32A ti; ZeroMemory (&ti, sizeof(TTTOOLINFO32A)); ti.cbSize = sizeof (TTTOOLINFO32A); ti.hwnd = wndPtr->hwndSelf; - ti.uId = (LPSTR)lpTbb[nCount].idCommand; + ti.uId = lpTbb[nCount].idCommand; ti.hinst = 0; ti.lpszText = LPSTR_TEXTCALLBACK32A; @@ -654,7 +672,7 @@ TOOLBAR_AutoSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) INT32 x, y, cx, cy; UINT32 uPosFlags = 0; - FIXME (toolbar, "auto size!\n"); + TRACE (toolbar, "resizing!\n"); parent = GetParent32 (wndPtr->hwndSelf); GetClientRect32(parent, &parent_rect); @@ -805,7 +823,8 @@ TOOLBAR_DeleteButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons)) return FALSE; - if (infoPtr->hwndToolTip) { + if ((infoPtr->hwndToolTip) && + !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) { TTTOOLINFO32A ti; ZeroMemory (&ti, sizeof(TTTOOLINFO32A)); @@ -1102,7 +1121,14 @@ TOOLBAR_GetMaxSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); LPSIZE32 lpSize = (LPSIZE32)lParam; - FIXME (toolbar, "empty stub!\n"); + if (lpSize == NULL) + return FALSE; + + lpSize->cx = infoPtr->maxSize.cx; + lpSize->cx = infoPtr->maxSize.cy; + + TRACE (toolbar, "maximum size %d x %d\n", + infoPtr->maxSize.cx, infoPtr->maxSize.cy); return TRUE; } @@ -1110,7 +1136,31 @@ TOOLBAR_GetMaxSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) // << TOOLBAR_GetObject >> // << TOOLBAR_GetPadding >> -// << TOOLBAR_GetRect >> + + +static LRESULT +TOOLBAR_GetRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + TBUTTON_INFO *btnPtr; + LPRECT32 lpRect; + INT32 nIndex; + + if (infoPtr == NULL) return FALSE; + nIndex = (INT32)wParam; + btnPtr = &infoPtr->buttons[nIndex]; + if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons)) + return FALSE; + lpRect = (LPRECT32)lParam; + if (lpRect == NULL) return FALSE; + + lpRect->left = btnPtr->rect.left; + lpRect->right = btnPtr->rect.right; + lpRect->bottom = btnPtr->rect.bottom; + lpRect->top = btnPtr->rect.top; + + return TRUE; +} static LRESULT @@ -1151,7 +1201,16 @@ TOOLBAR_GetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -// << TOOLBAR_GetTextRows >> +static LRESULT +TOOLBAR_GetTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + + if (infoPtr == NULL) + return 0; + + return infoPtr->nMaxTextRows; +} static LRESULT @@ -1164,7 +1223,16 @@ TOOLBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -// << TOOLBAR_GetUnicodeFormat >> +static LRESULT +TOOLBAR_GetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + + TRACE (toolbar, "%s hwnd=0x%04x stub!\n", + infoPtr->bUnicode ? "TRUE" : "FALSE", wndPtr->hwndSelf); + + return infoPtr->bUnicode; +} static LRESULT @@ -1193,7 +1261,7 @@ TOOLBAR_HideButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -static LRESULT +__inline__ static LRESULT TOOLBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { return TOOLBAR_InternalHitTest (wndPtr, (LPPOINT32)lParam); @@ -1262,7 +1330,7 @@ TOOLBAR_InsertButton32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) infoPtr->buttons[nIndex].dwData = lpTbb->dwData; infoPtr->buttons[nIndex].iString = lpTbb->iString; - if (infoPtr->hwndToolTip) { + if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) { TTTOOLINFO32A ti; ZeroMemory (&ti, sizeof(TTTOOLINFO32A)); @@ -1482,7 +1550,19 @@ TOOLBAR_SetButtonSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -// << TOOLBAR_SetButtonWidth >> +static LRESULT +TOOLBAR_SetButtonWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + + if (infoPtr == NULL) + return FALSE; + + infoPtr->cxMin = (INT32)LOWORD(lParam); + infoPtr->cxMax = (INT32)HIWORD(lParam); + + return TRUE; +} static LRESULT @@ -1496,6 +1576,12 @@ TOOLBAR_SetCmdId (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) infoPtr->buttons[nIndex].idCommand = (INT32)lParam; + if (infoPtr->hwndToolTip) { + + FIXME (toolbar, "change tool tip!\n"); + + } + return TRUE; } @@ -1608,7 +1694,20 @@ TOOLBAR_SetInsertMarkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -// << TOOLBAR_SetMaxTextRows >> +static LRESULT +TOOLBAR_SetMaxTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + + if (infoPtr == NULL) + return FALSE; + + infoPtr->nMaxTextRows = (INT32)wParam; + + return TRUE; +} + + // << TOOLBAR_SetPadding >> @@ -1679,6 +1778,12 @@ TOOLBAR_SetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) TOOLBAR_DrawButton (wndPtr, btnPtr, hdc); ReleaseDC32 (wndPtr->hwndSelf, hdc); + if (infoPtr->hwndToolTip) { + + FIXME (toolbar, "change tool tip!\n"); + + } + return TRUE; } @@ -1698,10 +1803,15 @@ static LRESULT TOOLBAR_SetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); + BOOL32 bTemp; - FIXME (toolbar, "hwnd=0x%04x stub!\n", wndPtr->hwndSelf); + TRACE (toolbar, "%s hwnd=0x%04x stub!\n", + ((BOOL32)wParam) ? "TRUE" : "FALSE", wndPtr->hwndSelf); - return 0; + bTemp = infoPtr->bUnicode; + infoPtr->bUnicode = (BOOL32)wParam; + + return bTemp; } @@ -1719,8 +1829,12 @@ TOOLBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER; infoPtr->nMaxRows = 1; + infoPtr->nMaxTextRows = 1; + infoPtr->cxMin = -1; + infoPtr->cxMax = -1; - infoPtr->bCaptured = 0; + infoPtr->bCaptured = FALSE; + infoPtr->bUnicode = FALSE; infoPtr->nButtonDown = -1; infoPtr->nOldHit = -1; @@ -1737,8 +1851,7 @@ TOOLBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) CreateWindowEx32A (0, TOOLTIPS_CLASS32A, NULL, TTS_ALWAYSTIP, CW_USEDEFAULT32, CW_USEDEFAULT32, CW_USEDEFAULT32, CW_USEDEFAULT32, - wndPtr->hwndSelf, 0, - wndPtr->hInstance, 0); + wndPtr->hwndSelf, 0, 0, 0); /* Send NM_TOOLTIPSCREATED notification */ if (infoPtr->hwndToolTip) { @@ -1997,7 +2110,7 @@ TOOLBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } - +// << TOOLBAR_NCActivate >> static LRESULT @@ -2005,8 +2118,7 @@ TOOLBAR_NCCalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { if (!(wndPtr->dwStyle & CCS_NODIVIDER)) { LPRECT32 winRect = (LPRECT32)lParam; - winRect->top += 2; - winRect->bottom += 2; + winRect->top += 2; } return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam); @@ -2096,11 +2208,25 @@ TOOLBAR_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr); LPNMHDR lpnmh = (LPNMHDR)lParam; - if ((infoPtr->hwndToolTip) && ((lpnmh->code == TTN_GETDISPINFO32A) || - (lpnmh->code == TTN_GETDISPINFO32W))) { + TRACE (toolbar, "passing WM_NOTIFY!\n"); - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - wParam, lParam); + if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) { + SendMessage32A (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam); + +#if 0 + if (lpnmh->code == TTN_GETDISPINFO32A) { + LPNMTTDISPINFO32A lpdi = (LPNMTTDISPINFO32A)lParam; + + FIXME (toolbar, "retrieving ASCII string\n"); + + } + else if (lpnmh->code == TTN_GETDISPINFO32W) { + LPNMTTDISPINFO32W lpdi = (LPNMTTDISPINFO32W)lParam; + + FIXME (toolbar, "retrieving UNICODE string\n"); + + } +#endif } return 0; @@ -2286,7 +2412,9 @@ ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) // case TB_GETOBJECT: /* 4.71 */ // case TB_GETPADDING: /* 4.71 */ -// case TB_GETRECT: /* 4.70 */ + + case TB_GETRECT: + return TOOLBAR_GetRect (wndPtr, wParam, lParam); case TB_GETROWS: return TOOLBAR_GetRows (wndPtr, wParam, lParam); @@ -2297,12 +2425,14 @@ ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) case TB_GETSTYLE: return TOOLBAR_GetStyle (wndPtr, wParam, lParam); -// case TB_GETTEXTROWS: /* 4.70 */ + case TB_GETTEXTROWS: + return TOOLBAR_GetTextRows (wndPtr, wParam, lParam); case TB_GETTOOLTIPS: return TOOLBAR_GetToolTips (wndPtr, wParam, lParam); -// case TB_GETUNICODEFORMAT: + case TB_GETUNICODEFORMAT: + return TOOLBAR_GetUnicodeFormat (wndPtr, wParam, lParam); case TB_HIDEBUTTON: return TOOLBAR_HideButton (wndPtr, wParam, lParam); @@ -2363,7 +2493,8 @@ ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) case TB_SETBUTTONSIZE: return TOOLBAR_SetButtonSize (wndPtr, wParam, lParam); -// case TB_SETBUTTONWIDTH: /* 4.70 */ + case TB_SETBUTTONWIDTH: + return TOOLBAR_SetButtonWidth (wndPtr, wParam, lParam); case TB_SETCMDID: return TOOLBAR_SetCmdId (wndPtr, wParam, lParam); @@ -2394,7 +2525,9 @@ ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) case TB_SETINSERTMARKCOLOR: return TOOLBAR_SetInsertMarkColor (wndPtr, wParam, lParam); -// case TB_SETMAXTEXTROWS: /* 4.70 */ + case TB_SETMAXTEXTROWS: + return TOOLBAR_SetMaxTextRows (wndPtr, wParam, lParam); + // case TB_SETPADDING: /* 4.71 */ case TB_SETPARENT: diff --git a/controls/tooltips.c b/controls/tooltips.c index e0e8477b78b..baf6971d1d2 100644 --- a/controls/tooltips.c +++ b/controls/tooltips.c @@ -4,24 +4,18 @@ * Copyright 1998 Eric Kohl * * TODO: - * - Subclassing. * - Tracking tooltips (under construction). * - TTS_ALWAYSTIP (undefined). * - Unicode support. * - Custom draw support. + * - The "lParam" variable from NMTTDISPINFO32A is not handled + * in TOOLTIPS_GetTipText. * * Testing: * - Run tests using Waite Group Windows95 API Bible Volume 2. * The second cdrom (chapter 3) contains executables activate.exe, * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe, * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe. - * - * - Activate.exe, deltool.exe, enumtool.exe, getinfo.exe and getiptxt.exe - * are the only working examples, since subclassing is not implemented. - * - * Fixme: - * - The "lParam" variable from NMTTDISPINFO32A is not handled - * in TOOLTIPS_GetTipText. */ #include "windows.h" @@ -35,10 +29,15 @@ #define ID_TIMER1 1 /* show delay timer */ #define ID_TIMER2 2 /* auto pop timer */ #define ID_TIMER3 3 /* tool leave timer */ +#define TT_SUBCLASS_PROP "CC32SubclassInfo" /* property name of tooltip window handle */ #define TOOLTIPS_GetInfoPtr(wndPtr) ((TOOLTIPS_INFO *)wndPtr->wExtra[0]) +LRESULT CALLBACK +TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam); + + static VOID TOOLTIPS_Refresh (WND *wndPtr, HDC32 hdc) { @@ -91,8 +90,8 @@ TOOLTIPS_GetTipText (WND *wndPtr, TOOLTIPS_INFO *infoPtr) ttnmdi.lpszText = infoPtr->szTipText; TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom); - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&ttnmdi); + SendMessage32A (toolPtr->hwnd, WM_NOTIFY, + (WPARAM32)toolPtr->uId, (LPARAM)&ttnmdi); if (ttnmdi.hinst) { LoadString32A (ttnmdi.hinst, (UINT32)ttnmdi.szText, @@ -195,17 +194,17 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr) return; } - TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nTool); + TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool); + toolPtr = &infoPtr->tools[infoPtr->nCurrentTool]; hdr.hwndFrom = wndPtr->hwndSelf; - hdr.idFrom = infoPtr->nTool; + hdr.idFrom = toolPtr->uId; hdr.code = TTN_SHOW; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&hdr); + SendMessage32A (toolPtr->hwnd, WM_NOTIFY, + (WPARAM32)toolPtr->uId, (LPARAM)&hdr); TRACE (tooltips, "\"%s\"\n", infoPtr->szTipText); - toolPtr = &infoPtr->tools[infoPtr->nTool]; TOOLTIPS_CalcTipSize (wndPtr, infoPtr, &size); TRACE (tooltips, "size %d - %d\n", size.cx, size.cy); @@ -232,9 +231,8 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr) TRACE (tooltips, "pos %d - %d\n", pt.x, pt.y); -// SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y, -// size.cx, size.cy, SWP_SHOWWINDOW); - SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1, +// SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, 1, 1, + SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, pt.x, pt.y, size.cx, size.cy, SWP_SHOWWINDOW); SetTimer32 (wndPtr->hwndSelf, ID_TIMER2, infoPtr->nAutoPopTime, 0); @@ -244,19 +242,21 @@ TOOLTIPS_Show (WND *wndPtr, TOOLTIPS_INFO *infoPtr) static VOID TOOLTIPS_Hide (WND *wndPtr, TOOLTIPS_INFO *infoPtr) { + TTTOOL_INFO *toolPtr; NMHDR hdr; if (infoPtr->nCurrentTool == -1) return; + toolPtr = &infoPtr->tools[infoPtr->nCurrentTool]; TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool); KillTimer32 (wndPtr->hwndSelf, ID_TIMER2); hdr.hwndFrom = wndPtr->hwndSelf; - hdr.idFrom = infoPtr->nCurrentTool; + hdr.idFrom = toolPtr->uId; hdr.code = TTN_POP; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&hdr); + SendMessage32A (toolPtr->hwnd, WM_NOTIFY, + (WPARAM32)toolPtr->uId, (LPARAM)&hdr); infoPtr->nCurrentTool = -1; @@ -270,22 +270,6 @@ TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFO32A lpToolInfo) TTTOOL_INFO *toolPtr; INT32 nTool; -#if 0 - for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) { - toolPtr = &infoPtr->tools[nTool]; - - if (toolPtr->uFlags & TTF_IDISHWND) { - if (lpToolInfo->uId == toolPtr->uId) - return nTool; - } - else { - if ((lpToolInfo->hwnd == toolPtr->hwnd) && - (lpToolInfo->uId == toolPtr->uId)) - return nTool; - } - } -#endif - for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) { toolPtr = &infoPtr->tools[nTool]; @@ -316,11 +300,7 @@ TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND32 hwnd, LPPOINT32 lpPt) for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) { toolPtr = &infoPtr->tools[nTool]; - if (toolPtr->uFlags & TTF_IDISHWND) { - if ((HWND32)toolPtr->uId == hwnd) - return nTool; - } - else { + if (!(toolPtr->uFlags & TTF_IDISHWND)) { if (hwnd != toolPtr->hwnd) continue; if (!PtInRect32 (&toolPtr->rect, *lpPt)) @@ -329,10 +309,34 @@ TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND32 hwnd, LPPOINT32 lpPt) } } + for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) { + toolPtr = &infoPtr->tools[nTool]; + + if (toolPtr->uFlags & TTF_IDISHWND) { + if ((HWND32)toolPtr->uId == hwnd) + return nTool; + } + } + return -1; } +static INT32 +TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND32 hwndTool) +{ + DWORD dwPos; + POINT32 pt; + + dwPos = GetMessagePos (); + pt.x = (INT32)LOWORD(dwPos); + pt.y = (INT32)HIWORD(dwPos); + ScreenToClient32 (hwndTool, &pt); + + return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt); +} + + static BOOL32 TOOLTIPS_CheckTool (WND *wndPtr) { @@ -381,9 +385,6 @@ TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) if (lpToolInfo == NULL) return FALSE; - if (lpToolInfo->uFlags & TTF_SUBCLASS) - FIXME (tooltips, "subclassing not supported!\n"); - TRACE (tooltips, "add tool (%x) %x %d%s!\n", wndPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId, (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : ""); @@ -435,6 +436,44 @@ TOOLTIPS_AddTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) if (lpToolInfo->cbSize >= sizeof(TTTOOLINFO32A)) toolPtr->lParam = lpToolInfo->lParam; + /* install subclassing */ + if (toolPtr->uFlags & TTF_SUBCLASS) { + if (toolPtr->uFlags & TTF_IDISHWND) { + LPTT_SUBCLASS_INFO lpttsi = + (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); + if (lpttsi == NULL) { + lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO)); + lpttsi->wpOrigProc = + (WNDPROC32)SetWindowLong32A ((HWND32)toolPtr->uId, + GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc); + lpttsi->hwndToolTip = wndPtr->hwndSelf; + lpttsi->uRefCount++; + SetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP, + (HANDLE32)lpttsi); + } + else + ERR (tooltips, "A window tool must only be listed once!\n"); + } + else { + LPTT_SUBCLASS_INFO lpttsi = + (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP); + if (lpttsi == NULL) { + lpttsi = (LPTT_SUBCLASS_INFO)HeapAlloc (GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(TT_SUBCLASS_INFO)); + lpttsi->wpOrigProc = + (WNDPROC32)SetWindowLong32A (toolPtr->hwnd, + GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc); + lpttsi->hwndToolTip = wndPtr->hwndSelf; + lpttsi->uRefCount++; + SetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP, (HANDLE32)lpttsi); + } + else + lpttsi->uRefCount++; + } + TRACE (tooltips, "subclassing installed!\n"); + } + return TRUE; } @@ -465,6 +504,38 @@ TOOLTIPS_DelTool32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) HeapFree (GetProcessHeap (), 0, toolPtr->lpszText); } + /* remove subclassing */ + if (toolPtr->uFlags & TTF_SUBCLASS) { + if (toolPtr->uFlags & TTF_IDISHWND) { + LPTT_SUBCLASS_INFO lpttsi = + (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); + if (lpttsi) { + SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC, + (LONG)lpttsi->wpOrigProc); + RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); + HeapFree (GetProcessHeap(), 0, &lpttsi); + } + else + ERR (tooltips, "Invalid data handle!\n"); + } + else { + LPTT_SUBCLASS_INFO lpttsi = + (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP); + if (lpttsi) { + if (lpttsi->uRefCount == 1) { + SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC, + (LONG)lpttsi->wpOrigProc); + RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); + HeapFree (GetProcessHeap(), 0, &lpttsi); + } + else + lpttsi->uRefCount--; + } + else + ERR (tooltips, "Invalid data handle!\n"); + } + } + /* delete tool from tool list */ if (infoPtr->uNumTools == 1) { HeapFree (GetProcessHeap (), 0, infoPtr->tools); @@ -734,7 +805,9 @@ TOOLTIPS_NewToolRect32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) INT32 nTool; if (!(lpti)) return 0; +#if 0 if (lpti->cbSize < sizeof(TTTOOLINFO32A)) return 0; +#endif nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti); if (nTool == -1) return 0; @@ -766,17 +839,11 @@ TOOLTIPS_RelayEvent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) LPMSG32 lpMsg = (LPMSG32)lParam; POINT32 pt; - if (lpMsg == NULL) { + if (lParam == NULL) { ERR (tooltips, "lpMsg == NULL!\n"); return 0; } - pt = lpMsg->pt; - ScreenToClient32 (lpMsg->hwnd, &pt); - infoPtr->nOldTool = infoPtr->nTool; - infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt); - TRACE (tooltips, "tool (%x) %d %d\n", wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool); - switch (lpMsg->message) { case WM_LBUTTONDOWN: case WM_LBUTTONUP: @@ -784,10 +851,22 @@ TOOLTIPS_RelayEvent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: + pt = lpMsg->pt; + ScreenToClient32 (lpMsg->hwnd, &pt); + infoPtr->nOldTool = infoPtr->nTool; + infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt); + TRACE (tooltips, "tool (%x) %d %d\n", + wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool); TOOLTIPS_Hide (wndPtr, infoPtr); break; case WM_MOUSEMOVE: + pt = lpMsg->pt; + ScreenToClient32 (lpMsg->hwnd, &pt); + infoPtr->nOldTool = infoPtr->nTool; + infoPtr->nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lpMsg->hwnd, &pt); + TRACE (tooltips, "tool (%x) %d %d\n", + wndPtr->hwndSelf, infoPtr->nOldTool, infoPtr->nTool); TRACE (tooltips, "WM_MOUSEMOVE (%04x %d %d)\n", wndPtr->hwndSelf, pt.x, pt.y); if ((infoPtr->bActive) && (infoPtr->nTool != infoPtr->nOldTool)) { @@ -1103,14 +1182,33 @@ static LRESULT TOOLTIPS_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(wndPtr); + TTTOOL_INFO *toolPtr; /* free tools */ if (infoPtr->tools) { INT32 i; for (i = 0; i < infoPtr->uNumTools; i++) { - if ((infoPtr->tools[i].hinst) && (infoPtr->tools[i].lpszText)) { - if (infoPtr->tools[i].lpszText != LPSTR_TEXTCALLBACK32A) - HeapFree (GetProcessHeap (), 0, infoPtr->tools[i].lpszText); + toolPtr = &infoPtr->tools[i]; + if ((toolPtr->hinst) && (toolPtr->lpszText)) { + if (toolPtr->lpszText != LPSTR_TEXTCALLBACK32A) + HeapFree (GetProcessHeap (), 0, toolPtr->lpszText); + } + + /* remove subclassing */ + if (toolPtr->uFlags & TTF_SUBCLASS) { + LPTT_SUBCLASS_INFO lpttsi; + + if (toolPtr->uFlags & TTF_IDISHWND) + lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); + else + lpttsi = (LPTT_SUBCLASS_INFO)GetProp32A (toolPtr->hwnd, TT_SUBCLASS_PROP); + + if (lpttsi) { + SetWindowLong32A ((HWND32)toolPtr->uId, GWL_WNDPROC, + (LONG)lpttsi->wpOrigProc); + RemoveProp32A ((HWND32)toolPtr->uId, TT_SUBCLASS_PROP); + HeapFree (GetProcessHeap(), 0, &lpttsi); + } } } HeapFree (GetProcessHeap (), 0, infoPtr->tools); @@ -1249,8 +1347,72 @@ TOOLTIPS_WinIniChange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -LRESULT WINAPI -ToolTipsWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) +LRESULT CALLBACK +TOOLTIPS_SubclassProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) +{ + LPTT_SUBCLASS_INFO lpttsi = + (LPTT_SUBCLASS_INFO)GetProp32A (hwnd, TT_SUBCLASS_PROP); + WND *wndPtr; + TOOLTIPS_INFO *infoPtr; + UINT32 nTool; + + switch (uMsg) { + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + { + wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip); + infoPtr = TOOLTIPS_GetInfoPtr(wndPtr); + nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd); + + TRACE (tooltips, "subclassed mouse message %04x\n", uMsg); + infoPtr->nOldTool = infoPtr->nTool; + infoPtr->nTool = nTool; + TOOLTIPS_Hide (wndPtr, infoPtr); + } + break; + + case WM_MOUSEMOVE: + { + wndPtr = WIN_FindWndPtr(lpttsi->hwndToolTip); + infoPtr = TOOLTIPS_GetInfoPtr(wndPtr); + nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd); + + TRACE (tooltips, "subclassed WM_MOUSEMOVE\n"); + infoPtr->nOldTool = infoPtr->nTool; + infoPtr->nTool = nTool; + + if ((infoPtr->bActive) && + (infoPtr->nTool != infoPtr->nOldTool)) { + if (infoPtr->nOldTool == -1) { + SetTimer32 (wndPtr->hwndSelf, ID_TIMER1, + infoPtr->nInitialTime, 0); + TRACE (tooltips, "timer 1 started!\n"); + } + else { + TOOLTIPS_Hide (wndPtr, infoPtr); + SetTimer32 (wndPtr->hwndSelf, ID_TIMER1, + infoPtr->nReshowTime, 0); + TRACE (tooltips, "timer 2 started!\n"); + } + } + if (infoPtr->nCurrentTool != -1) { + SetTimer32 (wndPtr->hwndSelf, ID_TIMER3, 100, 0); + TRACE (tooltips, "timer 3 started!\n"); + } + } + break; + } + + return CallWindowProc32A (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam); +} + + +LRESULT CALLBACK +TOOLTIPS_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) { WND *wndPtr = WIN_FindWndPtr(hwnd); @@ -1423,7 +1585,7 @@ TOOLTIPS_Register (void) ZeroMemory (&wndClass, sizeof(WNDCLASS32A)); wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS; - wndClass.lpfnWndProc = (WNDPROC32)ToolTipsWindowProc; + wndClass.lpfnWndProc = (WNDPROC32)TOOLTIPS_WindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *); wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A); diff --git a/debugger/stabs.c b/debugger/stabs.c index f3d080bc8fb..8fb9c96f847 100644 --- a/debugger/stabs.c +++ b/debugger/stabs.c @@ -1075,7 +1075,7 @@ DEBUG_ProcessElfObject(char * filename, unsigned int load_offset) goto leave; } free(fn); - if (t) s = t+1; + if (t) s = t+1; else break; } if (!s || !*s) fprintf(stderr," not found"); free(paths); diff --git a/dlls/Makefile.in b/dlls/Makefile.in new file mode 100644 index 00000000000..efbafbcf272 --- /dev/null +++ b/dlls/Makefile.in @@ -0,0 +1,21 @@ +SUBDIRS = \ + shell32 + +all: $(SUBDIRS) + +$(SUBDIRS): dummy + @cd $@; $(MAKE) + +depend: + for i in $(SUBDIRS); do (cd $$i; $(MAKE) depend) || exit 1; done + +install: + for i in $(SUBDIRS); do (cd $$i; $(MAKE) install) || exit 1; done + +uninstall: + for i in $(SUBDIRS); do (cd $$i; $(MAKE) uninstall) || exit 1; done + +clean: + for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done + +dummy: diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in new file mode 100644 index 00000000000..59a0004301d --- /dev/null +++ b/dlls/shell32/Makefile.in @@ -0,0 +1,30 @@ +DEFS = @DLLFLAGS@ -D__WINE__ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = shell32 +WRCEXTRA = -A -p $* + +C_SRCS = \ + contmenu.c \ + enumidlist.c \ + folders.c \ + pidl.c \ + shell32_main.c \ + shellole.c \ + shellord.c \ + shlfolder.c \ + shlview.c + +RC_SRCS = \ + shres.rc + +all: check_wrc $(MODULE).o + +@MAKE_RULES@ + +$(RC_SRCS:.rc=.s): $(WRC) + +### Dependencies: + diff --git a/dlls/shell32/contmenu.c b/dlls/shell32/contmenu.c new file mode 100644 index 00000000000..52ce25307c6 --- /dev/null +++ b/dlls/shell32/contmenu.c @@ -0,0 +1,383 @@ +/* + * IContextMenu + * + * Copyright 1998 Juergen Schmied + */ +#include "windows.h" +#include "winerror.h" +#include "debug.h" +#include "shlobj.h" +#include "shell32_main.h" + +#define IDM_EXPLORE 0 +#define IDM_OPEN 1 +#define IDM_RENAME 2 +#define IDM_LAST IDM_RENAME + +#define __T(x) x +#define _T(x) __T(x) +#define TEXT _T + +static HRESULT WINAPI IContextMenu_QueryInterface(LPCONTEXTMENU ,REFIID , LPVOID *); +static ULONG WINAPI IContextMenu_AddRef(LPCONTEXTMENU); +static ULONG WINAPI IContextMenu_Release(LPCONTEXTMENU); +static HRESULT WINAPI IContextMenu_QueryContextMenu(LPCONTEXTMENU , HMENU32 ,UINT32 ,UINT32 ,UINT32 ,UINT32); +static HRESULT WINAPI IContextMenu_InvokeCommand(LPCONTEXTMENU, LPCMINVOKECOMMANDINFO); +static HRESULT WINAPI IContextMenu_GetCommandString(LPCONTEXTMENU , UINT32 ,UINT32 ,LPUINT32 ,LPSTR ,UINT32); + +BOOL32 IContextMenu_AllocPidlTable(LPCONTEXTMENU, DWORD); +void IContextMenu_FreePidlTable(LPCONTEXTMENU); +BOOL32 IContextMenu_CanRenameItems(LPCONTEXTMENU); +BOOL32 IContextMenu_FillPidlTable(LPCONTEXTMENU, LPCITEMIDLIST *, UINT32); + +static struct IContextMenu_VTable cmvt = +{ IContextMenu_QueryInterface, + IContextMenu_AddRef, + IContextMenu_Release, + IContextMenu_QueryContextMenu, + IContextMenu_InvokeCommand, + IContextMenu_GetCommandString +}; +/************************************************************************** +* IContextMenu_QueryInterface +*/ +static HRESULT WINAPI IContextMenu_QueryInterface(LPCONTEXTMENU this,REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = (LPUNKNOWN)(LPCONTEXTMENU)this; + } + else if(IsEqualIID(riid, &IID_IContextMenu)) /*IContextMenu*/ + { *ppvObj = (LPCONTEXTMENU)this; + } + else if(IsEqualIID(riid, &IID_IShellExtInit)) /*IShellExtInit*/ + { *ppvObj = (LPSHELLEXTINIT)this; + } + + if(*ppvObj) + { (*(LPCONTEXTMENU*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/************************************************************************** +* IContextMenu_AddRef +*/ +static ULONG WINAPI IContextMenu_AddRef(LPCONTEXTMENU this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); + return ++(this->ref); +} +/************************************************************************** +* IContextMenu_Release +*/ +static ULONG WINAPI IContextMenu_Release(LPCONTEXTMENU this) +{ TRACE(shell,"(%p)->()\n",this); + if (!--(this->ref)) + { TRACE(shell," destroying IContextMenu(%p)\n",this); + + if(this->pSFParent) + this->pSFParent->lpvtbl->fnRelease(this->pSFParent); + + /*make sure the pidl is freed*/ + if(this->aPidls) + { IContextMenu_FreePidlTable(this); + } + + if(this->pPidlMgr) + PidlMgr_Destructor(this->pPidlMgr); + + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +/************************************************************************** +* IContextMenu_Constructor() +*/ +LPCONTEXTMENU IContextMenu_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST *aPidls, UINT32 uItemCount) +{ LPCONTEXTMENU cm; + UINT32 u; + + cm = (LPCONTEXTMENU)HeapAlloc(GetProcessHeap(),0,sizeof(IContextMenu)); + cm->lpvtbl=&cmvt; + cm->ref = 1; + + cm->pSFParent = pSFParent; + if(cm->pSFParent) + cm->pSFParent->lpvtbl->fnAddRef(cm->pSFParent); + + cm->aPidls = NULL; + cm->pPidlMgr = PidlMgr_Constructor(); + + IContextMenu_AllocPidlTable(cm, uItemCount); + + if(cm->aPidls) + { IContextMenu_FillPidlTable(cm, aPidls, uItemCount); + } + + cm->bAllValues = 1; + for(u = 0; u < uItemCount; u++) + { cm->bAllValues &= (cm->pPidlMgr->lpvtbl->fnIsValue(cm->pPidlMgr, aPidls[u]) ? 1 : 0); + } + TRACE(shell,"(%p)->()\n",cm); + return cm; +} + + +/************************************************************************** +* IContextMenu_QueryContextMenu() +*/ + +static HRESULT WINAPI IContextMenu_QueryContextMenu( LPCONTEXTMENU this, HMENU32 hmenu, + UINT32 indexMenu,UINT32 idCmdFirst,UINT32 idCmdLast,UINT32 uFlags) +{ BOOL32 fExplore ; + MENUITEMINFO32A mii; + + TRACE(shell,"(%p)->(hmenu=%x indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",this, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags); + if(!(CMF_DEFAULTONLY & uFlags)) + { if(!this->bAllValues) + { fExplore = uFlags & CMF_EXPLORE; + if(fExplore) + { ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + mii.wID = idCmdFirst + IDM_EXPLORE; + mii.fType = MFT_STRING; + mii.dwTypeData = TEXT("&Explore"); + mii.fState = MFS_ENABLED | MFS_DEFAULT; + InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii); + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + mii.wID = idCmdFirst + IDM_OPEN; + mii.fType = MFT_STRING; + mii.dwTypeData = TEXT("&Open"); + mii.fState = MFS_ENABLED; + InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii); + } + else + { ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + mii.wID = idCmdFirst + IDM_OPEN; + mii.fType = MFT_STRING; + mii.dwTypeData = TEXT("&Open"); + mii.fState = MFS_ENABLED | MFS_DEFAULT; + InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii); + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + mii.wID = idCmdFirst + IDM_EXPLORE; + mii.fType = MFT_STRING; + mii.dwTypeData = TEXT("&Explore"); + mii.fState = MFS_ENABLED; + InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii); + } + + if(uFlags & CMF_CANRENAME) + { ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE; + mii.wID = 0; + mii.fType = MFT_SEPARATOR; + InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii); + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + mii.wID = idCmdFirst + IDM_RENAME; + mii.fType = MFT_STRING; + mii.dwTypeData = TEXT("&Rename"); + mii.fState = (IContextMenu_CanRenameItems(this) ? MFS_ENABLED : MFS_DISABLED); + InsertMenuItem32A( hmenu, indexMenu++, TRUE, &mii); + } + } + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (IDM_LAST + 1)); + } + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); +} + +/************************************************************************** +* IContextMenu_InvokeCommand() +*/ +static HRESULT WINAPI IContextMenu_InvokeCommand(LPCONTEXTMENU this, LPCMINVOKECOMMANDINFO lpcmi) +{ LPITEMIDLIST pidlTemp,pidlFQ; + SHELLEXECUTEINFO sei; + int i; + + TRACE(shell,"(%p)->(execinfo=%p)\n",this,lpcmi); + + if(HIWORD(lpcmi->lpVerb)) + { //the command is being sent via a verb + return NOERROR; + } + + if(LOWORD(lpcmi->lpVerb) > IDM_LAST) + return E_INVALIDARG; + + switch(LOWORD(lpcmi->lpVerb)) + { case IDM_EXPLORE: + case IDM_OPEN: + /* Find the first item in the list that is not a value. These commands + should never be invoked if there isn't at least one key item in the list.*/ + + for(i = 0; this->aPidls[i]; i++) + { if(!this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, this->aPidls[i])) + break; + } + + pidlTemp = ILCombine(this->pSFParent->mpidl, this->aPidls[i]); + pidlFQ = ILCombine(this->pSFParent->mpidlNSRoot, pidlTemp); + SHFree(pidlTemp); + + ZeroMemory(&sei, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME; + sei.lpIDList = pidlFQ; + sei.lpClass = TEXT("folder"); + sei.hwnd = lpcmi->hwnd; + sei.nShow = SW_SHOWNORMAL; + + if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE) + { sei.lpVerb = TEXT("explore"); + } + else + { sei.lpVerb = TEXT("open"); + } + ShellExecuteEx32A(&sei); + SHFree(pidlFQ); + break; + + case IDM_RENAME: + MessageBeep32(MB_OK); + /*handle rename for the view here*/ + break; + } + return NOERROR; +} + +/************************************************************************** +* IContextMenu_GetCommandString() +*/ +static HRESULT WINAPI IContextMenu_GetCommandString( LPCONTEXTMENU this, UINT32 idCommand, + UINT32 uFlags,LPUINT32 lpReserved,LPSTR lpszName,UINT32 uMaxNameLen) +{ HRESULT hr = E_INVALIDARG; + + TRACE(shell,"(%p)->(idcom=%x flags=%x %p name=%s len=%x)\n",this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); + + switch(uFlags) + { case GCS_HELPTEXT: + hr = E_NOTIMPL; + break; + + case GCS_VERBA: + switch(idCommand) + { case IDM_RENAME: + strcpy((LPSTR)lpszName, "rename"); + hr = NOERROR; + break; + } + break; + + /* NT 4.0 with IE 3.0x or no IE will always call this with GCS_VERBW. In this + case, you need to do the lstrcpyW to the pointer passed.*/ + case GCS_VERBW: + switch(idCommand) + { case IDM_RENAME: + lstrcpyAtoW((LPWSTR)lpszName, "rename"); + hr = NOERROR; + break; + } + break; + + case GCS_VALIDATE: + hr = NOERROR; + break; + } + return hr; +} + +/************************************************************************** +* IContextMenu_AllocPidlTable() +*/ +BOOL32 IContextMenu_AllocPidlTable(LPCONTEXTMENU this, DWORD dwEntries) +{ //add one for NULL terminator + TRACE(shell,"(%p)->(entrys=%u)\n",this, dwEntries); + dwEntries++; + + this->aPidls = (LPITEMIDLIST*)SHAlloc(dwEntries * sizeof(LPITEMIDLIST)); + + if(this->aPidls) + { ZeroMemory(this->aPidls, dwEntries * sizeof(LPITEMIDLIST)); /*set all of the entries to NULL*/ + } + return (this->aPidls != NULL); +} + +/************************************************************************** +* IContextMenu_FreePidlTable() +*/ +void IContextMenu_FreePidlTable(LPCONTEXTMENU this) +{ int i; + + TRACE(shell,"(%p)->()\n",this); + + if(this->aPidls) + { for(i = 0; this->aPidls[i]; i++) + { SHFree(this->aPidls[i]); + } + + SHFree(this->aPidls); + this->aPidls = NULL; + } +} + +/************************************************************************** +* IContextMenu_FillPidlTable() +*/ +BOOL32 IContextMenu_FillPidlTable(LPCONTEXTMENU this, LPCITEMIDLIST *aPidls, UINT32 uItemCount) +{ UINT32 i; + TRACE(shell,"(%p)->(apidl=%p count=%u)\n",this, aPidls, uItemCount); + if(this->aPidls) + { for(i = 0; i < uItemCount; i++) + { this->aPidls[i] = ILClone(aPidls[i]); + } + return TRUE; + } + return FALSE; +} + +/************************************************************************** +* IContextMenu_CanRenameItems() +*/ +BOOL32 IContextMenu_CanRenameItems(LPCONTEXTMENU this) +{ UINT32 i; + DWORD dwAttributes; + + TRACE(shell,"(%p)->()\n",this); + + if(this->aPidls) + { if(this->pPidlMgr) + { for(i = 0; this->aPidls[i]; i++){} /*get the number of items assigned to this object*/ + if(i > 1) /*you can't rename more than one item at a time*/ + { return FALSE; + } + dwAttributes = SFGAO_CANRENAME; + this->pSFParent->lpvtbl->fnGetAttributesOf(this->pSFParent, i, + (LPCITEMIDLIST*)this->aPidls, &dwAttributes); + + return dwAttributes & SFGAO_CANRENAME; + } + } + return FALSE; +} + diff --git a/dlls/shell32/enumidlist.c b/dlls/shell32/enumidlist.c new file mode 100644 index 00000000000..4afff0ce515 --- /dev/null +++ b/dlls/shell32/enumidlist.c @@ -0,0 +1,357 @@ +/* + * IEnumIDList + * + * Copyright 1998 Juergen Schmied + */ + +#include +#include +#include +#include "ole.h" +#include "ole2.h" +#include "debug.h" +#include "compobj.h" +#include "interfaces.h" +#include "shlobj.h" +#include "shell.h" +#include "winerror.h" +#include "winnls.h" +#include "winproc.h" +#include "commctrl.h" + +#include "shell32_main.h" + +/* IEnumIDList Implementation */ +static HRESULT WINAPI IEnumIDList_QueryInterface(LPENUMIDLIST,REFIID,LPVOID*); +static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST); +static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST); +static HRESULT WINAPI IEnumIDList_Next(LPENUMIDLIST,ULONG,LPITEMIDLIST*,ULONG*); +static HRESULT WINAPI IEnumIDList_Skip(LPENUMIDLIST,ULONG); +static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST); +static HRESULT WINAPI IEnumIDList_Clone(LPENUMIDLIST,LPENUMIDLIST*); +static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST,LPCSTR, DWORD); +static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST,LPITEMIDLIST); +static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST); + +/************************************************************************** + * IEnumIDList_VTable + */ +static IEnumIDList_VTable eidlvt = +{ IEnumIDList_QueryInterface, + IEnumIDList_AddRef, + IEnumIDList_Release, + IEnumIDList_Next, + IEnumIDList_Skip, + IEnumIDList_Reset, + IEnumIDList_Clone, + IEnumIDList_CreateEnumList, + IEnumIDList_AddToEnumList, + IEnumIDList_DeleteList +}; + +/************************************************************************** + * IEnumIDList_Constructor + */ + +LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult) +{ LPENUMIDLIST lpeidl; + + lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList)); + lpeidl->ref = 1; + lpeidl->lpvtbl = &eidlvt; + lpeidl->mpFirst=NULL; + lpeidl->mpLast=NULL; + lpeidl->mpCurrent=NULL; + + TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,debugstr_a(lpszPath),dwFlags,pResult); + + lpeidl->mpPidlMgr=PidlMgr_Constructor(); + if (!lpeidl->mpPidlMgr) + { if (pResult) + { *pResult=E_OUTOFMEMORY; + HeapFree(GetProcessHeap(),0,lpeidl); + return NULL; + } + } + + if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags)) + { if(pResult) + { *pResult = E_OUTOFMEMORY; + HeapFree(GetProcessHeap(),0,lpeidl->mpPidlMgr); + HeapFree(GetProcessHeap(),0,lpeidl); + return NULL; + } + } + + TRACE(shell,"-- (%p)->()\n",lpeidl); + return lpeidl; +} + +/************************************************************************** + * EnumIDList::QueryInterface + */ +static HRESULT WINAPI IEnumIDList_QueryInterface( + LPENUMIDLIST this, REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = this; + } + else if(IsEqualIID(riid, &IID_IEnumIDList)) /*IEnumIDList*/ + { *ppvObj = (IEnumIDList*)this; + } + + if(*ppvObj) + { (*(LPENUMIDLIST*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/****************************************************************************** + * IEnumIDList_AddRef + */ +static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this) +{ TRACE(shell,"(%p)->()\n",this); + return ++(this->ref); +} +/****************************************************************************** + * IEnumIDList_Release + */ +static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this) +{ TRACE(shell,"(%p)->()\n",this); + if (!--(this->ref)) + { TRACE(shell," destroying IEnumIDList(%p)\n",this); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +/************************************************************************** + * IEnumIDList_Next + */ + +static HRESULT WINAPI IEnumIDList_Next( + LPENUMIDLIST this,ULONG celt,LPITEMIDLIST * rgelt,ULONG *pceltFetched) +{ ULONG i; + HRESULT hr = S_OK; + LPITEMIDLIST temp; + + TRACE(shell,"(%p)->(%ld,%p, %p)\n",this,celt,rgelt,pceltFetched); + + /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's + subsystems actually use it (and so may a third party browser) + */ + if(pceltFetched) + *pceltFetched = 0; + + *rgelt=0; + + if(celt > 1 && !pceltFetched) + { return E_INVALIDARG; + } + + for(i = 0; i < celt; i++) + { if(!(this->mpCurrent)) + { hr = S_FALSE; + break; + } + temp = ILClone(this->mpCurrent->pidl); + rgelt[i] = temp; + this->mpCurrent = this->mpCurrent->pNext; + } + if(pceltFetched) + { *pceltFetched = i; + } + + return hr; +} + +/************************************************************************** +* IEnumIDList_Skip +*/ +static HRESULT WINAPI IEnumIDList_Skip( + LPENUMIDLIST this,ULONG celt) +{ DWORD dwIndex; + HRESULT hr = S_OK; + + TRACE(shell,"(%p)->(%lu)\n",this,celt); + + for(dwIndex = 0; dwIndex < celt; dwIndex++) + { if(!this->mpCurrent) + { hr = S_FALSE; + break; + } + this->mpCurrent = this->mpCurrent->pNext; + } + return hr; +} +/************************************************************************** +* IEnumIDList_Reset +*/ +static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST this) +{ TRACE(shell,"(%p)\n",this); + this->mpCurrent = this->mpFirst; + return S_OK; +} +/************************************************************************** +* IEnumIDList_Clone +*/ +static HRESULT WINAPI IEnumIDList_Clone( + LPENUMIDLIST this,LPENUMIDLIST * ppenum) +{ TRACE(shell,"(%p)->() to (%p)->() E_NOTIMPL\n",this,ppenum); + return E_NOTIMPL; +} +/************************************************************************** + * EnumIDList_CreateEnumList() + * fixme: devices not handled + * fixme: add wildcards to path + */ +static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST this, LPCSTR lpszPath, DWORD dwFlags) +{ LPITEMIDLIST pidl=NULL; + WIN32_FIND_DATA32A stffile; + HANDLE32 hFile; + DWORD dwDrivemap; + CHAR szDriveName[4]; + CHAR szPath[MAX_PATH]; + + TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags); + + if (lpszPath && lpszPath[0]!='\0') + { strcpy(szPath, lpszPath); + PathAddBackslash(szPath); + strcat(szPath,"*.*"); + } + + /*enumerate the folders*/ + if(dwFlags & SHCONTF_FOLDERS) + { /* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood... + so we need to fake an enumeration of those.*/ + if(!lpszPath) + { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (special) items\n",this); + //create the pidl for this item + pidl = this->mpPidlMgr->lpvtbl->fnCreateMyComputer(this->mpPidlMgr); + if(pidl) + { if(!IEnumIDList_AddToEnumList(this, pidl)) + return FALSE; + } + } + else if (lpszPath[0]=='\0') /* enumerate the drives*/ + { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",this); + dwDrivemap = GetLogicalDrives(); + strcpy (szDriveName,"A:\\"); + while (szDriveName[0]<='Z') + { if(dwDrivemap & 0x00000001L) + { pidl = this->mpPidlMgr->lpvtbl->fnCreateDrive(this->mpPidlMgr,szDriveName ); + if(pidl) + { if(!IEnumIDList_AddToEnumList(this, pidl)) + return FALSE; + } + } + szDriveName[0]++; + dwDrivemap = dwDrivemap >> 1; + } + } + + else + { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",this,debugstr_a(szPath)); + hFile = FindFirstFile32A(szPath,&stffile); + if ( hFile != INVALID_HANDLE_VALUE32 ) + { do + { if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, "..")) + { pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName); + if(pidl) + { if(!IEnumIDList_AddToEnumList(this, pidl)) + { return FALSE; + } + } + else + { return FALSE; + } + } + } while( FindNextFile32A(hFile,&stffile)); + FindClose32 (hFile); + } + } + } + //enumerate the non-folder items (values) + if(dwFlags & SHCONTF_NONFOLDERS) + { if(lpszPath) + { TRACE (shell,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",this,debugstr_a(szPath)); + hFile = FindFirstFile32A(szPath,&stffile); + if ( hFile != INVALID_HANDLE_VALUE32 ) + { do + { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) + { pidl = this->mpPidlMgr->lpvtbl->fnCreateValue(this->mpPidlMgr, stffile.cFileName); + if(pidl) + { if(!IEnumIDList_AddToEnumList(this, pidl)) + { return FALSE; + } + } + else + { return FALSE; + } + } + } while( FindNextFile32A(hFile,&stffile)); + FindClose32 (hFile); + } + } + } + return TRUE; +} + +/************************************************************************** + * EnumIDList_AddToEnumList() + */ +static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST this,LPITEMIDLIST pidl) +{ LPENUMLIST pNew; + + TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); + pNew = (LPENUMLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ENUMLIST)); + if(pNew) + { //set the next pointer + pNew->pNext = NULL; + pNew->pidl = pidl; + + //is this the first item in the list? + if(!this->mpFirst) + { this->mpFirst = pNew; + this->mpCurrent = pNew; + } + + if(this->mpLast) + { //add the new item to the end of the list + this->mpLast->pNext = pNew; + } + + //update the last item pointer + this->mpLast = pNew; + TRACE(shell,"-- (%p)->(first=%p, last=%p)\n",this,this->mpFirst,this->mpLast); + return TRUE; + } + return FALSE; +} +/************************************************************************** +* EnumIDList_DeleteList() +*/ +static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST this) +{ LPENUMLIST pDelete; + + TRACE(shell,"(%p)->()\n",this); + + while(this->mpFirst) + { pDelete = this->mpFirst; + this->mpFirst = pDelete->pNext; + SHFree(pDelete->pidl); + SHFree(pDelete); + } + this->mpFirst = this->mpLast = this->mpCurrent = NULL; + return TRUE; +} diff --git a/dlls/shell32/folders.c b/dlls/shell32/folders.c new file mode 100644 index 00000000000..e9e078cf113 --- /dev/null +++ b/dlls/shell32/folders.c @@ -0,0 +1,224 @@ +/* + * Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL) + * + * Copyright 1997 Marcus Meissner + * Copyright 1998 Juergen Schmied + * + * !!! currently work in progress on all classes !!! + * + */ + +#include +#include +#include +#include "ole.h" +#include "ole2.h" +#include "debug.h" +#include "compobj.h" +#include "interfaces.h" +#include "shlobj.h" +#include "shell.h" +#include "winerror.h" +#include "winnls.h" +#include "winproc.h" +#include "commctrl.h" + +#include "shell32_main.h" + + +/****************************************************************************** +* foreward declaration +*/ + +/* IExtractIcon implementation*/ +static HRESULT WINAPI IExtractIcon_QueryInterface(LPEXTRACTICON, REFIID, LPVOID *); +static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON); +static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON); +static ULONG WINAPI IExtractIcon_Release(LPEXTRACTICON); +static HRESULT IExtractIcon_GetIconLocation(LPEXTRACTICON, UINT32, LPSTR, UINT32, int *, UINT32 *); +static HRESULT IExtractIcon_Extract(LPEXTRACTICON, LPCSTR, UINT32, HICON32 *, HICON32 *, UINT32); + +/* IShellLink Implementation */ +static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*); +static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK); +static ULONG WINAPI IShellLink_Release(LPSHELLLINK); + + +/*********************************************************************** +* IExtractIcon implementation +*/ +static struct IExtractIcon_VTable eivt = +{ IExtractIcon_QueryInterface, + IExtractIcon_AddRef, + IExtractIcon_Release, + IExtractIcon_GetIconLocation, + IExtractIcon_Extract +}; +/************************************************************************** +* IExtractIcon_Constructor +*/ +LPEXTRACTICON IExtractIcon_Constructor(LPCITEMIDLIST pidl) +{ LPEXTRACTICON ei; + ei=(LPEXTRACTICON)HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIcon)); + ei->ref=1; + ei->lpvtbl=&eivt; + ei->pidl=ILClone(pidl); + + TRACE(shell,"(%p)\n",ei); + return ei; +} +/************************************************************************** + * IExtractIcon_QueryInterface + */ +static HRESULT WINAPI IExtractIcon_QueryInterface( LPEXTRACTICON this, REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = this; + } + else if(IsEqualIID(riid, &IID_IExtractIcon)) /*IExtractIcon*/ + { *ppvObj = (IExtractIcon*)this; + } + + if(*ppvObj) + { (*(LPEXTRACTICON*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/************************************************************************** +* IExtractIcon_AddRef +*/ +static ULONG WINAPI IExtractIcon_AddRef(LPEXTRACTICON this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); + return ++(this->ref); +} +/************************************************************************** +* IExtractIcon_Release +*/ +static ULONG WINAPI IExtractIcon_Release(LPEXTRACTICON this) +{ TRACE(shell,"(%p)->()\n",this); + if (!--(this->ref)) + { TRACE(shell," destroying IExtractIcon(%p)\n",this); + SHFree(this->pidl); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} +/************************************************************************** +* IExtractIcon_GetIconLocation +* NOTE +* FIXME returns allways the icon no. 3 (closed Folder) +*/ +static HRESULT IExtractIcon_GetIconLocation(LPEXTRACTICON this, UINT32 uFlags, LPSTR szIconFile, UINT32 cchMax, int * piIndex, UINT32 * pwFlags) +{ FIXME (shell,"(%p) (flags=%u file=%s max=%u %p %p) semi-stub\n", this, uFlags, szIconFile, cchMax, piIndex, pwFlags); + *pwFlags = GIL_NOTFILENAME; + *piIndex = 3; + return NOERROR; +} +/************************************************************************** +* IExtractIcon_Extract +*/ +static HRESULT IExtractIcon_Extract(LPEXTRACTICON this, LPCSTR pszFile, UINT32 nIconIndex, HICON32 *phiconLarge, HICON32 *phiconSmall, UINT32 nIconSize) +{ FIXME (shell,"(%p) (file=%s index=%u %p %p size=%u) semi-stub\n", this, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize); + *phiconLarge = pImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT); + *phiconSmall = pImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT); + return S_OK; +} + +/************************************************************************** +* IShellLink Implementation +*/ + +static struct IShellLink_VTable slvt = { + IShellLink_QueryInterface, + IShellLink_AddRef, + IShellLink_Release, + (void *)0xcafe0004, + (void *)0xcafe0005, + (void *)0xcafe0006, + (void *)0xcafe0007, + (void *)0xcafe0008, + (void *)0xcafe0009, + (void *)0xcafe0010, + (void *)0xcafe0011, + (void *)0xcafe0012, + (void *)0xcafe0013, + (void *)0xcafe0014, + (void *)0xcafe0015, + (void *)0xcafe0016, + (void *)0xcafe0017, + (void *)0xcafe0018, + (void *)0xcafe0019, + (void *)0xcafe0020, + (void *)0xcafe0021 +}; + +/************************************************************************** + * IShellLink_Constructor + */ +LPSHELLLINK IShellLink_Constructor() +{ LPSHELLLINK sl; + + sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink)); + sl->ref = 1; + sl->lpvtbl = &slvt; + TRACE(shell,"(%p)->()\n",sl); + return sl; +} + +/************************************************************************** + * IShellLink::QueryInterface + */ +static HRESULT WINAPI IShellLink_QueryInterface( + LPSHELLLINK this, REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = this; + } + else if(IsEqualIID(riid, &IID_IShellLink)) /*IShellLink*/ + { *ppvObj = (LPSHELLLINK)this; + } + + if(*ppvObj) + { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} +/****************************************************************************** + * IShellLink_AddRef + */ +static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); + return ++(this->ref); +} +/****************************************************************************** + * IClassFactory_Release + */ +static ULONG WINAPI IShellLink_Release(LPSHELLLINK this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); + if (!--(this->ref)) + { TRACE(shell,"-- destroying IShellLink(%p)\n",this); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + + diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c new file mode 100644 index 00000000000..7b1440a5d13 --- /dev/null +++ b/dlls/shell32/pidl.c @@ -0,0 +1,846 @@ +/* + * pidl Handling + * + * Copyright 1998 Juergen Schmied + * + * !!! currently work in progress on all classes !!! + * + */ + +#include +#include +#include +#include "ole.h" +#include "ole2.h" +#include "debug.h" +#include "compobj.h" +#include "interfaces.h" +#include "shlobj.h" +#include "shell.h" +#include "winerror.h" +#include "winnls.h" +#include "winproc.h" +#include "commctrl.h" +#include "shell32_main.h" + +#include "pidl.h" + +void pdump (LPCITEMIDLIST pidl) +{ DWORD type; + CHAR * szData; + LPITEMIDLIST pidltemp = pidl; + TRACE(pidl,"---------- pidl=%p \n", pidl); + do + { szData = ((LPPIDLDATA )(pidltemp->mkid.abID))->szText; + type = ((LPPIDLDATA )(pidltemp->mkid.abID))->type; + TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData)); + pidltemp = (LPITEMIDLIST)(((BYTE*)pidltemp)+pidltemp->mkid.cb); + } while (pidltemp->mkid.cb); +} +/************************************************************************* + * ILGetDisplayName [SHELL32.15] + */ +BOOL32 WINAPI ILGetDisplayName(LPCITEMIDLIST iil,LPSTR path) +{ FIXME(pidl,"(%p,%p),stub, return e:!\n",iil,path); + strcpy(path,"e:\\"); + return TRUE; +} +/************************************************************************* + * ILFindLastID [SHELL32.16] + */ +LPSHITEMID WINAPI ILFindLastID(LPITEMIDLIST iil) +{ LPSHITEMID lastsii,sii; + + TRACE(pidl,"%p\n",iil); + if (!iil) + { return NULL; + } + sii = &(iil->mkid); + lastsii = sii; + while (sii->cb) + { lastsii = sii; + sii = (LPSHITEMID)(((char*)sii)+sii->cb); + } + return lastsii; +} +/************************************************************************* + * ILRemoveLastID [SHELL32.17] + * NOTES + * Removes the last item + */ +BOOL32 WINAPI ILRemoveLastID(LPCITEMIDLIST pidl) +{ LPCITEMIDLIST xpidl; + + TRACE(shell,"pidl=%p\n",pidl); + if (!pidl || !pidl->mkid.cb) + return 0; + ILFindLastID(pidl)->cb = 0; + return 1; +} + +/************************************************************************* + * ILClone [SHELL32.18] + * + * NOTES + * dupicate an idlist + */ +LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl) +{ DWORD len; + LPITEMIDLIST newpidl; + + TRACE(pidl,"%p\n",pidl); + + if (!pidl) + return NULL; + + len = ILGetSize(pidl); + newpidl = (LPITEMIDLIST)SHAlloc(len); + if (newpidl) + memcpy(newpidl,pidl,len); + return newpidl; +} +/************************************************************************* + * ILCloneFirst [SHELL32.19] + * + * NOTES + * duplicates the first idlist of a complex pidl + */ +LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl) +{ FIXME(pidl,"pidl=%p\n",pidl); + return NULL; +} + +/************************************************************************* + * ILCombine [SHELL32.25] + * + * NOTES + * Concatenates two complex idlists. + * The pidl is the first one, pidlsub the next one + * Does not destroy the passed in idlists! + */ +LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) +{ DWORD len1,len2; + LPITEMIDLIST pidlNew; + + TRACE(pidl,"pidl=%p pidl=%p\n",pidl1,pidl2); + + if(!pidl1 && !pidl2) + { return NULL; + } + + if(!pidl1) + { pidlNew = ILClone(pidl2); + return pidlNew; + } + + if(!pidl2) + { pidlNew = ILClone(pidl1); + return pidlNew; + } + + len1 = ILGetSize(pidl1)-2; + len2 = ILGetSize(pidl2); + pidlNew = SHAlloc(len1+len2); + + if (pidlNew) + { memcpy(pidlNew,pidl1,len1); + memcpy(((BYTE *)pidlNew)+len1,pidl2,len2); + } + +/* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/ + return pidlNew; +} +/************************************************************************* + * ILGetSize [SHELL32.152] + * gets the byte size of an idlist including zero terminator (pidl) + * + * PARAMETERS + * pidl ITEMIDLIST + * + * RETURNS + * size of pidl + * + * NOTES + * exported by ordinal + */ +DWORD WINAPI ILGetSize(LPITEMIDLIST pidl) +{ LPSHITEMID si = &(pidl->mkid); + DWORD len=0; + + TRACE(pidl,"pidl=%p\n",pidl); + + if (pidl) + { while (si->cb) + { len += si->cb; + si = (LPSHITEMID)(((LPBYTE)si)+si->cb); + } + len += 2; + } +/* TRACE(pidl,"-- size=%lu\n",len);*/ + return len; +} +/************************************************************************* + * ILGetNext [SHELL32.153] + * gets the next simple pidl ot of a complex pidl + * + * PARAMETERS + * pidl ITEMIDLIST + * + * RETURNS + * pointer to next element + * + */ +LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl) +{ LPITEMIDLIST nextpidl; + + TRACE(pidl,"(pidl=%p)\n",pidl); + if(pidl) + { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb); + return nextpidl; + } + else + { return (NULL); + } +} +/************************************************************************* + * ILAppend [SHELL32.154] + * + * NOTES + * Adds the single item to the idlist indicated by pidl. + * if bEnd is 0, adds the item to the front of the list, + * otherwise adds the item to the end. + * Destroys the passed in idlist! + */ +LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd) +{ TRACE(pidl,"(pidl=%p,pidl=%p,%08u)\n",pidl,item,bEnd); + return NULL; +} +/************************************************************************* + * ILFree [SHELL32.155] + * + * NOTES + * free_check_ptr - frees memory (if not NULL) + * allocated by SHMalloc allocator + * exported by ordinal + */ +DWORD WINAPI ILFree(LPVOID pidl) +{ TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl); + if (!pidl) + return 0; + return SHFree(pidl); +} + +/************************************************************************** +* INTERNAL CLASS pidlmgr +*/ + +static struct PidlMgr_VTable pmgrvt = { + PidlMgr_CreateDesktop, + PidlMgr_CreateMyComputer, + PidlMgr_CreateDrive, + PidlMgr_CreateFolder, + PidlMgr_CreateValue, + PidlMgr_GetDesktop, + PidlMgr_GetDrive, + PidlMgr_GetLastItem, + PidlMgr_GetItemText, + PidlMgr_IsDesktop, + PidlMgr_IsMyComputer, + PidlMgr_IsDrive, + PidlMgr_IsFolder, + PidlMgr_IsValue, + PidlMgr_HasFolders, + PidlMgr_GetFolderText, + PidlMgr_GetValueText, + PidlMgr_GetValueType, + PidlMgr_GetDataText, + PidlMgr_GetPidlPath, + PidlMgr_Create, + PidlMgr_GetData, + PidlMgr_GetDataPointer, + PidlMgr_SeparatePathAndValue +}; +/************************************************************************** + * PidlMgr_Constructor + */ +LPPIDLMGR PidlMgr_Constructor() +{ LPPIDLMGR pmgr; + pmgr = (LPPIDLMGR)HeapAlloc(GetProcessHeap(),0,sizeof(pidlmgr)); + pmgr->lpvtbl = &pmgrvt; + TRACE(pidl,"(%p)->()\n",pmgr); + /** FIXMEDllRefCount++;*/ + return pmgr; +} +/************************************************************************** + * PidlMgr_Destructor + */ +void PidlMgr_Destructor(LPPIDLMGR this) +{ HeapFree(GetProcessHeap(),0,this); + TRACE(pidl,"(%p)->()\n",this); + /** FIXMEDllRefCount--;*/ +} + +/************************************************************************** + * PidlMgr_CreateDesktop() + * PidlMgr_CreateMyComputer() + * PidlMgr_CreateDrive() + * PidlMgr_CreateFolder() + * PidlMgr_CreateValue() + */ +LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this) +{ TRACE(pidl,"(%p)->()\n",this); + return PidlMgr_Create(this,PT_DESKTOP, NULL, 0); +} +LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this) +{ TRACE(pidl,"(%p)->()\n",this); + return PidlMgr_Create(this,PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1); +} +LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR this, LPCSTR lpszNew) +{ char sTemp[4]; + strncpy (sTemp,lpszNew,4); + sTemp[2]='\\'; + sTemp[3]=0x00; + TRACE(pidl,"(%p)->(%s)\n",this,sTemp); + return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4); +} +LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew) +{ TRACE(pidl,"(%p)->(%s)\n",this,lpszNew); + return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1); +} +LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew) +{ TRACE(pidl,"(%p)->(%s)\n",this,lpszNew); + return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1); +} + +/************************************************************************** + * PidlMgr_GetDesktop() + * + * FIXME: quick hack + */ +BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut) +{ TRACE(pidl,"(%p)->(%p %p)\n",this,pidl,pOut); + return (BOOL32)PidlMgr_GetData(this,PT_DESKTOP, pidl, (LPVOID)pOut, 255); +} +/************************************************************************** + * PidlMgr_GetDrive() + * + * FIXME: quick hack + */ +BOOL32 PidlMgr_GetDrive(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize) +{ LPITEMIDLIST pidlTemp=NULL; + + TRACE(pidl,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize); + if(PidlMgr_IsMyComputer(this,pidl)) + { pidlTemp = ILGetNext(pidl); + } + else if (pidlTemp && PidlMgr_IsDrive(this,pidlTemp)) + { return (BOOL32)PidlMgr_GetData(this,PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize); + } + return FALSE; +} +/************************************************************************** + * PidlMgr_GetLastItem() + * Gets the last item in the list + */ +LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR this,LPCITEMIDLIST pidl) +{ LPITEMIDLIST pidlLast = NULL; + + TRACE(pidl,"(%p)->(pidl=%p)\n",this,pidl); + + if(pidl) + { while(pidl->mkid.cb) + { pidlLast = (LPITEMIDLIST)pidl; + pidl = ILGetNext(pidl); + } + } + return pidlLast; +} +/************************************************************************** + * PidlMgr_GetItemText() + * Gets the text for only this item + */ +DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize) +{ TRACE(pidl,"(%p)->(pidl=%p %p %x)\n",this,pidl,lpszText,uSize); + if (PidlMgr_IsMyComputer(this, pidl)) + { return PidlMgr_GetData(this,PT_MYCOMP, pidl, (LPVOID)lpszText, uSize); + } + if (PidlMgr_IsDrive(this, pidl)) + { return PidlMgr_GetData(this,PT_DRIVE, pidl, (LPVOID)lpszText, uSize); + } + return PidlMgr_GetData(this,PT_TEXT, pidl, (LPVOID)lpszText, uSize); +} +/************************************************************************** + * PidlMgr_IsDesktop() + * PidlMgr_IsDrive() + * PidlMgr_IsFolder() + * PidlMgr_IsValue() +*/ +BOOL32 PidlMgr_IsDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl) +{ TRACE(pidl,"%p->(%p)\n",this,pidl); + + if (! pidl) + return FALSE; + + return ( pidl->mkid.cb == 0x00 ); +} + +BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl) +{ LPPIDLDATA pData; + TRACE(pidl,"%p->(%p)\n",this,pidl); + + if (! pidl) + return FALSE; + + pData = PidlMgr_GetDataPointer(this,pidl); + return (PT_MYCOMP == pData->type); +} + +BOOL32 PidlMgr_IsDrive(LPPIDLMGR this,LPCITEMIDLIST pidl) +{ LPPIDLDATA pData; + TRACE(pidl,"%p->(%p)\n",this,pidl); + + if (! pidl) + return FALSE; + + pData = PidlMgr_GetDataPointer(this,pidl); + return (PT_DRIVE == pData->type); +} + +BOOL32 PidlMgr_IsFolder(LPPIDLMGR this,LPCITEMIDLIST pidl) +{ LPPIDLDATA pData; + TRACE(pidl,"%p->(%p)\n",this,pidl); + + if (! pidl) + return FALSE; + + pData = PidlMgr_GetDataPointer(this,pidl); + return (PT_FOLDER == pData->type); +} + +BOOL32 PidlMgr_IsValue(LPPIDLMGR this,LPCITEMIDLIST pidl) +{ LPPIDLDATA pData; + TRACE(pidl,"%p->(%p)\n",this,pidl); + + if (! pidl) + return FALSE; + + pData = PidlMgr_GetDataPointer(this,pidl); + return (PT_VALUE == pData->type); +} +/************************************************************************** + * PidlMgr_HasFolders() + * fixme: quick hack + */ +BOOL32 PidlMgr_HasFolders(LPPIDLMGR this, LPSTR pszPath, LPCITEMIDLIST pidl) +{ BOOL32 bResult= FALSE; + WIN32_FIND_DATA32A stffile; + HANDLE32 hFile; + + TRACE(pidl,"(%p)->%p %p\n",this, pszPath, pidl); + + hFile = FindFirstFile32A(pszPath,&stffile); + do + { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) + { bResult= TRUE; + } + } while( FindNextFile32A(hFile,&stffile)); + FindClose32 (hFile); + + return bResult; +} + + +/************************************************************************** + * PidlMgr_GetFolderText() + * Creates a Path string from a PIDL, filtering out the special Folders + */ +DWORD PidlMgr_GetFolderText(LPPIDLMGR this,LPCITEMIDLIST pidl, + LPSTR lpszPath, DWORD dwSize) +{ LPITEMIDLIST pidlTemp; + DWORD dwCopied = 0; + + TRACE(pidl,"(%p)->(%p)\n",this,pidl); + + if(!pidl) + { return 0; + } + + if(PidlMgr_IsMyComputer(this,pidl)) + { pidlTemp = ILGetNext(pidl); + TRACE(pidl,"-- (%p)->skip My Computer\n",this); + } + else + { pidlTemp = (LPITEMIDLIST)pidl; + } + + //if this is NULL, return the required size of the buffer + if(!lpszPath) + { while(pidlTemp->mkid.cb) + { LPPIDLDATA pData = PidlMgr_GetDataPointer(this,pidlTemp); + + //add the length of this item plus one for the backslash + dwCopied += strlen(pData->szText) + 1; /* FIXME pData->szText is not every time a string*/ + + pidlTemp = ILGetNext(pidlTemp); + } + + //add one for the NULL terminator + TRACE(pidl,"-- (%p)->(size=%lu)\n",this,dwCopied); + return dwCopied + 1; + } + + *lpszPath = 0; + + while(pidlTemp->mkid.cb && (dwCopied < dwSize)) + { LPPIDLDATA pData = PidlMgr_GetDataPointer(this,pidlTemp); + + //if this item is a value, then skip it and finish + if(PT_VALUE == pData->type) + { break; + } + + strcat(lpszPath, pData->szText); + strcat(lpszPath, "\\"); + dwCopied += strlen(pData->szText) + 1; + pidlTemp = ILGetNext(pidlTemp); + + TRACE(pidl,"-- (%p)->(size=%lu,%s)\n",this,dwCopied,lpszPath); + } + + //remove the last backslash if necessary + if(dwCopied) + { if(*(lpszPath + strlen(lpszPath) - 1) == '\\') + { *(lpszPath + strlen(lpszPath) - 1) = 0; + dwCopied--; + } + } + TRACE(pidl,"-- (%p)->(path=%s)\n",this,lpszPath); + return dwCopied; +} + + +/************************************************************************** + * PidlMgr_GetValueText() + * Gets the text for the last item in the list + */ +DWORD PidlMgr_GetValueText(LPPIDLMGR this, + LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize) +{ LPITEMIDLIST pidlTemp=pidl; + CHAR szText[MAX_PATH]; + + TRACE(pidl,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize); + + if(!pidl) + { return 0; + } + + while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp)) + { pidlTemp = ILGetNext(pidlTemp); + } + + if(!pidlTemp->mkid.cb) + { return 0; + } + + PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText)); + + if(!lpszValue) + { return strlen(szText) + 1; + } + strcpy(lpszValue, szText); + TRACE(pidl,"-- (%p)->(pidl=%p %p=%s 0x%08lx)\n",this,pidl,lpszValue,lpszValue,dwSize); + return strlen(lpszValue); +} +/************************************************************************** + * PidlMgr_GetValueType() + */ +BOOL32 PidlMgr_GetValueType( LPPIDLMGR this, + LPCITEMIDLIST pidlPath, + LPCITEMIDLIST pidlValue, + LPDWORD pdwType) +{ LPSTR lpszFolder, + lpszValueName; + DWORD dwNameSize; + + FIXME(pidl,"(%p)->(%p %p %p) stub\n",this,pidlPath,pidlValue,pdwType); + + if(!pidlPath) + { return FALSE; + } + + if(!pidlValue) + { return FALSE; + } + + if(!pdwType) + { return FALSE; + } + + //get the Desktop + //PidlMgr_GetDesktop(this,pidlPath); + + /* fixme: add the driveletter here*/ + + //assemble the Folder string + dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0); + lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); + if(!lpszFolder) + { return FALSE; + } + PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize); + + //assemble the value name + dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0); + lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); + if(!lpszValueName) + { HeapFree(GetProcessHeap(),0,lpszFolder); + return FALSE; + } + PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize); + + /* fixme: we've got the path now do something with it + -like get the filetype*/ + + pdwType=NULL; + + HeapFree(GetProcessHeap(),0,lpszFolder); + HeapFree(GetProcessHeap(),0,lpszValueName); + return TRUE; +} +/************************************************************************** + * PidlMgr_GetDataText() + */ +DWORD PidlMgr_GetDataText( LPPIDLMGR this, + LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize) +{ LPSTR lpszFolder, + lpszValueName; + DWORD dwNameSize; + + FIXME(pidl,"(%p)->(pidl=%p pidl=%p) stub\n",this,pidlPath,pidlValue); + + if(!lpszOut || !pidlPath || !pidlValue) + { return FALSE; + } + + /* fixme: get the driveletter*/ + + //assemble the Folder string + dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0); + lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); + if(!lpszFolder) + { return FALSE; + } + PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize); + + //assemble the value name + dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0); + lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); + if(!lpszValueName) + { HeapFree(GetProcessHeap(),0,lpszFolder); + return FALSE; + } + PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize); + + /* fixme: we've got the path now do something with it*/ + + HeapFree(GetProcessHeap(),0,lpszFolder); + HeapFree(GetProcessHeap(),0,lpszValueName); + + TRACE(pidl,"-- (%p)->(%p=%s 0x%08lx)\n",this,lpszOut,lpszOut,dwOutSize); + + return TRUE; +} + +/************************************************************************** + * CPidlMgr::GetPidlPath() + * Create a string that includes the Drive name, the folder text and + * the value text. + */ +DWORD PidlMgr_GetPidlPath(LPPIDLMGR this, + LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize) +{ LPSTR lpszTemp; + WORD len; + + TRACE(pidl,"(%p)->(%p,%lu)\n",this,lpszOut,dwOutSize); + + if(!lpszOut) + { return 0; + } + + *lpszOut = 0; + lpszTemp = lpszOut; + + dwOutSize -= PidlMgr_GetFolderText(this,pidl, lpszTemp, dwOutSize); + + //add a backslash if necessary + len = strlen(lpszTemp); + if (len && lpszTemp[len-1]!='\\') + { lpszTemp[len+0]='\\'; + lpszTemp[len+1]='\0'; + dwOutSize--; + } + + lpszTemp = lpszOut + strlen(lpszOut); + + //add the value string + PidlMgr_GetValueText(this,pidl, lpszTemp, dwOutSize); + + //remove the last backslash if necessary + if(*(lpszOut + strlen(lpszOut) - 1) == '\\') + { *(lpszOut + strlen(lpszOut) - 1) = 0; + } + + TRACE(pidl,"-- (%p)->(%p=%s,%lu)\n",this,lpszOut,lpszOut,dwOutSize); + + return strlen(lpszOut); + +} + +/************************************************************************** + * PidlMgr_Create() + * Creates a new PIDL + * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE + * pIn = data + * uInSize = size of data + */ + +LPITEMIDLIST PidlMgr_Create(LPPIDLMGR this,PIDLTYPE type, LPVOID pIn, UINT16 uInSize) +{ LPITEMIDLIST pidlOut=NULL; + UINT16 uSize; + LPITEMIDLIST pidlTemp=NULL; + LPPIDLDATA pData; + + TRACE(pidl,"(%p)->(%x %p %x)\n",this,type,pIn,uInSize); + + if ( type == PT_DESKTOP) + { pidlOut = SHAlloc(2); + pidlOut->mkid.cb=0x0000; + return pidlOut; + } + + if (! pIn) + { return NULL; + } + + uSize = 2 + (sizeof(PIDLTYPE)) + uInSize + 2; /* cb + PIDLTYPE + uInSize +2 */ + pidlOut = SHAlloc(uSize); + pidlTemp = pidlOut; + if(pidlOut) + { pidlTemp->mkid.cb = uSize - 2; + pData =(LPPIDLDATA) &(pidlTemp->mkid.abID[0]); + pData->type = type; + switch(type) + { case PT_MYCOMP: + memcpy(pData->szText, pIn, uInSize); + TRACE(pidl,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText)); + break; + case PT_DRIVE: + memcpy(pData->szText, pIn, uInSize); + TRACE(pidl,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText)); + break; + case PT_FOLDER: + case PT_VALUE: + memcpy(pData->szText, pIn, uInSize); + TRACE(pidl,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText)); + break; + default: + FIXME(pidl,"- (%p) wrong argument\n",this); + break; + } + + pidlTemp = ILGetNext(pidlTemp); + pidlTemp->mkid.cb = 0x00; + } + TRACE(pidl,"-- (%p)->(pidl=%p, size=%u)\n",this,pidlOut,uSize-2); + return pidlOut; +} +/************************************************************************** + * PidlMgr_GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16) + */ +DWORD PidlMgr_GetData( + LPPIDLMGR this, + PIDLTYPE type, + LPCITEMIDLIST pidl, + LPVOID pOut, + UINT16 uOutSize) +{ LPPIDLDATA pData; + DWORD dwReturn=0; + + TRACE(pidl,"(%p)->(%x %p %p %x)\n",this,type,pidl,pOut,uOutSize); + + if(!pidl) + { return 0; + } + + pData = PidlMgr_GetDataPointer(this,pidl); + + //copy the data + switch(type) + { case PT_MYCOMP: if(uOutSize < 1) + return 0; + if(PT_MYCOMP != pData->type) + return 0; + *(LPSTR)pOut = 0; + strncpy((LPSTR)pOut, "My Computer", uOutSize); + dwReturn = strlen((LPSTR)pOut); + break; + + case PT_DRIVE: if(uOutSize < 1) + return 0; + if(PT_DRIVE != pData->type) + return 0; + *(LPSTR)pOut = 0; + strncpy((LPSTR)pOut, pData->szText, uOutSize); + dwReturn = strlen((LPSTR)pOut); + break; + + case PT_FOLDER: + case PT_VALUE: + case PT_TEXT: *(LPSTR)pOut = 0; + strncpy((LPSTR)pOut, pData->szText, uOutSize); + dwReturn = strlen((LPSTR)pOut); + break; + default: break; + } + TRACE(pidl,"-- (%p)->(%p=%s 0x%08lx)\n",this,pOut,(char*)pOut,dwReturn); + return dwReturn; +} + + +/************************************************************************** + * PidlMgr_GetDataPointer() + */ +LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR this,LPITEMIDLIST pidl) +{ if(!pidl) + { return NULL; + } + TRACE(pidl,"(%p)->(%p)\n" ,this, pidl); + return (LPPIDLDATA)(pidl->mkid.abID); +} + +/************************************************************************** + * CPidlMgr_SeparatePathAndValue) + * Creates a separate path and value PIDL from a fully qualified PIDL. + */ +BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR this, + LPITEMIDLIST pidlFQ, LPITEMIDLIST *ppidlPath, LPITEMIDLIST *ppidlValue) +{ LPITEMIDLIST pidlTemp; + TRACE(pidl,"(%p)->(pidl=%p pidl=%p pidl=%p)",this,pidlFQ,ppidlPath,ppidlValue); + if(!pidlFQ) + { return FALSE; + } + + *ppidlValue = PidlMgr_GetLastItem(this,pidlFQ); + + if(!PidlMgr_IsValue(this,*ppidlValue)) + { return FALSE; + } + + *ppidlValue = ILClone(*ppidlValue); + *ppidlPath = ILClone(pidlFQ); + + pidlTemp = PidlMgr_GetLastItem(this,*ppidlPath); + pidlTemp->mkid.cb = 0x00; + + return TRUE; +} diff --git a/dlls/shell32/pidl.h b/dlls/shell32/pidl.h new file mode 100644 index 00000000000..0817b536f76 --- /dev/null +++ b/dlls/shell32/pidl.h @@ -0,0 +1,31 @@ +/* INTERNAL CLASS pidlmgr */ + +#ifndef __WINE_PIDL_H +#define __WINE_PIDL_H + +extern LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR); +extern LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR); +extern LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR,LPCSTR); +extern LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR,LPCSTR); +extern LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR,LPCSTR); +extern BOOL32 PidlMgr_GetDesktop(LPPIDLMGR,LPCITEMIDLIST,LPSTR); +extern BOOL32 PidlMgr_GetDrive(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16); +extern LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR,LPCITEMIDLIST); +extern DWORD PidlMgr_GetItemText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16); +extern BOOL32 PidlMgr_IsDesktop(LPPIDLMGR,LPCITEMIDLIST); +extern BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR,LPCITEMIDLIST); +extern BOOL32 PidlMgr_IsDrive(LPPIDLMGR,LPCITEMIDLIST); +extern BOOL32 PidlMgr_IsFolder(LPPIDLMGR,LPCITEMIDLIST); +extern BOOL32 PidlMgr_IsValue(LPPIDLMGR,LPCITEMIDLIST); +extern BOOL32 PidlMgr_HasFolders(LPPIDLMGR,LPSTR,LPCITEMIDLIST); +extern DWORD PidlMgr_GetFolderText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); +extern DWORD PidlMgr_GetValueText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); +extern BOOL32 PidlMgr_GetValueType(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPDWORD); +extern DWORD PidlMgr_GetDataText(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPSTR,DWORD); +extern DWORD PidlMgr_GetPidlPath(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); +extern LPITEMIDLIST PidlMgr_Create(LPPIDLMGR,PIDLTYPE,LPVOID,UINT16); +extern DWORD PidlMgr_GetData(LPPIDLMGR,PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT16); +extern LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR,LPCITEMIDLIST); +extern BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST*,LPITEMIDLIST*); + +#endif diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c new file mode 100644 index 00000000000..2a348f8b793 --- /dev/null +++ b/dlls/shell32/shell32_main.c @@ -0,0 +1,962 @@ +/* + * Shell basics + * + * 1998 Marcus Meissner + * 1998 Juergen Schmied (jsch) * + */ +#include +#include +#include +#include +#include +#include "windows.h" +#include "winerror.h" +#include "file.h" +#include "shell.h" +#include "heap.h" +#include "module.h" +#include "neexe.h" +#include "resource.h" +#include "dlgs.h" +#include "win.h" +#include "graphics.h" +#include "cursoricon.h" +#include "interfaces.h" +#include "sysmetrics.h" +#include "shlobj.h" +#include "debug.h" +#include "winreg.h" +#include "imagelist.h" +#include "commctrl.h" +#include "authors.h" + +#include "shell32_main.h" + +/************************************************************************* + * CommandLineToArgvW [SHELL32.7] + */ +LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs) +{ LPWSTR *argv,s,t; + int i; + TRACE(shell,"\n"); + + /* to get writeable copy */ + cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline); + s=cmdline;i=0; + while (*s) + { /* space */ + if (*s==0x0020) + { i++; + s++; + while (*s && *s==0x0020) + s++; + continue; + } + s++; + } + argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) ); + s=t=cmdline; + i=0; + while (*s) + { if (*s==0x0020) + { *s=0; + argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t ); + *s=0x0020; + while (*s && *s==0x0020) + s++; + if (*s) + t=s+1; + else + t=s; + continue; + } + s++; + } + if (*t) + argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t ); + HeapFree( GetProcessHeap(), 0, cmdline ); + argv[i]=NULL; + *numargs=i; + return argv; +} + +/************************************************************************* + * Control_RunDLL [SHELL32.12] + * + * Wild speculation in the following! + * + * http://premium.microsoft.com/msdn/library/techart/msdn193.htm + */ + +void WINAPI Control_RunDLL (HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4) +{ FIXME(shell, "(%08x, %p, \"%s\", %08lx)\n", + hwnd, code ? code : "(null)", cmd ? cmd : "(null)", arg4); +} + +/************************************************************************* + * Shell_GetImageList [SHELL32.71] + * + * PARAMETERS + * imglist[1|2] [OUT] pointer which recive imagelist handles + * + * NOTES + * undocumented + * I don't know, which pointer is which. They may have to be + * exchanged. (jsch) + */ +BOOL32 WINAPI Shell_GetImageList(HIMAGELIST * imglist1,HIMAGELIST * imglist2) +{ WARN(shell,"(%p,%p):semi-stub.\n",imglist1,imglist2); + if (imglist1) + { *imglist1=ShellBigIconList; + } + if (imglist2) + { *imglist2=ShellSmallIconList; + } + + return TRUE; +} + +/************************************************************************* + * SHGetFileInfoA [SHELL32.218] + * + * FIXME + * + */ +HIMAGELIST ShellSmallIconList = 0; +HIMAGELIST ShellBigIconList = 0; + +DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes, + SHFILEINFO32A *psfi, UINT32 sizeofpsfi, + UINT32 flags ) +{ CHAR szTemp[MAX_PATH]; + DWORD ret=0; + + TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n", + path,dwFileAttributes,psfi,sizeofpsfi,flags); + + /* translate the pidl to a path*/ + if (flags & SHGFI_PIDL) + { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp); + TRACE(shell,"pidl=%p is %s\n",path,szTemp); + } + else + { TRACE(shell,"path=%p\n",path); + } + + if (flags & SHGFI_ATTRIBUTES) + { FIXME(shell,"file attributes, stub\n"); + psfi->dwAttributes=SFGAO_FILESYSTEM; + ret=TRUE; + } + + if (flags & SHGFI_DISPLAYNAME) + { if (flags & SHGFI_PIDL) + { strcpy(psfi->szDisplayName,szTemp); + } + else + { strcpy(psfi->szDisplayName,path); + TRACE(shell,"displayname=%s\n", szTemp); + } + ret=TRUE; + } + + if (flags & SHGFI_TYPENAME) + { FIXME(shell,"get the file type, stub\n"); + strcpy(psfi->szTypeName,""); + ret=TRUE; + } + + if (flags & SHGFI_ICONLOCATION) + { FIXME(shell,"location of icon, stub\n"); + strcpy(psfi->szDisplayName,""); + ret=TRUE; + } + + if (flags & SHGFI_EXETYPE) + FIXME(shell,"type of executable, stub\n"); + + if (flags & SHGFI_LINKOVERLAY) + FIXME(shell,"set icon to link, stub\n"); + + if (flags & SHGFI_OPENICON) + FIXME(shell,"set to open icon, stub\n"); + + if (flags & SHGFI_SELECTED) + FIXME(shell,"set icon to selected, stub\n"); + + if (flags & SHGFI_SHELLICONSIZE) + FIXME(shell,"set icon to shell size, stub\n"); + + if (flags & SHGFI_USEFILEATTRIBUTES) + FIXME(shell,"use the dwFileAttributes, stub\n"); + + if (flags & SHGFI_ICON) + { FIXME(shell,"icon handle\n"); + if (flags & SHGFI_SMALLICON) + { TRACE(shell,"set to small icon\n"); + psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL); + ret = (DWORD) ShellSmallIconList; + } + else + { TRACE(shell,"set to big icon\n"); + psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL); + ret = (DWORD) ShellBigIconList; + } + } + + if (flags & SHGFI_SYSICONINDEX) + { FIXME(shell,"get the SYSICONINDEX\n"); + psfi->iIcon=32; + if (flags & SHGFI_SMALLICON) + { TRACE(shell,"set to small icon\n"); + ret = (DWORD) ShellSmallIconList; + } + else + { TRACE(shell,"set to big icon\n"); + ret = (DWORD) ShellBigIconList; + } + } + + + return ret; +} + +/************************************************************************* + * ExtractIcon32A (SHELL32.133) + */ +HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName, + UINT32 nIconIndex ) +{ HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1); + TRACE(shell,"\n"); + if( handle ) + { + HICON16* ptr = (HICON16*)GlobalLock16(handle); + HICON16 hIcon = *ptr; + + GlobalFree16(handle); + return hIcon; + } + return 0; +} + +/************************************************************************* + * ExtractIcon32W (SHELL32.180) + */ +HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName, + UINT32 nIconIndex ) +{ LPSTR exefn; + HICON32 ret; + TRACE(shell,"\n"); + + exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName); + ret = ExtractIcon32A(hInstance,exefn,nIconIndex); + + HeapFree(GetProcessHeap(),0,exefn); + return ret; +} + +/************************************************************************* + * FindExecutable32A (SHELL32.184) + */ +HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory, + LPSTR lpResult ) +{ HINSTANCE32 retval=31; /* default - 'No association was found' */ + char old_dir[1024]; + + TRACE(shell, "File %s, Dir %s\n", + (lpFile != NULL?lpFile:"-"), + (lpDirectory != NULL?lpDirectory:"-")); + + lpResult[0]='\0'; /* Start off with an empty return string */ + + /* trap NULL parameters on entry */ + if (( lpFile == NULL ) || ( lpResult == NULL )) + { /* FIXME - should throw a warning, perhaps! */ + return 2; /* File not found. Close enough, I guess. */ + } + + if (lpDirectory) + { GetCurrentDirectory32A( sizeof(old_dir), old_dir ); + SetCurrentDirectory32A( lpDirectory ); + } + + retval = SHELL_FindExecutable( lpFile, "open", lpResult ); + + TRACE(shell, "returning %s\n", lpResult); + if (lpDirectory) + SetCurrentDirectory32A( old_dir ); + return retval; +} + +typedef struct +{ LPCSTR szApp; + LPCSTR szOtherStuff; + HICON32 hIcon; +} ABOUT_INFO; + +#define IDC_STATIC_TEXT 100 +#define IDC_LISTBOX 99 +#define IDC_WINE_TEXT 98 + +#define DROP_FIELD_TOP (-15) +#define DROP_FIELD_HEIGHT 15 + +extern HICON32 hIconTitleFont; + +static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect ) +{ HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT); + if( hWndCtl ) + { GetWindowRect32( hWndCtl, lprect ); + MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 ); + lprect->bottom = (lprect->top += DROP_FIELD_TOP); + return TRUE; + } + return FALSE; +} + +/************************************************************************* + * SHAppBarMessage32 [SHELL32.207] + */ +UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data) +{ FIXME(shell,"(0x%08lx,%p): stub\n", msg, data); +#if 0 + switch (msg) + { case ABM_ACTIVATE: + case ABM_GETAUTOHIDEBAR: + case ABM_GETSTATE: + case ABM_GETTASKBARPOS: + case ABM_NEW: + case ABM_QUERYPOS: + case ABM_REMOVE: + case ABM_SETAUTOHIDEBAR: + case ABM_SETPOS: + case ABM_WINDOWPOSCHANGED: + ; + } +#endif + return 0; +} + +/************************************************************************* + * SHBrowseForFolderA [SHELL32.209] + * + */ +LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi) +{ FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle); + return NULL; +} + +/************************************************************************* + * SHGetDesktopFolder [SHELL32.216] + * + * SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with + * CLSID_ShellDesktop + * CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf); + * + * RETURNS + * the interface to the shell desktop folder. + * + * FIXME + * the pdesktopfolder has to be released at the end (at dll unloading???) + */ +LPSHELLFOLDER pdesktopfolder=NULL; + +DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) +{ HRESULT hres = E_OUTOFMEMORY; + LPCLASSFACTORY lpclf; + TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder); + + if (pdesktopfolder) + { hres = NOERROR; + } + else + { lpclf = IClassFactory_Constructor(); + /* fixme: the buildin IClassFactory_Constructor is at the moment only + for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/ + if(lpclf) + { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder); + lpclf->lpvtbl->fnRelease(lpclf); + } + } + + if (pdesktopfolder) + { *shellfolder = pdesktopfolder; + pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder); + } + else + { *shellfolder=NULL; + } + + TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder); + return hres; +} +/************************************************************************* + * SHGetPathFromIDList [SHELL32.221][NT 4.0: SHELL32.219] + */ +BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath) +{ TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath); + return SHGetPathFromIDList32A(pidl,pszPath); +} + +/************************************************************************* + * SHGetSpecialFolderLocation [SHELL32.223] + * gets the folder locations from the registry and creates a pidl + * creates missing reg keys and directorys + * + * PARAMS + * hwndOwner [I] + * nFolder [I] CSIDL_xxxxx + * ppidl [O] PIDL of a special folder + * + * RETURNS + * HResult + * + * FIXME + * - look for "User Shell Folder" first + * + */ +HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl) +{ LPSHELLFOLDER shellfolder; + DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res; + CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH]; + LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0]; + HKEY key; + + enum + { FT_UNKNOWN= 0x00000000, + FT_DIR= 0x00000001, + FT_DESKTOP= 0x00000002 + } tFolder; + + TRACE(shell,"(%04x,%d,%p)\n", hwndOwner,nFolder,ppidl); + + strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); + + res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp); + if (res) + { ERR(shell,"Could not create key %s %08lx \n",buffer,res); + return E_OUTOFMEMORY; + } + + tFolder=FT_DIR; + switch (nFolder) + { case CSIDL_BITBUCKET: + strcpy (buffer,"xxx"); /*not in the registry*/ + TRACE (shell,"looking for Recycler\n"); + tFolder=FT_UNKNOWN; + break; + case CSIDL_CONTROLS: + strcpy (buffer,"xxx"); /*virtual folder*/ + TRACE (shell,"looking for Control\n"); + tFolder=FT_UNKNOWN; + break; + case CSIDL_DESKTOP: + strcpy (buffer,"xxx"); /*virtual folder*/ + TRACE (shell,"looking for Desktop\n"); + tFolder=FT_DESKTOP; + break; + case CSIDL_DESKTOPDIRECTORY: + strcpy (buffer,"Desktop"); + break; + case CSIDL_DRIVES: + strcpy (buffer,"xxx"); /*virtual folder*/ + TRACE (shell,"looking for Drives\n"); + tFolder=FT_UNKNOWN; + break; + case CSIDL_FONTS: + strcpy (buffer,"Fonts"); + break; + case CSIDL_NETHOOD: + strcpy (buffer,"NetHood"); + break; + case CSIDL_NETWORK: + strcpy (buffer,"xxx"); /*virtual folder*/ + TRACE (shell,"looking for Network\n"); + tFolder=FT_UNKNOWN; + break; + case CSIDL_PERSONAL: + strcpy (buffer,"Personal"); + break; + case CSIDL_FAVORITES: + strcpy (buffer,"Favorites"); + break; + case CSIDL_PRINTERS: + strcpy (buffer,"PrintHood"); + break; + case CSIDL_PROGRAMS: + strcpy (buffer,"Programs"); + break; + case CSIDL_RECENT: + strcpy (buffer,"Recent"); + break; + case CSIDL_SENDTO: + strcpy (buffer,"SendTo"); + break; + case CSIDL_STARTMENU: + strcpy (buffer,"Start Menu"); + break; + case CSIDL_STARTUP: + strcpy (buffer,"Startup"); + break; + case CSIDL_TEMPLATES: + strcpy (buffer,"Templates"); + break; + default: + ERR (shell,"unknown CSIDL\n"); + tFolder=FT_UNKNOWN; + break; + } + + TRACE(shell,"Key=%s\n",buffer); + + type=REG_SZ; + + switch (tFolder) + { case FT_DIR: + /* Directory: get the value from the registry, if its not there + create it and the directory*/ + if (RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen)) + { GetWindowsDirectory32A(npath,MAX_PATH); + PathAddBackslash(npath); + switch (nFolder) + { case CSIDL_DESKTOPDIRECTORY: + strcat (npath,"Desktop"); + break; + case CSIDL_FONTS: + strcat (npath,"Fonts"); + break; + case CSIDL_NETHOOD: + strcat (npath,"NetHood"); + break; + case CSIDL_PERSONAL: + strcpy (npath,"C:\\Personal"); + break; + case CSIDL_FAVORITES: + strcat (npath,"Favorites"); + break; + case CSIDL_PRINTERS: + strcat (npath,"PrintHood"); + break; + case CSIDL_PROGRAMS: + strcat (npath,"Start Menu"); + CreateDirectory32A(npath,NULL); + strcat (npath,"\\Programs"); + break; + case CSIDL_RECENT: + strcat (npath,"Recent"); + break; + case CSIDL_SENDTO: + strcat (npath,"SendTo"); + break; + case CSIDL_STARTMENU: + strcat (npath,"Start Menu"); + break; + case CSIDL_STARTUP: + strcat (npath,"Start Menu"); + CreateDirectory32A(npath,NULL); + strcat (npath,"\\Startup"); + break; + case CSIDL_TEMPLATES: + strcat (npath,"Templates"); + break; + default: + RegCloseKey(key); + return E_OUTOFMEMORY; + } + if (RegSetValueEx32A(key,buffer,0,REG_SZ,npath,sizeof(npath)+1)) + { ERR(shell,"could not create value %s\n",buffer); + RegCloseKey(key); + return E_OUTOFMEMORY; + } + TRACE(shell,"value %s=%s created\n",buffer,npath); + CreateDirectory32A(npath,NULL); + } + break; + case FT_DESKTOP: + strcpy (tpath,"Desktop"); + break; + default: + RegCloseKey(key); + return E_OUTOFMEMORY; + break; + } + + RegCloseKey(key); + + TRACE(shell,"Value=%s\n",tpath); + LocalToWideChar32(lpszDisplayName, tpath, 256); + + if (SHGetDesktopFolder(&shellfolder)==S_OK) + { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL); + shellfolder->lpvtbl->fnRelease(shellfolder); + } + + TRACE(shell, "-- (new pidl %p)\n",*ppidl); + return NOERROR; +} +/************************************************************************* + * SHHelpShortcuts_RunDLL [SHELL32.224] + * + */ +DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4) +{ FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n", + dwArg1, dwArg2, dwArg3, dwArg4); + + return 0; +} + +/************************************************************************* + * SHLoadInProc [SHELL32.225] + * + */ + +DWORD WINAPI SHLoadInProc (DWORD dwArg1) +{ FIXME (shell, "(%lx) empty stub!\n", dwArg1); + return 0; +} + +/************************************************************************* + * ShellExecute32A (SHELL32.245) + */ +HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation, + LPCSTR lpFile, LPCSTR lpParameters, + LPCSTR lpDirectory, INT32 iShowCmd ) +{ TRACE(shell,"\n"); + return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters, + lpDirectory, iShowCmd ); +} + + +/************************************************************************* + * AboutDlgProc32 (not an exported API function) + */ +LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam, + LPARAM lParam ) +{ HWND32 hWndCtl; + char Template[512], AppTitle[512]; + + TRACE(shell,"\n"); + + switch(msg) + { case WM_INITDIALOG: + { ABOUT_INFO *info = (ABOUT_INFO *)lParam; + if (info) + { const char* const *pstr = SHELL_People; + SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0); + GetWindowText32A( hWnd, Template, sizeof(Template) ); + sprintf( AppTitle, Template, info->szApp ); + SetWindowText32A( hWnd, AppTitle ); + SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), + info->szOtherStuff ); + hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX); + SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 ); + SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 ); + while (*pstr) + { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr ); + pstr++; + } + SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 ); + } + } + return 1; + + case WM_PAINT: + { RECT32 rect; + PAINTSTRUCT32 ps; + HDC32 hDC = BeginPaint32( hWnd, &ps ); + + if( __get_dropline( hWnd, &rect ) ) + GRAPH_DrawLines( hDC, (LPPOINT32)&rect, 1, GetStockObject32( BLACK_PEN ) ); + EndPaint32( hWnd, &ps ); + } + break; + + case WM_LBTRACKPOINT: + hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX); + if( (INT16)GetKeyState16( VK_CONTROL ) < 0 ) + { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) ) + { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 ); + if( idx != -1 ) + { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 ); + HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 ); + char* pstr = (char*)GlobalLock16( hMemObj ); + + if( pstr ) + { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) ); + SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr ); + SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 ); + UpdateWindow32( hWndCtl ); + if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) ) + SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr ); + } + if( hMemObj ) + GlobalFree16( hMemObj ); + } + } + } + break; + + case WM_QUERYDROPOBJECT: + if( wParam == 0 ) + { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); + if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA ) + { RECT32 rect; + if( __get_dropline( hWnd, &rect ) ) + { POINT32 pt = { lpDragInfo->pt.x, lpDragInfo->pt.y }; + rect.bottom += DROP_FIELD_HEIGHT; + if( PtInRect32( &rect, pt ) ) + { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 ); + return TRUE; + } + } + } + } + break; + + case WM_DROPOBJECT: + if( wParam == hWnd ) + { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); + if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList ) + { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) ); + if( pstr ) + { static char __appendix_str[] = " with"; + + hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT ); + SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template ); + if( !lstrncmp32A( Template, "WINE", 4 ) ) + SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template ); + else + { char* pch = Template + strlen(Template) - strlen(__appendix_str); + *pch = '\0'; + SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, + (WPARAM32)-1, (LPARAM)Template ); + } + + lstrcpy32A( Template, pstr ); + lstrcat32A( Template, __appendix_str ); + SetWindowText32A( hWndCtl, Template ); + SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 ); + return TRUE; + } + } + } + break; + + case WM_COMMAND: + if (wParam == IDOK) + { EndDialog32(hWnd, TRUE); + return TRUE; + } + break; + } + return 0; +} + + +/************************************************************************* + * ShellAbout32A (SHELL32.243) + */ +BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff, + HICON32 hIcon ) +{ ABOUT_INFO info; + TRACE(shell,"\n"); + info.szApp = szApp; + info.szOtherStuff = szOtherStuff; + info.hIcon = hIcon; + if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); + return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ), + SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ), + hWnd, AboutDlgProc32, (LPARAM)&info ); +} + + +/************************************************************************* + * ShellAbout32W (SHELL32.244) + */ +BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, + HICON32 hIcon ) +{ BOOL32 ret; + ABOUT_INFO info; + + TRACE(shell,"\n"); + + info.szApp = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp ); + info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff ); + info.hIcon = hIcon; + if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); + ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ), + SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ), + hWnd, AboutDlgProc32, (LPARAM)&info ); + HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp ); + HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff ); + return ret; +} + +/************************************************************************* + * Shell_NotifyIcon [SHELL32.296] + * 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 ) +{ TRACE(shell,"\n"); + return FALSE; +} + +/************************************************************************* + * Shell_NotifyIcon [SHELL32.297] + * 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 ) +{ TRACE(shell,"\n"); + return FALSE; +} + +/************************************************************************* + * FreeIconList + */ +void WINAPI FreeIconList( DWORD dw ) +{ FIXME(shell, "(%lx): stub\n",dw); +} + +/************************************************************************* + * SHGetPathFromIDList32A [SHELL32.261][NT 4.0: SHELL32.220] + * + * PARAMETERS + * pidl, [IN] pidl + * pszPath [OUT] path + * + * RETURNS + * path from a passed PIDL. + * + * NOTES + * exported by name + * + * FIXME + * fnGetDisplayNameOf can return different types of OLEString + */ +DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath) +{ STRRET lpName; + LPSHELLFOLDER shellfolder; + CHAR buffer[MAX_PATH],tpath[MAX_PATH]; + DWORD type,tpathlen=MAX_PATH,dwdisp; + HKEY key; + + TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath); + + if (!pidl) + { strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); + + if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp)) + { return E_OUTOFMEMORY; + } + type=REG_SZ; + strcpy (buffer,"Desktop"); /*registry name*/ + if ( RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen)) + { GetWindowsDirectory32A(tpath,MAX_PATH); + PathAddBackslash(tpath); + strcat (tpath,"Desktop"); /*folder name*/ + RegSetValueEx32A(key,buffer,0,REG_SZ,tpath,tpathlen); + CreateDirectory32A(tpath,NULL); + } + RegCloseKey(key); + strcpy(pszPath,tpath); + } + else + { if (SHGetDesktopFolder(&shellfolder)==S_OK) + { shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName); + shellfolder->lpvtbl->fnRelease(shellfolder); + } + /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/ + strcpy(pszPath,lpName.u.cStr); + /* fixme free the olestring*/ + } + TRACE(shell,"-- (%s)\n",pszPath); + return NOERROR; +} +/************************************************************************* + * SHGetPathFromIDList32W [SHELL32.262] + */ +DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath) +{ FIXME (shell,"(pidl=%p %s):stub.\n", pidl, debugstr_w(pszPath)); + return 0; +} + + +void (CALLBACK* pDLLInitComctl)(); +INT32 (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon); +INT32(CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32); +HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32); +HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32); + +/************************************************************************* + * SHELL32 LibMain + * + * FIXME + * at the moment the icons are extracted from shell32.dll + * free the imagelists + */ +HINSTANCE32 shell32_hInstance; + +BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ HICON32 htmpIcon; + UINT32 iiconindex; + UINT32 index; + CHAR szShellPath[MAX_PATH]; + HINSTANCE32 hComctl32; + + + TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved); + + shell32_hInstance = hinstDLL; + + GetWindowsDirectory32A(szShellPath,MAX_PATH); + PathAddBackslash(szShellPath); + strcat(szShellPath,"system\\shell32.dll"); + + if (fdwReason==DLL_PROCESS_ATTACH) + { hComctl32 = LoadLibrary32A("COMCTL32.DLL"); + if (hComctl32) + { pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx"); + if (pDLLInitComctl) + { pDLLInitComctl(); + } + pImageList_Create=GetProcAddress32(hComctl32,"ImageList_Create"); + pImageList_AddIcon=GetProcAddress32(hComctl32,"ImageList_AddIcon"); + pImageList_ReplaceIcon=GetProcAddress32(hComctl32,"ImageList_ReplaceIcon"); + pImageList_GetIcon=GetProcAddress32(hComctl32,"ImageList_GetIcon"); + FreeLibrary32(hComctl32); + } + else + { /* panic, imediately exit wine*/ + ERR(shell,"P A N I C error getting functionpointers\n"); + exit (1); + } + if ( ! ShellSmallIconList ) + { if ( (ShellSmallIconList = pImageList_Create(sysMetrics[SM_CXSMICON],sysMetrics[SM_CYSMICON],0x101,0,0x20)) ) + { for (index=0;index < 40; index++) + { if ( ! ( htmpIcon = ExtractIcon32A(hinstDLL, szShellPath, index)) + || ( -1 == (iiconindex = pImageList_AddIcon (ShellSmallIconList, htmpIcon))) ) + { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n"); + break; + } + } + } + } + if ( ! ShellBigIconList ) + { if ( (ShellBigIconList = pImageList_Create(SYSMETRICS_CXSMICON, SYSMETRICS_CYSMICON,0x101,0,0x20)) ) + { for (index=0;index < 40; index++) + { if ( ! (htmpIcon = ExtractIcon32A( hinstDLL, szShellPath, index)) + || (-1 == (iiconindex = pImageList_AddIcon (ShellBigIconList, htmpIcon))) ) + { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n"); + break; + } + } + } + } + TRACE(shell,"hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList); + } + return TRUE; +} diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h new file mode 100644 index 00000000000..da0d8437afb --- /dev/null +++ b/dlls/shell32/shell32_main.h @@ -0,0 +1,31 @@ +/* + * internal Shell32 Library definitions + */ + +#ifndef __WINE_SHELL_MAIN_H +#define __WINE_SHELL_MAIN_H + +/******************************************* +* global SHELL32.DLL variables +*/ +extern HINSTANCE32 shell32_hInstance; +extern UINT32 shell32_DllRefCount; +extern HIMAGELIST ShellSmallIconList; +extern HIMAGELIST ShellBigIconList; + +/******************************************* +* pointer to functions dynamically loaded +*/ +extern void (CALLBACK* pDLLInitComctl)(); +extern INT32 (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon); +extern INT32(CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32); +extern HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32); +extern HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32); + +/* FIXME should be moved to a header file. IsEqualGUID +is declared but not exported in compobj.c !!!*/ +#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) +#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) +#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) + +#endif diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c new file mode 100644 index 00000000000..fbbc42ec381 --- /dev/null +++ b/dlls/shell32/shellole.c @@ -0,0 +1,346 @@ +/* + * Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL) + * + * Copyright 1997 Marcus Meissner + * Copyright 1998 Juergen Schmied + * + */ + +#include +#include +#include +#include "ole.h" +#include "ole2.h" +#include "debug.h" +#include "compobj.h" +#include "interfaces.h" +#include "shlobj.h" +#include "shell.h" +#include "winerror.h" +#include "winnls.h" +#include "winproc.h" +#include "commctrl.h" + +#include "shell32_main.h" + +/************************************************************************* + * + */ +typedef DWORD (* WINAPI GetClassPtr)(REFCLSID,REFIID,LPVOID); + +static GetClassPtr SH_find_moduleproc(LPSTR dllname,HMODULE32 *xhmod,LPSTR name) +{ HMODULE32 hmod; + FARPROC32 dllunload,nameproc; + + if (xhmod) + { *xhmod = 0; + } + if (!strcasecmp(PathFindFilename(dllname),"shell32.dll")) + { return (GetClassPtr)SHELL32_DllGetClassObject; + } + + hmod = LoadLibraryEx32A(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hmod) + { return NULL; + } + dllunload = GetProcAddress32(hmod,"DllCanUnloadNow"); + if (!dllunload) + { if (xhmod) + { *xhmod = hmod; + } + } + nameproc = GetProcAddress32(hmod,name); + if (!nameproc) + { FreeLibrary32(hmod); + return NULL; + } + /* register unloadable dll with unloadproc ... */ + return (GetClassPtr)nameproc; +} +/************************************************************************* + * + */ +static DWORD SH_get_instance(REFCLSID clsid,LPSTR dllname,LPVOID unknownouter,REFIID refiid,LPVOID inst) +{ GetClassPtr dllgetclassob; + DWORD hres; + LPCLASSFACTORY classfac; + + char xclsid[50],xrefiid[50]; + WINE_StringFromCLSID((LPCLSID)clsid,xclsid); + WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); + TRACE(shell,"\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n",xclsid, dllname,unknownouter,xrefiid,inst); + + dllgetclassob = SH_find_moduleproc(dllname,NULL,"DllGetClassObject"); + if (!dllgetclassob) + { return 0x80070000|GetLastError(); + } + +/* FIXME */ +/* + hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,inst); + if (hres<0) + return hres; + + */ + hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac); + if (hres<0 || (hres>=0x80000000)) + { return hres; + } + if (!classfac) + { FIXME(shell,"no classfactory, but hres is 0x%ld!\n",hres); + return E_FAIL; + } + classfac->lpvtbl->fnCreateInstance(classfac,unknownouter,refiid,inst); + classfac->lpvtbl->fnRelease(classfac); + return 0; +} + +/************************************************************************* + * SHCoCreateInstance [SHELL32.102] + * + * NOTES + * exported by ordinal + */ +LRESULT WINAPI SHCoCreateInstance(LPSTR aclsid,CLSID *clsid,LPUNKNOWN unknownouter,REFIID refiid,LPVOID inst) +{ char buffer[256],xclsid[48],xiid[48],path[260],tmodel[100]; + HKEY inprockey; + DWORD pathlen,type,tmodellen; + DWORD hres; + + WINE_StringFromCLSID(refiid,xiid); + + if (clsid) + { WINE_StringFromCLSID(clsid,xclsid); + } + else + { if (!aclsid) + { return 0x80040154; + } + strcpy(xclsid,aclsid); + } + TRACE(shell,"(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid,xclsid,unknownouter,xiid,inst); + + sprintf(buffer,"CLSID\\%s\\InProcServer32",xclsid); + + if (RegOpenKeyEx32A(HKEY_CLASSES_ROOT,buffer,0,0x02000000,&inprockey)) + { return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); + } + pathlen=sizeof(path); + + if (RegQueryValue32A(inprockey,NULL,path,&pathlen)) + { RegCloseKey(inprockey); + return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); + } + + TRACE(shell, "Server dll is %s\n",path); + tmodellen=sizeof(tmodel); + type=REG_SZ; + if (RegQueryValueEx32A(inprockey,"ThreadingModel",NULL,&type,tmodel,&tmodellen)) + { RegCloseKey(inprockey); + return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); + } + + TRACE(shell, "Threading model is %s\n",tmodel); + + hres=SH_get_instance(clsid,path,unknownouter,refiid,inst); + if (hres<0) + { hres=SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); + } + RegCloseKey(inprockey); + return hres; +} + + +/************************************************************************* + * SHELL32_DllGetClassObject [SHELL32.128] + * + * [Standart OLE/COM Interface Method] + * This Function retrives the pointer to a specified interface (iid) of + * a given class (rclsid). + * With this pointer it's possible to call the IClassFactory_CreateInstance + * method to get a instance of the requested Class. + * This function does NOT instantiate the Class!!! + * + * RETURNS + * HRESULT + * + */ +DWORD WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID *ppv) +{ HRESULT hres = E_OUTOFMEMORY; + LPCLASSFACTORY lpclf; + + char xclsid[50],xiid[50]; + WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); + WINE_StringFromCLSID((LPCLSID)iid,xiid); + TRACE(shell,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid); + + *ppv = NULL; + if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)|| + IsEqualCLSID(rclsid, &CLSID_ShellLink)) + { if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)) /*debug*/ + { TRACE(shell,"requested CLSID_ShellDesktop\n"); + } + if(IsEqualCLSID(rclsid, &CLSID_ShellLink)) /*debug*/ + { TRACE(shell,"requested CLSID_ShellLink\n"); + } + lpclf = IClassFactory_Constructor(); + if(lpclf) + { hres = lpclf->lpvtbl->fnQueryInterface(lpclf,iid, ppv); + lpclf->lpvtbl->fnRelease(lpclf); + } + } + else + { WARN(shell, "clsid(%s) not in buildin SHELL32\n",xclsid); + hres = CLASS_E_CLASSNOTAVAILABLE; + } + TRACE(shell,"RETURN pointer to interface: %p\n",ppv); + return hres; +} + +/************************************************************************* + * 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(LPMALLOC32 *lpmal) +{ TRACE(shell,"(%p)\n", lpmal); + return CoGetMalloc32(0,lpmal); +} + +/************************************************************************** +* IClassFactory Implementation +*/ +static HRESULT WINAPI IClassFactory_QueryInterface(LPCLASSFACTORY,REFIID,LPVOID*); +static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY); +static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY); +static HRESULT WINAPI IClassFactory_CreateInstance(); +static HRESULT WINAPI IClassFactory_LockServer(); +/************************************************************************** + * IClassFactory_VTable + */ +static IClassFactory_VTable clfvt = +{ IClassFactory_QueryInterface, + IClassFactory_AddRef, + IClassFactory_Release, + IClassFactory_CreateInstance, + IClassFactory_LockServer +}; + +/************************************************************************** + * IClassFactory_Constructor + */ + +LPCLASSFACTORY IClassFactory_Constructor() +{ LPCLASSFACTORY lpclf; + + lpclf= (LPCLASSFACTORY)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactory)); + lpclf->ref = 1; + lpclf->lpvtbl = &clfvt; + TRACE(shell,"(%p)->()\n",lpclf); + return lpclf; +} +/************************************************************************** + * IClassFactory::QueryInterface + */ +static HRESULT WINAPI IClassFactory_QueryInterface( + LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = this; + } + else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/ + { *ppvObj = (IClassFactory*)this; + } + + if(*ppvObj) + { (*(LPCLASSFACTORY*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} +/****************************************************************************** + * IClassFactory_AddRef + */ +static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); + return ++(this->ref); +} +/****************************************************************************** + * IClassFactory_Release + */ +static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); + if (!--(this->ref)) + { TRACE(shell,"-- destroying IClassFactory(%p)\n",this); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} +/****************************************************************************** + * IClassFactory_CreateInstance + */ +static HRESULT WINAPI IClassFactory_CreateInstance( + LPCLASSFACTORY this, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject) +{ IUnknown *pObj = NULL; + HRESULT hres; + char xriid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown,xriid,ppObject); + + *ppObject = NULL; + + if(pUnknown) + { return(CLASS_E_NOAGGREGATION); + } + + if (IsEqualIID(riid, &IID_IShellFolder)) + { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL); + } + else if (IsEqualIID(riid, &IID_IShellView)) + { pObj = (IUnknown *)IShellView_Constructor(); + } + else if (IsEqualIID(riid, &IID_IShellLink)) + { pObj = (IUnknown *)IShellLink_Constructor(); + } + else if (IsEqualIID(riid, &IID_IExtractIcon)) + { pObj = (IUnknown *)IExtractIcon_Constructor(NULL); + } + else if (IsEqualIID(riid, &IID_IContextMenu)) + { pObj = (IUnknown *)IContextMenu_Constructor(NULL, NULL, 0); + } + else + { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid); + return(E_NOINTERFACE); + } + + if (!pObj) + { return(E_OUTOFMEMORY); + } + + hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject); + pObj->lpvtbl->fnRelease(pObj); + TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject); + + return hres; +} +/****************************************************************************** + * IClassFactory_LockServer + */ +static HRESULT WINAPI IClassFactory_LockServer(LPCLASSFACTORY this, BOOL32 fLock) +{ TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock); + return E_NOTIMPL; +} diff --git a/misc/shellord.c b/dlls/shell32/shellord.c similarity index 71% rename from misc/shellord.c rename to dlls/shell32/shellord.c index 9076838618d..ae9990f9628 100644 --- a/misc/shellord.c +++ b/dlls/shell32/shellord.c @@ -30,19 +30,8 @@ #include "shlobj.h" #include "debug.h" #include "winreg.h" +#include "shell32_main.h" -void pdump (LPCITEMIDLIST pidl) -{ DWORD type; - CHAR * szData; - LPITEMIDLIST pidltemp = pidl; - TRACE(shell,"---------- pidl=%p \n", pidl); - do - { szData = ((LPPIDLDATA )(pidltemp->mkid.abID))->szText; - type = ((LPPIDLDATA )(pidltemp->mkid.abID))->type; - TRACE (shell,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData)); - pidltemp = (LPITEMIDLIST)(((BYTE*)pidltemp)+pidltemp->mkid.cb); - } while (pidltemp->mkid.cb); -} /************************************************************************* * SHChangeNotifyRegister [SHELL32.2] * NOTES @@ -69,116 +58,6 @@ SHChangeNotifyDeregister(LONG x1,LONG x2) { FIXME(shell,"(0x%08lx,0x%08lx):stub.\n",x1,x2); return 0; } -/************************************************************************* - * ILGetDisplayName [SHELL32.15] - * get_path_from_itemlist(itemlist,path); ? not sure... - */ -BOOL32 WINAPI ILGetDisplayName(LPCITEMIDLIST iil,LPSTR path) { - FIXME(shell,"(%p,%p),stub, return e:!\n",iil,path); - strcpy(path,"e:\\"); - return TRUE; -} -/************************************************************************* - * ILFindLastID [SHELL32.16] - */ -LPSHITEMID WINAPI ILFindLastID(LPITEMIDLIST iil) { - LPSHITEMID lastsii,sii; - - TRACE(shell,"%p\n",iil); - if (!iil) - return NULL; - sii = &(iil->mkid); - lastsii = sii; - while (sii->cb) { - lastsii = sii; - sii = (LPSHITEMID)(((char*)sii)+sii->cb); - } - return lastsii; -} -/************************************************************************* - * ILFindLastID [SHELL32.17] - * NOTES - * Creates a new list with the last item removed - */ -LPITEMIDLIST WINAPI ILRemoveLastID(LPCITEMIDLIST pidl) -{ TRACE(shell,"pidl=%p\n",pidl); - return NULL; -} - - -/************************************************************************* - * ILClone [SHELL32.18] - * - * NOTES - * dupicate an idlist - */ -LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl) -{ DWORD len; - LPITEMIDLIST newpidl; - - TRACE(shell,"%p\n",pidl); - - if (!pidl) - return NULL; - - len = ILGetSize(pidl); - newpidl = (LPITEMIDLIST)SHAlloc(len); - if (newpidl) - memcpy(newpidl,pidl,len); - return newpidl; -} - -/************************************************************************* - * ILCloneFirst [SHELL32.19] - * - * NOTES - * duplicates the first idlist of a complex pidl - */ -LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl) -{ FIXME(shell,"pidl=%p\n",pidl); - return NULL; -} - -/************************************************************************* - * ILCombine [SHELL32.25] - * - * NOTES - * Concatenates two complex idlists. - * The pidl is the first one, pidlsub the next one - * Does not destroy the passed in idlists! - */ -LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2) -{ DWORD len1,len2; - LPITEMIDLIST pidlNew; - - TRACE(shell,"pidl=%p pidl=%p\n",pidl1,pidl2); - - if(!pidl1 && !pidl2) - { return NULL; - } - - if(!pidl1) - { pidlNew = ILClone(pidl2); - return pidlNew; - } - - if(!pidl2) - { pidlNew = ILClone(pidl1); - return pidlNew; - } - - len1 = ILGetSize(pidl1)-2; - len2 = ILGetSize(pidl2); - pidlNew = SHAlloc(len1+len2); - - if (pidlNew) - { memcpy(pidlNew,pidl1,len1); - memcpy(((BYTE *)pidlNew)+len1,pidl2,len2); - } - -/* TRACE(shell,"--new pidl=%p\n",pidlNew);*/ - return pidlNew; -} /************************************************************************* * PathIsRoot [SHELL32.29] @@ -279,14 +158,14 @@ LPSTR WINAPI PathRemoveBlanks(LPSTR str) * NOTES * basename(char *fn); */ -LPSTR WINAPI PathFindFilename(LPSTR fn) { - LPSTR basefn; - TRACE(shell,"%s\n",fn); +LPSTR WINAPI PathFindFilename(LPSTR fn) +{ LPSTR basefn; + TRACE(shell,"%s\n",fn); basefn = fn; - while (fn[0]) { - if (((fn[0]=='\\') || (fn[0]==':')) && fn[1] && fn[1]!='\\') - basefn = fn+1; - fn++; + while (fn[0]) + { if (((fn[0]=='\\') || (fn[0]==':')) && fn[1] && fn[1]!='\\') + basefn = fn+1; + fn++; } return basefn; } @@ -486,17 +365,6 @@ DWORD WINAPI SHGetSettings(DWORD x,DWORD y,DWORD z) { ); return 0; } -/************************************************************************* - * Shell_GetImageList [SHELL32.71] - * - * NOTES - * returns internal shell values in the passed pointers - */ -BOOL32 WINAPI Shell_GetImageList(LPDWORD x,LPDWORD y) { - - FIXME(shell,"(%p,%p):stub.\n",x,y); - return TRUE; -} /************************************************************************* * Shell_GetCachedImageIndex [SHELL32.72] @@ -558,6 +426,8 @@ SHMapPIDLToSystemImageListIndex(DWORD x,DWORD y,DWORD z) * * NOTES * exported by ordinal + * FIXME + * wrong implemented OleStr is NOT wide string !!!! (jsch) */ BOOL32 WINAPI OleStrToStrN (LPSTR lpMulti, INT32 nMulti, LPCWSTR lpWide, INT32 nWide) { @@ -570,7 +440,9 @@ OleStrToStrN (LPSTR lpMulti, INT32 nMulti, LPCWSTR lpWide, INT32 nWide) { * * NOTES * exported by ordinal - */ + * FIXME + * wrong implemented OleStr is NOT wide string !!!! (jsch) +*/ BOOL32 WINAPI StrToOleStrN (LPWSTR lpWide, INT32 nWide, LPCSTR lpMulti, INT32 nMulti) { return MultiByteToWideChar (0, 0, lpMulti, nMulti, lpWide, nWide); @@ -631,125 +503,6 @@ void WINAPI RegisterShellHook32(HWND32 hwnd, DWORD y) { FIXME(shell,"(0x%08x,0x%08lx):stub.\n",hwnd,y); } -/************************************************************************* - * - */ -typedef DWORD (* WINAPI GetClassPtr)(REFCLSID,REFIID,LPVOID); - -static GetClassPtr SH_find_moduleproc(LPSTR dllname,HMODULE32 *xhmod, - LPSTR name) -{ HMODULE32 hmod; - FARPROC32 dllunload,nameproc; - - if (xhmod) *xhmod = 0; - if (!strcasecmp(PathFindFilename(dllname),"shell32.dll")) - return (GetClassPtr)SHELL32_DllGetClassObject; - - hmod = LoadLibraryEx32A(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH); - if (!hmod) - return NULL; - dllunload = GetProcAddress32(hmod,"DllCanUnloadNow"); - if (!dllunload) - if (xhmod) *xhmod = hmod; - nameproc = GetProcAddress32(hmod,name); - if (!nameproc) { - FreeLibrary32(hmod); - return NULL; - } - /* register unloadable dll with unloadproc ... */ - return (GetClassPtr)nameproc; -} -/************************************************************************* - * - */ -static DWORD SH_get_instance( - REFCLSID clsid, - LPSTR dllname, - LPVOID unknownouter, - REFIID refiid, - LPVOID inst) -{ GetClassPtr dllgetclassob; - DWORD hres; - LPCLASSFACTORY classfac; - - char xclsid[50],xrefiid[50]; - WINE_StringFromCLSID((LPCLSID)clsid,xclsid); - WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); - TRACE(shell,"\n\tCLSID:%s,%s,%p,\n\tIID:%s,%p\n", - xclsid, dllname,unknownouter,xrefiid,inst); - - dllgetclassob = SH_find_moduleproc(dllname,NULL,"DllGetClassObject"); - if (!dllgetclassob) - return 0x80070000|GetLastError(); - -/* FIXME */ -/* - hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,inst); - if (hres<0) - return hres; - - */ - hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac); - if (hres<0 || (hres>=0x80000000)) - return hres; - if (!classfac) { - FIXME(shell,"no classfactory, but hres is 0x%ld!\n",hres); - return E_FAIL; - } - classfac->lpvtbl->fnCreateInstance(classfac,unknownouter,refiid,inst); - classfac->lpvtbl->fnRelease(classfac); - return 0; -} - -/************************************************************************* - * SHCoCreateInstance [SHELL32.102] - * - * NOTES - * exported by ordinal - */ -LRESULT WINAPI SHCoCreateInstance( - LPSTR aclsid,CLSID *clsid,LPUNKNOWN unknownouter,REFIID refiid,LPVOID inst -) { - char buffer[256],xclsid[48],xiid[48],path[260],tmodel[100]; - HKEY inprockey; - DWORD pathlen,type,tmodellen; - DWORD hres; - - WINE_StringFromCLSID(refiid,xiid); - - if (clsid) - WINE_StringFromCLSID(clsid,xclsid); - else { - if (!aclsid) - return 0x80040154; - strcpy(xclsid,aclsid); - } - TRACE(shell,"(%p,\n\tSID:\t%s,%p,\n\tIID:\t%s,%p)\n",aclsid,xclsid,unknownouter,xiid,inst); - - sprintf(buffer,"CLSID\\%s\\InProcServer32",xclsid); - if (RegOpenKeyEx32A(HKEY_CLASSES_ROOT,buffer,0,0x02000000,&inprockey)) - return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); - pathlen=sizeof(path); - if (RegQueryValue32A(inprockey,NULL,path,&pathlen)) { - RegCloseKey(inprockey); - return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); - } - TRACE(shell, "Server dll is %s\n",path); - tmodellen=sizeof(tmodel); - type=REG_SZ; - if (RegQueryValueEx32A(inprockey,"ThreadingModel",NULL,&type,tmodel,&tmodellen)) { - RegCloseKey(inprockey); - return SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); - } - TRACE(shell, "Threading model is %s\n",tmodel); - hres=SH_get_instance(clsid,path,unknownouter,refiid,inst); - if (hres<0) - hres=SH_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst); - RegCloseKey(inprockey); - return hres; -} - - /************************************************************************* * ShellMessageBoxA [SHELL32.183] * @@ -775,7 +528,6 @@ ShellMessageBoxA(HMODULE32 hmod,HWND32 hwnd,DWORD id,DWORD x,DWORD type,LPVOID a /*MessageBox32A(hwnd,buf3,buf,id|0x10000);*/ } - /************************************************************************* * SHRestricted [SHELL32.100] * @@ -816,49 +568,6 @@ DWORD WINAPI SHRestricted (DWORD pol) { return 0; } -/************************************************************************* - * ILGetSize [SHELL32.152] - * gets the byte size of an idlist including zero terminator (pidl) - * - * PARAMETERS - * pidl ITEMIDLIST - * - * RETURNS - * size of pidl - * - * NOTES - * exported by ordinal - */ -DWORD WINAPI ILGetSize(LPITEMIDLIST pidl) -{ LPSHITEMID si = &(pidl->mkid); - DWORD len=0; - - TRACE(shell,"pidl=%p\n",pidl); - - if (pidl) - { while (si->cb) - { len += si->cb; - si = (LPSHITEMID)(((LPBYTE)si)+si->cb); - } - len += 2; - } -/* TRACE(shell,"-- size=%lu\n",len);*/ - return len; -} -/************************************************************************* - * ILAppend [SHELL32.154] - * - * NOTES - * Adds the single item to the idlist indicated by pidl. - * if bEnd is 0, adds the item to the front of the list, - * otherwise adds the item to the end. - * Destroys the passed in idlist! - */ -LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd) -{ TRACE(shell,"(pidl=%p,pidl=%p,%08u)\n",pidl,item,bEnd); - return NULL; -} - /************************************************************************* * PathGetExtension [SHELL32.158] * @@ -918,22 +627,6 @@ LPVOID WINAPI SHAlloc(DWORD len) { return ret; } - -/************************************************************************* - * ILFree [SHELL32.155] - * - * NOTES - * free_check_ptr - frees memory (if not NULL) - * allocated by SHMalloc allocator - * exported by ordinal - */ -DWORD WINAPI ILFree(LPVOID pidl) -{ TRACE (shell,"(pidl=0x%08lx)\n",(DWORD)pidl); - if (!pidl) - return 0; - return SHFree(pidl); -} - /************************************************************************* * OpenRegStream [SHELL32.85] * @@ -969,7 +662,6 @@ DWORD WINAPI SHRevokeDragDrop(DWORD x) { return 0; } - /************************************************************************* * RunFileDlg [SHELL32.61] * @@ -985,7 +677,6 @@ RunFileDlg (HWND32 hwndOwner, DWORD dwParam1, DWORD dwParam2, return 0; } - /************************************************************************* * ExitWindowsDialog [SHELL32.60] * @@ -999,7 +690,6 @@ ExitWindowsDialog (HWND32 hwndOwner) return 0; } - /************************************************************************* * ArrangeWindows [SHELL32.184] * @@ -1013,7 +703,6 @@ ArrangeWindows (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, return 0; } - /************************************************************************* * SHCLSIDFromString [SHELL32.147] * @@ -1024,7 +713,6 @@ DWORD WINAPI SHCLSIDFromString (DWORD dwParam1, DWORD dwParam2) { FIXME (shell,"(0x%lx 0x%lx):stub.\n", dwParam1, dwParam2); - FIXME (shell,"(\"%s\" \"%s\"):stub.\n", (LPSTR)dwParam1, (LPSTR)dwParam2); return 0; @@ -1123,8 +811,8 @@ HRESULT WINAPI FileMenu_Create (DWORD u, DWORD v, DWORD w, DWORD x, DWORD z) * ShellExecuteEx [SHELL32.291] * */ -HRESULT WINAPI ShellExecuteEx (DWORD u) -{ FIXME(shell,"0x%08lx stub\n",u); +BOOL32 WINAPI ShellExecuteEx32A (LPSHELLEXECUTEINFOA u) +{ FIXME(shell,"%p stub\n",u); return 0; } /************************************************************************* diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c new file mode 100644 index 00000000000..4a516cff593 --- /dev/null +++ b/dlls/shell32/shlfolder.c @@ -0,0 +1,782 @@ +/* + * Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL) + * + * Copyright 1997 Marcus Meissner + * Copyright 1998 Juergen Schmied + * + * !!! currently work in progress on all classes 980818 !!! + * + */ + +#include +#include +#include +#include "ole.h" +#include "ole2.h" +#include "debug.h" +#include "compobj.h" +#include "interfaces.h" +#include "shlobj.h" +#include "shell.h" +#include "winerror.h" +#include "winnls.h" +#include "winproc.h" +#include "commctrl.h" + +#include "shell32_main.h" + +static HRESULT WINAPI IShellFolder_QueryInterface(LPSHELLFOLDER,REFIID,LPVOID*); +static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER); +static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER); +static HRESULT WINAPI IShellFolder_Initialize(LPSHELLFOLDER,LPCITEMIDLIST); +static HRESULT WINAPI IShellFolder_ParseDisplayName(LPSHELLFOLDER,HWND32,LPBC,LPOLESTR32,DWORD*,LPITEMIDLIST*,DWORD*); +static HRESULT WINAPI IShellFolder_EnumObjects(LPSHELLFOLDER,HWND32,DWORD,LPENUMIDLIST*); +static HRESULT WINAPI IShellFolder_BindToObject(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*); +static HRESULT WINAPI IShellFolder_BindToStorage(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*); +static HRESULT WINAPI IShellFolder_CompareIDs(LPSHELLFOLDER,LPARAM,LPCITEMIDLIST,LPCITEMIDLIST); +static HRESULT WINAPI IShellFolder_CreateViewObject(LPSHELLFOLDER,HWND32,REFIID,LPVOID*); +static HRESULT WINAPI IShellFolder_GetAttributesOf(LPSHELLFOLDER,UINT32,LPCITEMIDLIST*,DWORD*); +static HRESULT WINAPI IShellFolder_GetUIObjectOf(LPSHELLFOLDER,HWND32,UINT32,LPCITEMIDLIST*,REFIID,UINT32*,LPVOID*); +static HRESULT WINAPI IShellFolder_GetDisplayNameOf(LPSHELLFOLDER,LPCITEMIDLIST,DWORD,LPSTRRET); +static HRESULT WINAPI IShellFolder_SetNameOf(LPSHELLFOLDER,HWND32,LPCITEMIDLIST,LPCOLESTR32,DWORD,LPITEMIDLIST*); +static BOOL32 WINAPI IShellFolder_GetFolderPath(LPSHELLFOLDER,LPSTR,DWORD); + +/*************************************************************************** + * GetNextElement (internal function) + * + * gets a part of a string till the first backslash + * + * PARAMETERS + * pszNext [IN] string to get the element from + * pszOut [IN] pointer to buffer whitch receives string + * dwOut [IN] length of pszOut + * + * RETURNS + * LPSTR pointer to first, not yet parsed char + */ +LPSTR GetNextElement(LPSTR pszNext,LPSTR pszOut,DWORD dwOut) +{ LPSTR pszTail = pszNext; + DWORD dwCopy; + TRACE(shell,"(%s %p 0x%08lx)\n",debugstr_a(pszNext),pszOut,dwOut); + + if(!pszNext || !*pszNext) + return NULL; + + while(*pszTail && (*pszTail != '\\')) + { pszTail++; + } + dwCopy=((LPBYTE)pszTail-(LPBYTE)pszNext)/sizeof(CHAR)+1; + lstrcpyn32A(pszOut, pszNext, (dwOutref=1; + sf->lpvtbl=&sfvt; + sf->mlpszFolder=NULL; + sf->mpSFParent=pParent; + + TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl); + + /* create own pidl-manager*/ + sf->pPidlMgr = PidlMgr_Constructor(); + if (! sf->pPidlMgr ) + { HeapFree(GetProcessHeap(),0,sf); + ERR (shell,"-- Could not initialize PidMGR\n"); + return NULL; + } + + /* keep a copy of the pidl in the instance*/ + sf->mpidl = ILClone(pidl); + sf->mpidlNSRoot = NULL; + + if(sf->mpidl) /* do we have a pidl?*/ + { dwSize = 0; + if(sf->mpSFParent->mlpszFolder) + { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1; + } + dwSize += sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr,sf->mpidl,NULL,0); + sf->mlpszFolder = SHAlloc(dwSize); + if(sf->mlpszFolder) + { *(sf->mlpszFolder)=0x00; + if(sf->mpSFParent->mlpszFolder) + { strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder); + PathAddBackslash (sf->mlpszFolder); + } + sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder)); + } + } + + TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder)); + return sf; +} +/************************************************************************** +* IShellFolder::QueryInterface +* PARAMETERS +* REFIID riid, //[in ] Requested InterfaceID +* LPVOID* ppvObject) //[out] Interface* to hold the result +*/ +static HRESULT WINAPI IShellFolder_QueryInterface( + LPSHELLFOLDER this, REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = this; + } + else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/ + { *ppvObj = (IShellFolder*)this; + } + + if(*ppvObj) + { (*(LPSHELLFOLDER*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/************************************************************************** +* IShellFolder::AddRef +*/ + +static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); + return ++(this->ref); +} + +/************************************************************************** + * IShellFolder_Release + */ +static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); + if (!--(this->ref)) + { TRACE(shell,"-- destroying IShellFolder(%p)\n",this); + + if (pdesktopfolder==this) + { pdesktopfolder=NULL; + TRACE(shell,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this); + } + if (this->pPidlMgr) + { PidlMgr_Destructor(this->pPidlMgr); + } + if(this->mpidlNSRoot) + { SHFree(this->mpidlNSRoot); + } + if(this->mpidl) + { SHFree(this->mpidl); + } + if(this->mlpszFolder) + { SHFree(this->mlpszFolder); + } + + HeapFree(GetProcessHeap(),0,this); + + return 0; + } + return this->ref; +} +/************************************************************************** +* IShellFolder_ParseDisplayName +* PARAMETERS +* HWND hwndOwner, //[in ] Parent window for any message's +* LPBC pbc, //[in ] reserved +* LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname. +* ULONG* pchEaten, //[out] (unicode) characters processed +* LPITEMIDLIST* ppidl, //[out] complex pidl to item +* ULONG* pdwAttributes //[out] items attributes +* +* FIXME: +* pdwAttributes: not used +*/ +static HRESULT WINAPI IShellFolder_ParseDisplayName( + LPSHELLFOLDER this, + HWND32 hwndOwner, + LPBC pbcReserved, + LPOLESTR32 lpszDisplayName, + DWORD *pchEaten, + LPITEMIDLIST *ppidl, + DWORD *pdwAttributes) +{ HRESULT hr=E_OUTOFMEMORY; + LPITEMIDLIST pidlFull=NULL, pidlTemp = NULL, pidlOld = NULL; + LPSTR pszNext=NULL; + CHAR szElement[MAX_PATH]; + BOOL32 bType; + + DWORD dwChars=lstrlen32W(lpszDisplayName) + 1; + LPSTR pszTemp=(LPSTR)HeapAlloc(GetProcessHeap(),0,dwChars * sizeof(CHAR)); + + TRACE(shell,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n", + this,hwndOwner,pbcReserved,lpszDisplayName,debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes); + + if(pszTemp) + { hr = E_FAIL; + WideCharToLocal32(pszTemp, lpszDisplayName, dwChars); + if(*pszTemp) + { if (strcmp(pszTemp,"Desktop")==0) + { pidlFull = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,2); + pidlFull->mkid.cb = 0; + } + else + { pidlFull = this->pPidlMgr->lpvtbl->fnCreateMyComputer(this->pPidlMgr); + + /* check if the lpszDisplayName is Folder or File*/ + bType = ! (GetFileAttributes32A(pszNext)&FILE_ATTRIBUTE_DIRECTORY); + pszNext = GetNextElement(pszTemp, szElement, MAX_PATH); + + pidlTemp = this->pPidlMgr->lpvtbl->fnCreateDrive(this->pPidlMgr,szElement); + pidlOld = pidlFull; + pidlFull = ILCombine(pidlFull,pidlTemp); + SHFree(pidlOld); + + if(pidlFull) + { while((pszNext=GetNextElement(pszNext, szElement, MAX_PATH))) + { if(!*pszNext && bType) + { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateValue(this->pPidlMgr,szElement); + } + else + { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateFolder(this->pPidlMgr,szElement); + } + pidlOld = pidlFull; + pidlFull = ILCombine(pidlFull,pidlTemp); + SHFree(pidlOld); + } + hr = S_OK; + } + } + } + } + HeapFree(GetProcessHeap(),0,pszTemp); + *ppidl = pidlFull; + return hr; +} + +/************************************************************************** +* IShellFolder_EnumObjects +* PARAMETERS +* HWND hwndOwner, //[in ] Parent Window +* DWORD grfFlags, //[in ] SHCONTF enumeration mask +* LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface +*/ +static HRESULT WINAPI IShellFolder_EnumObjects( + LPSHELLFOLDER this, + HWND32 hwndOwner, + DWORD dwFlags, + LPENUMIDLIST* ppEnumIDList) +{ HRESULT hr; + TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList); + + *ppEnumIDList = NULL; + *ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr); + TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList); + if(!*ppEnumIDList) + { return hr; + } + return S_OK; +} +/************************************************************************** + * IShellFolder_Initialize() + * IPersistFolder Method + */ +static HRESULT WINAPI IShellFolder_Initialize( + LPSHELLFOLDER this, + LPCITEMIDLIST pidl) +{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); + if(this->mpidlNSRoot) + { SHFree(this->mpidlNSRoot); + this->mpidlNSRoot = NULL; + } + this->mpidlNSRoot=ILClone(pidl); + return S_OK; +} + +/************************************************************************** +* IShellFolder_BindToObject +* PARAMETERS +* LPCITEMIDLIST pidl, //[in ] complex pidl to open +* LPBC pbc, //[in ] reserved +* REFIID riid, //[in ] Initial Interface +* LPVOID* ppvObject //[out] Interface* +*/ +static HRESULT WINAPI IShellFolder_BindToObject( + LPSHELLFOLDER this, + LPCITEMIDLIST pidl, + LPBC pbcReserved, + REFIID riid, + LPVOID * ppvOut) +{ char xriid[50]; + HRESULT hr; + LPSHELLFOLDER pShellFolder; + + WINE_StringFromCLSID(riid,xriid); + + TRACE(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl,pbcReserved,xriid,ppvOut); + + *ppvOut = NULL; + pShellFolder = IShellFolder_Constructor(this, pidl); + if(!pShellFolder) + return E_OUTOFMEMORY; + /* pShellFolder->lpvtbl->fnInitialize(pShellFolder, this->mpidlNSRoot);*/ + IShellFolder_Initialize(pShellFolder, this->mpidlNSRoot); + hr = pShellFolder->lpvtbl->fnQueryInterface(pShellFolder, riid, ppvOut); + pShellFolder->lpvtbl->fnRelease(pShellFolder); + TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut); + return hr; +} + +/************************************************************************** +* IShellFolder_BindToStorage +* PARAMETERS +* LPCITEMIDLIST pidl, //[in ] complex pidl to store +* LPBC pbc, //[in ] reserved +* REFIID riid, //[in ] Initial storage interface +* LPVOID* ppvObject //[out] Interface* returned +*/ +static HRESULT WINAPI IShellFolder_BindToStorage( + LPSHELLFOLDER this, + LPCITEMIDLIST pidl, /*simple/complex pidl*/ + LPBC pbcReserved, + REFIID riid, + LPVOID *ppvOut) +{ char xriid[50]; + WINE_StringFromCLSID(riid,xriid); + + FIXME(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl,pbcReserved,xriid,ppvOut); + + *ppvOut = NULL; + return E_NOTIMPL; +} + +/************************************************************************** +* IShellFolder_CompareIDs +* +* PARMETERS +* LPARAM lParam, //[in ] Column? +* LPCITEMIDLIST pidl1, //[in ] simple pidl +* LPCITEMIDLIST pidl2) //[in ] simple pidl +* FIXME +* we have to handle simple pidl's only +*/ +static HRESULT WINAPI IShellFolder_CompareIDs( + LPSHELLFOLDER this, + LPARAM lParam, + LPCITEMIDLIST pidl1, /*simple pidl*/ + LPCITEMIDLIST pidl2) /*simple pidl*/ +{ CHAR szString1[MAX_PATH] = ""; + CHAR szString2[MAX_PATH] = ""; + int nReturn; + LPCITEMIDLIST pidlTemp1 = pidl1, pidlTemp2 = pidl2; + + TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam,pidl1,pidl2); + + /*Special case - If one of the items is a Path and the other is a File, always + make the Path come before the File.*/ + + /* get the last item in each list */ + while((ILGetNext(pidlTemp1))->mkid.cb) + pidlTemp1 = ILGetNext(pidlTemp1); + while((ILGetNext(pidlTemp2))->mkid.cb) + pidlTemp2 = ILGetNext(pidlTemp2); + + /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */ + if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1) != this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp2)) + { if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1)) + return 1; + return -1; + } + + this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl1,szString1,sizeof(szString1)); + this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl2,szString1,sizeof(szString2)); + nReturn = strcasecmp(szString1, szString2); + if(nReturn) + return nReturn; + + this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl1,szString1,sizeof(szString1)); + this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl2,szString2,sizeof(szString2)); + nReturn = strcasecmp(szString1, szString2); + if(nReturn) + return nReturn; + + this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl1,szString1,sizeof(szString1)); + this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl2,szString2,sizeof(szString2)); + return strcasecmp(szString1, szString2); +} + +/************************************************************************** +* IShellFolder_CreateViewObject +* Creates an View Object representing the ShellFolder +* IShellView / IShellBrowser / IContextMenu +* +* PARAMETERS +* HWND hwndOwner, // Handle of owner window +* REFIID riid, // Requested initial interface +* LPVOID* ppvObject) // Resultant interface* +* +* NOTES +* the same as SHCreateShellFolderViewEx ??? +*/ +static HRESULT WINAPI IShellFolder_CreateViewObject( + LPSHELLFOLDER this, + HWND32 hwndOwner, + REFIID riid, + LPVOID *ppvOut) +{ LPSHELLVIEW pShellView; + char xriid[50]; + HRESULT hr; + + WINE_StringFromCLSID(riid,xriid); + TRACE(shell,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner,xriid,ppvOut); + + *ppvOut = NULL; + + pShellView = IShellView_Constructor(this, this->mpidl); + if(!pShellView) + return E_OUTOFMEMORY; + hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut); + pShellView->lpvtbl->fnRelease(pShellView); + TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut); + return hr; +} + +/************************************************************************** +* IShellFolder_GetAttributesOf +* +* PARAMETERS +* UINT cidl, //[in ] num elements in pidl array ++ LPCITEMIDLIST* apidl, //[in ] simple pidl array +* ULONG* rgfInOut) //[out] result array +* +* FIXME: quick hack +* Note: rgfInOut is documented as being an array of ULONGS. +* This does not seem to be the case. Testing this function using the shell to +* call it with cidl > 1 (by deleting multiple items) reveals that the shell +* passes ONE element in the array and writing to further elements will +* cause the shell to fail later. +*/ +static HRESULT WINAPI IShellFolder_GetAttributesOf( + LPSHELLFOLDER this, + UINT32 cidl, + LPCITEMIDLIST *apidl, /*simple pidl's*/ + DWORD *rgfInOut) +{ LPCITEMIDLIST * pidltemp; + DWORD i; + + TRACE(shell,"(%p)->(%d,%p,%p)\n",this,cidl,apidl,rgfInOut); + + if ((! cidl )| (!apidl) | (!rgfInOut)) + return E_INVALIDARG; + + pidltemp=apidl; + *rgfInOut = 0x00; + i=cidl; + + TRACE(shell,"-- mask=0x%08lx\n",*rgfInOut); + + do + { if (*pidltemp) + { if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, *pidltemp)) + { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); + } + else if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, *pidltemp)) + { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER); + } + else if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, *pidltemp)) + { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM); + } + else if (this->pPidlMgr->lpvtbl->fnIsFolder(this->pPidlMgr, *pidltemp)) + { *rgfInOut |= (SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER); + } + else if (this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, *pidltemp)) + { *rgfInOut |= (SFGAO_FILESYSTEM); + } + } + pidltemp++; + cidl--; + } while (cidl > 0 && *pidltemp); + + return S_OK; +} +/************************************************************************** +* IShellFolder_GetUIObjectOf +* +* PARAMETERS +* HWND hwndOwner, //[in ] Parent window for any output +* UINT cidl, //[in ] array size +* LPCITEMIDLIST* apidl, //[in ] simple pidl array +* REFIID riid, //[in ] Requested Interface +* UINT* prgfInOut, //[ ] reserved +* LPVOID* ppvObject) //[out] Resulting Interface +* +* NOTES +* This function gets asked to return "view objects" for one or more (multiple select) +* items: +* The viewobject typically is an COM object with one of the following interfaces: +* IExtractIcon,IDataObject,IContextMenu +* In order to support icon positions in the default Listview your DataObject +* must implement the SetData method (in addition to GetData :) - the shell passes +* a barely documented "Icon positions" structure to SetData when the drag starts, +* and GetData's it if the drop is in another explorer window that needs the positions. +*/ +static HRESULT WINAPI IShellFolder_GetUIObjectOf( LPSHELLFOLDER this,HWND32 hwndOwner,UINT32 cidl, + LPCITEMIDLIST * apidl, REFIID riid, UINT32 * prgfInOut,LPVOID * ppvOut) +{ char xclsid[50]; + LPEXTRACTICON pei; + LPCONTEXTMENU pcm; + LPITEMIDLIST pidl; + + WINE_StringFromCLSID(riid,xclsid); + + TRACE(shell,"(%p)->(%u,%u,pidl=%p,\n\tIID:%s,%p,%p)\n", + this,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut); + + *ppvOut = NULL; + + if(IsEqualIID(riid, &IID_IContextMenu)) + { pcm = IContextMenu_Constructor(this, apidl, cidl); + if(pcm) + { *ppvOut = pcm; + return S_OK; + } + } + + if(cidl != 1) + return E_FAIL; + + if(IsEqualIID(riid, &IID_IExtractIcon)) + { pidl = ILCombine(this->mpidl, apidl[0]); + pei = IExtractIcon_Constructor(pidl); + + /* The temp PIDL can be deleted because the new CExtractIcon either failed or + made its own copy of it. */ + SHFree(pidl); + + if(pei) + { *ppvOut = pei; + return S_OK; + } + return E_OUTOFMEMORY; + } + +/* if(IsEqualIID(riid, IID_IQueryInfo)) + { CQueryInfo *pqit; + LPITEMIDLIST pidl; + pidl = m_pPidlMgr->Concatenate(m_pidl, pPidl[0]); + pqit = new CQueryInfo(pidl); + */ + /* The temp PIDL can be deleted because the new CQueryInfo either failed or + made its own copy of it. */ + /* m_pPidlMgr->Delete(pidl); + + if(pqit) + { *ppvReturn = pqit; + return S_OK; + } + return E_OUTOFMEMORY; + } +*/ + ERR(shell,"(%p)->E_NOINTERFACE\n",this); + return E_NOINTERFACE; +} +/************************************************************************** +* IShellFolder_GetDisplayNameOf +* Retrieves the display name for the specified file object or subfolder +* +* PARAMETERS +* LPCITEMIDLIST pidl, //[in ] complex pidl to item +* DWORD dwFlags, //[in ] SHGNO formatting flags +* LPSTRRET lpName) //[out] Returned display name +* +* FIXME +* if the name is in the pidl the ret value should be a STRRET_OFFSET +*/ +#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00) +#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF) + +static HRESULT WINAPI IShellFolder_GetDisplayNameOf( + LPSHELLFOLDER this, + LPCITEMIDLIST pidl, /* simple/complex pidl*/ + DWORD dwFlags, + LPSTRRET lpName) +{ CHAR szText[MAX_PATH]; + CHAR szTemp[MAX_PATH]; + CHAR szSpecial[MAX_PATH]; + CHAR szDrive[MAX_PATH]; + DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags; + LPITEMIDLIST pidlTemp=NULL; + BOOL32 bSimplePidl=FALSE; + + TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName); + + if (!pidl) + { return E_OUTOFMEMORY; + } + + szSpecial[0]=0x00; + szDrive[0]=0x00; + + /* test if simple(relative) or complex(absolute) pidl */ + pidlTemp = ILGetNext(pidl); + if (pidlTemp->mkid.cb==0x00) + { bSimplePidl = TRUE; + } + if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, pidl)) + { strcpy (szText,"Desktop"); + } + else + { if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl)) + { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH); + } + if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, pidl)) + { pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); + if (pidlTemp) + { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH); + } + if ( dwFlags==SHGDN_NORMAL || dwFlags==SHGDN_INFOLDER) + { GetVolumeInformation32A(szTemp,szDrive,MAX_PATH,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0); + if (szTemp[2]=='\\') + { szTemp[2]=0x00; + } + strcat (szDrive," ("); + strcat (szDrive,szTemp); + strcat (szDrive,")"); + } + else + { PathAddBackslash (szTemp); + strcpy(szDrive,szTemp); + } + } + + switch(dwFlags) + { case SHGDN_NORMAL: + this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH); + break; + case SHGDN_INFOLDER: + pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); + if (pidlTemp) + { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szText, MAX_PATH); + } + break; + case SHGDN_FORPARSING: + if (bSimplePidl) + { /* if the IShellFolder has parents, get the path from the + parent and add the ItemName*/ + szText[0]=0x00; + if (this->mlpszFolder && strlen (this->mlpszFolder)) + { if (strcmp(this->mlpszFolder,"My Computer")) + { strcpy (szText,this->mlpszFolder); + PathAddBackslash (szText); + } + } + pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); + if (pidlTemp) + { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH ); + } + strcat(szText,szTemp); + } + else + { /* if the pidl is absolute, get everything from the pidl*/ + this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH); + } + break; + default: return E_INVALIDARG; + } + if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00)) + { strcpy(szText,szDrive); + } + if (szText[0]==0x00 && szSpecial[0]!=0x00) + { strcpy(szText,szSpecial); + } + } + + TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText); + + if(!(lpName)) + { return E_OUTOFMEMORY; + } + lpName->uType = STRRET_CSTR; + strcpy(lpName->u.cStr,szText); + return S_OK; +} + +/************************************************************************** +* IShellFolder_SetNameOf +* Changes the name of a file object or subfolder, possibly changing its item +* identifier in the process. +* +* PARAMETERS +* HWND hwndOwner, //[in ] Owner window for output +* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change +* LPCOLESTR lpszName, //[in ] the items new display name +* DWORD dwFlags, //[in ] SHGNO formatting flags +* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned +*/ +static HRESULT WINAPI IShellFolder_SetNameOf( + LPSHELLFOLDER this, + HWND32 hwndOwner, + LPCITEMIDLIST pidl, /*simple pidl*/ + LPCOLESTR32 lpName, + DWORD dw, + LPITEMIDLIST *pPidlOut) +{ FIXME(shell,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n", + this,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut); + return E_NOTIMPL; +} +/************************************************************************** +* IShellFolder_GetFolderPath +* FIXME: drive not included +*/ +static BOOL32 WINAPI IShellFolder_GetFolderPath(LPSHELLFOLDER this, LPSTR lpszOut, DWORD dwOutSize) +{ CHAR szTemp[MAX_PATH]; + DWORD dwSize; + + TRACE(shell,"(%p)->(%p %lu)\n",this, lpszOut, dwOutSize); + if (!lpszOut) + { return FALSE; + } + + *lpszOut=0; + + dwSize = strlen (this->mlpszFolder) +1; + if ( dwSize > dwOutSize) + return FALSE; + strcpy(lpszOut, this->mlpszFolder); + + TRACE(shell,"-- (%p)->(return=%s)\n",this, lpszOut); + return TRUE; +} diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c new file mode 100644 index 00000000000..90796db4bb1 --- /dev/null +++ b/dlls/shell32/shlview.c @@ -0,0 +1,1185 @@ +/* + * ShellView + * + * Copyright 1998 Juergen Schmied + * + * !!! currently work in progress on all classes 980801 !!! + * + */ + +#include +#include +#include +#include "ole.h" +#include "ole2.h" +#include "debug.h" +#include "compobj.h" +#include "interfaces.h" +#include "shlobj.h" +#include "shell.h" +#include "winerror.h" +#include "winnls.h" +#include "winproc.h" +#include "commctrl.h" + +#include "shell32_main.h" +#include "pidl.h" +#include "shresdef.h" + +/*********************************************************************** +* IShellView implementation +*/ +static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID, LPVOID *); +static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ; +static ULONG WINAPI IShellView_Release(LPSHELLVIEW); + /* IOleWindow methods */ +static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd); +static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode); + /* IShellView methods */ +static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg); +static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable); +static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState); +static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW); +static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd); +static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW); +static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs); +static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam); +static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW); +static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags); +static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv); + +static struct IShellView_VTable svvt = +{ IShellView_QueryInterface, + IShellView_AddRef, + IShellView_Release, + IShellView_GetWindow, + IShellView_ContextSensitiveHelp, + IShellView_TranslateAccelerator, + IShellView_EnableModeless, + IShellView_UIActivate, + IShellView_Refresh, + IShellView_CreateViewWindow, + IShellView_DestroyViewWindow, + IShellView_GetCurrentInfo, + IShellView_AddPropertySheetPages, + IShellView_SaveViewState, + IShellView_SelectItem, + IShellView_GetItemObject +}; + +//menu items +#define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500) +#define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501) +#define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502) + +#define TOOLBAR_ID (L"ShellView") +typedef struct +{ int idCommand; + int iImage; + int idButtonString; + int idMenuString; + int nStringOffset; + BYTE bState; + BYTE bStyle; +} MYTOOLINFO, *LPMYTOOLINFO; + +MYTOOLINFO g_Tools[] = +{ {IDM_VIEW_FILES, 0, IDS_TB_VIEW_FILES, IDS_MI_VIEW_FILES, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON}, + {-1, 0, 0, 0, 0, 0, 0} +}; +/************************************************************************** +* IShellView_Constructor +*/ +LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl) +{ LPSHELLVIEW sv; + sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView)); + sv->ref=1; + sv->lpvtbl=&svvt; + + sv->mpidl = ILClone(pidl); + + sv->pSFParent = pFolder; + if(sv->pSFParent) + sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent); + + TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl); + return sv; +} +/************************************************************************** +* ShellView_CreateList() +* +* NOTES +* internal +*/ +#define ID_LISTVIEW 2000 + +BOOL32 ShellView_CreateList (LPSHELLVIEW this) +{ DWORD dwStyle; + + TRACE(shell,"%p\n",this); + + dwStyle = WS_TABSTOP | WS_VISIBLE |WS_CHILD | WS_BORDER | LVS_REPORT | + LVS_SHAREIMAGELISTS | LVS_EDITLABELS ; + + this->hWndList=CreateWindowEx32A( WS_EX_CLIENTEDGE,WC_LISTVIEW32A,NULL,dwStyle, + 0,0,0,0, + this->hWnd,(HMENU32)ID_LISTVIEW,shell32_hInstance,NULL); + + if(!this->hWndList) + return FALSE; + +// UpdateShellSettings(); + return TRUE; +} +/************************************************************************** +* ShellView_InitList() +* +* NOTES +* internal +*/ +int nColumn1=100; /* width of column */ +int nColumn2=100; +int nColumn3=100; +int nColumn4=100; + +BOOL32 ShellView_InitList(LPSHELLVIEW this) +{ LV_COLUMN lvColumn; + CHAR szString[50]; + + TRACE(shell,"%p\n",this); + + + ListView_DeleteAllItems(this->hWndList); /*empty the list*/ + + //initialize the columns + lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvColumn.fmt = LVCFMT_LEFT; + lvColumn.pszText = szString; + + lvColumn.cx = nColumn1; + strcpy(szString,"File"); + /*LoadString32A(shell32_hInstance, IDS_COLUMN1, szString, sizeof(szString));*/ + ListView_InsertColumn(this->hWndList, 0, &lvColumn); + + lvColumn.cx = nColumn2; + strcpy(szString,"IDS_COLUMN2"); + ListView_InsertColumn(this->hWndList, 1, &lvColumn); + + lvColumn.cx = nColumn3; + strcpy(szString,"IDS_COLUMN3"); + ListView_InsertColumn(this->hWndList, 2, &lvColumn); + + lvColumn.cx = nColumn4; + strcpy(szString,"IDS_COLUMN4"); + ListView_InsertColumn(this->hWndList, 3, &lvColumn); + + ListView_SetImageList(this->hWndList, ShellBigIconList, LVSIL_SMALL); + + return TRUE; +} +/************************************************************************** +* ShellView_CompareItems() +* +* NOTES +* internal +*/ +int CALLBACK ShellView_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ LPSHELLFOLDER pFolder = (LPSHELLFOLDER)lpData; + + TRACE(shell,"\n"); + if(!pFolder) + return 0; + + return (int)pFolder->lpvtbl->fnCompareIDs(pFolder, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2); +} + +/************************************************************************** +* ShellView_FillList() +* +* NOTES +* internal +*/ + +void ShellView_FillList(LPSHELLVIEW this) +{ LPENUMIDLIST pEnumIDList; + LPITEMIDLIST pidl; + DWORD dwFetched; + LV_ITEM lvItem; + + TRACE(shell,"%p\n",this); + + if(S_OK == this->pSFParent->lpvtbl->fnEnumObjects(this->pSFParent,this->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList)) + { SendMessage32A(this->hWndList, WM_SETREDRAW, FALSE, 0); /*turn the listview's redrawing off*/ + + while((S_OK == pEnumIDList->lpvtbl->fnNext(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched) + { ZeroMemory(&lvItem, sizeof(lvItem)); + + lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/ + lvItem.iItem = ListView_GetItemCount(this->hWndList); /*add the item to the end of the list*/ + lvItem.lParam = (LPARAM)ILClone(pidl); /*set the item's data*/ + lvItem.pszText = LPSTR_TEXTCALLBACK32A; /*get text on a callback basis*/ + lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/ + ListView_InsertItem(this->hWndList, &lvItem); /*add the item*/ + } + + /*sort the items*/ + ListView_SortItems(this->hWndList, ShellView_CompareItems, (LPARAM)this->pSFParent); + + /*turn the listview's redrawing back on and force it to draw*/ + SendMessage32A(this->hWndList, WM_SETREDRAW, TRUE, 0); + InvalidateRect32(this->hWndList, NULL, TRUE); + UpdateWindow32(this->hWndList); + + pEnumIDList->lpvtbl->fnRelease(pEnumIDList); + } +} + +/************************************************************************** +* ShellView_OnCreate() +* +* NOTES +* internal +*/ +LRESULT ShellView_OnCreate(LPSHELLVIEW this) +{ TRACE(shell,"%p\n",this); + if(ShellView_CreateList(this)) + { if(ShellView_InitList(this)) + { ShellView_FillList(this); + } + } + return S_OK; +} +/************************************************************************** +* ShellView_OnSize() +*/ +LRESULT ShellView_OnSize(LPSHELLVIEW this, WORD wWidth, WORD wHeight) +{ TRACE(shell,"%p width=%u height=%u\n",this, wWidth,wHeight); + //resize the ListView to fit our window + if(this->hWndList) + { MoveWindow32(this->hWndList, 0, 0, wWidth, wHeight, TRUE); + } + return S_OK; +} +/************************************************************************** +* ShellView_BuildFileMenu() +*/ +HMENU32 ShellView_BuildFileMenu(LPSHELLVIEW this) +{ CHAR szText[MAX_PATH]; + MENUITEMINFO32A mii; + int nTools,i; + HMENU32 hSubMenu = CreatePopupMenu32(); + + TRACE(shell,"(%p) stub\n",this); + if(hSubMenu) + { /*get the number of items in our global array*/ + for(nTools = 0; g_Tools[nTools].idCommand != -1; nTools++){} + + //add the menu items + for(i = 0; i < nTools; i++) + { strcpy(szText, "dummy 44"); + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + + if(TBSTYLE_SEP != g_Tools[i].bStyle) + { mii.fType = MFT_STRING; + mii.fState = MFS_ENABLED; + mii.dwTypeData = szText; + mii.wID = g_Tools[i].idCommand; + } + else + { mii.fType = MFT_SEPARATOR; + } + /* tack this item onto the end of the menu */ + InsertMenuItem32A(hSubMenu, (UINT32)-1, TRUE, &mii); + } + } + return hSubMenu; +} +/************************************************************************** +* ShellView_MergeFileMenu() +*/ +void ShellView_MergeFileMenu(LPSHELLVIEW this, HMENU32 hSubMenu) +{ MENUITEMINFO32A mii; + CHAR szText[MAX_PATH]; + + TRACE(shell,"(%p)->(submenu=0x%08x) stub\n",this,hSubMenu); + if(hSubMenu) + { ZeroMemory(&mii, sizeof(mii)); + + /* add a separator */ + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + mii.fType = MFT_SEPARATOR; + mii.fState = MFS_ENABLED; + + /*insert this item at the beginning of the menu */ + InsertMenuItem32A(hSubMenu, 0, TRUE, &mii); + + /*add the file menu items */ + strcpy(szText,"dummy 45"); + + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + mii.fType = MFT_STRING; + mii.fState = MFS_ENABLED; + mii.dwTypeData = szText; + mii.wID = IDM_MYFILEITEM; + + /*insert this item at the beginning of the menu */ + InsertMenuItem32A(hSubMenu, 0, TRUE, &mii); + } +} + +/************************************************************************** +* ShellView_MergeViewMenu() +*/ +void ShellView_MergeViewMenu(LPSHELLVIEW this, HMENU32 hSubMenu) +{ MENUITEMINFO32A mii; + CHAR szText[MAX_PATH]; + + TRACE(shell,"(%p)->(submenu=0x%08x) stub\n",this,hSubMenu); + if(hSubMenu) + { ZeroMemory(&mii, sizeof(mii)); + + /*add a separator at the correct position in the menu*/ + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + mii.fType = MFT_SEPARATOR; + mii.fState = MFS_ENABLED; + InsertMenuItem32A(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii); + + /*add the view menu items at the correct position in the menu*/ + strcpy(szText,"Dummy 46"); + + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + mii.fType = MFT_STRING; + mii.fState = MFS_ENABLED; + mii.dwTypeData = szText; + mii.wID = IDM_VIEW_FILES; + InsertMenuItem32A(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii); + } +} +/************************************************************************** +* ShellView_OnDeactivate() +* +* NOTES +* internal +*/ +void ShellView_OnDeactivate(LPSHELLVIEW this) +{ TRACE(shell,"%p\n",this); + if(this->uState != SVUIA_DEACTIVATE) + { if(this->hMenu) + { this->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser,0, 0, 0); + this->pShellBrowser->lpvtbl->fnRemoveMenusSB(this->pShellBrowser,this->hMenu); + DestroyMenu32(this->hMenu); + this->hMenu = 0; + } + + this->uState = SVUIA_DEACTIVATE; + } +} + +/************************************************************************** +* CShellView_OnActivate() +*/ +LRESULT ShellView_OnActivate(LPSHELLVIEW this, UINT32 uState) +{ OLEMENUGROUPWIDTHS32 omw = { {0, 0, 0, 0, 0, 0} }; + MENUITEMINFO32A mii; + CHAR szText[MAX_PATH]; + + TRACE(shell,"%p uState=%x\n",this,uState); + + //don't do anything if the state isn't really changing + if(this->uState == uState) + { return S_OK; + } + + ShellView_OnDeactivate(this); + + //only do this if we are active + if(uState != SVUIA_DEACTIVATE) + { //merge the menus + this->hMenu = CreateMenu32(); + + if(this->hMenu) + { this->pShellBrowser->lpvtbl->fnInsertMenusSB(this->pShellBrowser, this->hMenu, &omw); + + //build the top level menu + //get the menu item's text + strcpy(szText,"dummy 31"); + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE; + mii.fType = MFT_STRING; + mii.fState = MFS_ENABLED; + mii.dwTypeData = szText; + mii.hSubMenu = ShellView_BuildFileMenu(this); + + //insert our menu into the menu bar + if(mii.hSubMenu) + { InsertMenuItem32A(this->hMenu, FCIDM_MENU_HELP, FALSE, &mii); + } + + //get the view menu so we can merge with it + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_SUBMENU; + + if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_VIEW, FALSE, &mii)) + { ShellView_MergeViewMenu(this, mii.hSubMenu); + } + + //add the items that should only be added if we have the focus + if(SVUIA_ACTIVATE_FOCUS == uState) + { //get the file menu so we can merge with it + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_SUBMENU; + + if(GetMenuItemInfo32A(this->hMenu, FCIDM_MENU_FILE, FALSE, &mii)) + { ShellView_MergeFileMenu(this, mii.hSubMenu); + } + } + this->pShellBrowser->lpvtbl->fnSetMenuSB(this->pShellBrowser, this->hMenu, 0, this->hWnd); + } + } + this->uState = uState; + return 0; +} + +/************************************************************************** +* ShellView_OnSetFocus() +* +* NOTES +* internal +*/ +LRESULT ShellView_OnSetFocus(LPSHELLVIEW this) +{ TRACE(shell,"%p\n",this); + /* Tell the browser one of our windows has received the focus. This should always + be done before merging menus (OnActivate merges the menus) if one of our + windows has the focus.*/ + this->pShellBrowser->lpvtbl->fnOnViewWindowActive(this->pShellBrowser,this); + ShellView_OnActivate(this, SVUIA_ACTIVATE_FOCUS); + + return 0; +} + +BOOL32 g_bViewKeys; +BOOL32 g_bShowIDW; +/************************************************************************** +* ShellView_OnKillFocus() +*/ +LRESULT ShellView_OnKillFocus(LPSHELLVIEW this) +{ TRACE(shell,"(%p) stub\n",this); + ShellView_OnActivate(this, SVUIA_ACTIVATE_NOFOCUS); + return 0; +} + +/************************************************************************** +* CShellView::AddRemoveDockingWindow() +*/ +BOOL32 ShellView_AddRemoveDockingWindow(LPSHELLVIEW this, BOOL32 bAdd) +{ TRACE(shell,"(%p)->(badd=0x%08x) stub\n",this,bAdd); + return FALSE; +/* + BOOL32 bReturn = FALSE; + HRESULT32 hr; + IServiceProvider *pSP; +*/ + /* get the browser's IServiceProvider */ +/* hr = this->pShellBrowser->QueryInterface((REFIID)IID_IServiceProvider, (LPVOID*)&pSP); + if(SUCCEEDED(hr)) + { + IDockingWindowFrame *pFrame; +*/ + /*get the IDockingWindowFrame pointer*/ +/* + hr = pSP->QueryService(SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame); + if(SUCCEEDED(hr)) + { if(bAdd) + { hr = S_OK; + if(!this->pDockingWindow) + { //create the toolbar object + this->pDockingWindow = new CDockingWindow(this, this->hWnd); + } + + if(this->pDockingWindow) + { //add the toolbar object + hr = pFrame->AddToolbar((IDockingWindow*)this->pDockingWindow, TOOLBAR_ID, 0); + + if(SUCCEEDED(hr)) + { bReturn = TRUE; + } + } + } + else + { if(this->pDockingWindow) + { hr = pFrame->RemoveToolbar((IDockingWindow*)this->pDockingWindow, DWFRF_NORMAL); + + if(SUCCEEDED(hr)) + {*/ + /* RemoveToolbar should release the toolbar object which will cause + it to destroy itself. Our toolbar object is no longer valid at + this point.*/ + +/* this->pDockingWindow = NULL; + bReturn = TRUE; + } + } + } + pFrame->Release(); + } + pSP->Release(); + } + return bReturn;*/ +} + +/************************************************************************** +* ShellView_OnCommand() +*/ +LRESULT ShellView_OnCommand(LPSHELLVIEW this,DWORD dwCmdID, DWORD dwCmd, HWND32 hwndCmd) +{ TRACE(shell,"(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",this, dwCmdID, dwCmd, hwndCmd); + switch(dwCmdID) + { case IDM_VIEW_FILES: + g_bViewKeys = ! g_bViewKeys; + IShellView_Refresh(this); + break; + + case IDM_VIEW_IDW: + g_bShowIDW = ! g_bShowIDW; + ShellView_AddRemoveDockingWindow(this, g_bShowIDW); + break; + + case IDM_MYFILEITEM: + MessageBeep32(MB_OK); + break; + } + return 0; +} +/************************************************************************** +* ShellView_CanDoIDockingWindow() +*/ +BOOL32 ShellView_CanDoIDockingWindow(LPSHELLVIEW this) +{ TRACE(shell,"(%p) stub\n",this); + return FALSE; +/* + BOOL32 bReturn = FALSE; + HRESULT32 hr; + IServiceProvider *pSP; + IDockingWindowFrame *pFrame; + + //get the browser's IServiceProvider + hr = this->pShellBrowser->lpvtbl->fnQueryInterface(this->pShellBrowser, (REFIID)IID_IServiceProvider, (LPVOID*)&pSP); + if(hr==S_OK) + { hr = pSP->lpvtbl->fnQueryService(pSP, SID_SShellBrowser, IID_IDockingWindowFrame, (LPVOID*)&pFrame); + if(SUCCEEDED(hr)) + { bReturn = TRUE; + pFrame->lpvtbl->fnRelease(pFrame); + } + pSP->lpvtbl->fnRelease(pSP); + } + return bReturn;*/ +} +/************************************************************************** +* ShellView_UpdateMenu() +*/ +LRESULT ShellView_UpdateMenu(LPSHELLVIEW this, HMENU32 hMenu) +{ TRACE(shell,"(%p)->(menu=0x%08x\n",this,hMenu); + CheckMenuItem32(hMenu, IDM_VIEW_FILES, MF_BYCOMMAND | (g_bViewKeys ? MF_CHECKED: MF_UNCHECKED)); + + if(ShellView_CanDoIDockingWindow(this)) + { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_ENABLED); + CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | (g_bShowIDW ? MF_CHECKED: MF_UNCHECKED)); + } + else + { EnableMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + CheckMenuItem32(hMenu, IDM_VIEW_IDW, MF_BYCOMMAND | MF_UNCHECKED); + } + return 0; +} + +/************************************************************************** +* ShellView_UpdateShellSettings() + +**************************************************************************/ +typedef void (WINAPI *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask); + + +void ShellView_UpdateShellSettings(LPSHELLVIEW this) +{ TRACE(shell,"(%p) stub\n",this); + return ; +/* + SHELLFLAGSTATE sfs; + HINSTANCE hinstShell32; +*/ + /* Since SHGetSettings is not implemented in all versions of the shell, get the + function address manually at run time. This allows the code to run on all + platforms.*/ +/* + ZeroMemory(&sfs, sizeof(sfs)); +*/ + /* The default, in case any of the following steps fails, is classic Windows 95 + style.*/ +/* + sfs.fWin95Classic = TRUE; + + hinstShell32 = LoadLibrary(TEXT("shell32.dll")); + if(hinstShell32) + { PFNSHGETSETTINGSPROC pfnSHGetSettings; + + pfnSHGetSettings = (PFNSHGETSETTINGSPROC)GetProcAddress(hinstShell32, "SHGetSettings"); + if(pfnSHGetSettings) + { (*pfnSHGetSettings)(&sfs, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC); + } + FreeLibrary(hinstShell32); + } + + DWORD dwExStyles = 0; + + if(!sfs.fWin95Classic && !sfs.fDoubleClickInWebView) + dwExStyles |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT; + + ListView_SetExtendedListViewStyle(this->hWndList, dwExStyles); +*/ +} + +/************************************************************************** +* ShellView_OnSettingChange() +*/ +LRESULT ShellView_OnSettingChange(LPSHELLVIEW this, LPCSTR lpszSection) +{ TRACE(shell,"(%p) stub\n",this); + //if(0 == lstrcmpi(lpszSection, TEXT("ShellState"))) + { ShellView_UpdateShellSettings(this); + return 0; + } + return 0; +} + +#define MENU_OFFSET 1 +#define MENU_MAX 100 + +/************************************************************************** +* ShellView_DoContextMenu() +*/ +void ShellView_DoContextMenu(LPSHELLVIEW this, WORD x, WORD y, BOOL32 fDefault) +{ UINT32 uSelected = ListView_GetSelectedCount(this->hWndList); + LPITEMIDLIST *aSelectedItems; + UINT32 i; + LPCONTEXTMENU pContextMenu = NULL; + LVITEM lvItem; + UINT32 uCommand; + MENUITEMINFO32A mii; + int nMenuIndex; + CMINVOKECOMMANDINFO cmi; + + TRACE(shell,"(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x, y, fDefault); + aSelectedItems = (LPITEMIDLIST*)SHAlloc(uSelected * sizeof(LPITEMIDLIST)); + + if(aSelectedItems) + { ZeroMemory(&lvItem, sizeof(lvItem)); + lvItem.mask = LVIF_STATE | LVIF_PARAM; + lvItem.stateMask = LVIS_SELECTED; + lvItem.iItem = 0; + + i = 0; + + while(ListView_GetItem(this->hWndList, &lvItem) && (i < uSelected)) + { if(lvItem.state & LVIS_SELECTED) + { aSelectedItems[i] = (LPITEMIDLIST)lvItem.lParam; + i++; + } + lvItem.iItem++; + } + + this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent, this->hWndParent, uSelected, + (LPCITEMIDLIST*)aSelectedItems, &IID_IContextMenu, NULL,(LPVOID*)&pContextMenu); + + if(pContextMenu) + { HMENU32 hMenu = CreatePopupMenu32(); + + /* See if we are in Explore or Open mode. If the browser's tree is present, + then we are in Explore mode.*/ + + BOOL32 fExplore = FALSE; + HWND32 hwndTree = 0; + if(S_OK==(this->pShellBrowser->lpvtbl->fnGetControlWindow(this->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree) + { fExplore = TRUE; + } + + if(hMenu && S_OK==(pContextMenu->lpvtbl->fnQueryContextMenu(pContextMenu, + hMenu,0,MENU_OFFSET,MENU_MAX,CMF_NORMAL | + (uSelected != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0)))) + { if(fDefault) + { uCommand = 0; + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STATE | MIIM_ID; + + nMenuIndex = 0; + + //find the default item in the menu + while(GetMenuItemInfo32A(hMenu, nMenuIndex, TRUE, &mii)) + { if(mii.fState & MFS_DEFAULT) + { uCommand = mii.wID; + break; + } + nMenuIndex++; + } + } + else + { uCommand = TrackPopupMenu32( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,this->hWnd,NULL); + } + + if(uCommand > 0) + { ZeroMemory(&cmi, sizeof(cmi)); + cmi.cbSize = sizeof(cmi); + cmi.hwnd = this->hWndParent; + cmi.lpVerb = (LPCSTR)MAKEINTRESOURCE32A(uCommand - MENU_OFFSET); + pContextMenu->lpvtbl->fnInvokeCommand(pContextMenu, &cmi); + } + DestroyMenu32(hMenu); + } + pContextMenu->lpvtbl->fnRelease(pContextMenu); + } + SHFree(aSelectedItems); + } +} + +/************************************************************************** +* ShellView_OnNotify() +*/ + +LRESULT ShellView_OnNotify(LPSHELLVIEW this, UINT32 CtlID, LPNMHDR lpnmh) +{ NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh; + LV_DISPINFO *lpdi = (LV_DISPINFO *)lpnmh; + LPITEMIDLIST pidl; + DWORD dwCursor; + STRRET str; + UINT32 uFlags; + IExtractIcon *pei; + + TRACE(shell,"%p CtlID=%u lpnmh->code=%x\n",this,CtlID,lpnmh->code); + + switch(lpnmh->code) + { case NM_SETFOCUS: + TRACE(shell,"NM_SETFOCUS %p\n",this); + ShellView_OnSetFocus(this); + break; + + case NM_KILLFOCUS: + TRACE(shell,"NM_KILLFOCUS %p\n",this); + ShellView_OnDeactivate(this); + break; + + case HDN_ENDTRACK: + TRACE(shell,"HDN_ENDTRACK %p\n",this); + /*nColumn1 = ListView_GetColumnWidth(this->hWndList, 0); + nColumn2 = ListView_GetColumnWidth(this->hWndList, 1);*/ + return 0; + + case LVN_DELETEITEM: + TRACE(shell,"LVN_DELETEITEM %p\n",this); + SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/ + break; + +#ifdef LVN_ITEMACTIVATE + case LVN_ITEMACTIVATE: + +#else //LVN_ITEMACTIVATE + case NM_DBLCLK: + case NM_RETURN: +#endif //LVN_ITEMACTIVATE + TRACE(shell,"LVN_ITEMACTIVATE | NM_RETURN %p\n",this); + ShellView_DoContextMenu(this, 0, 0, TRUE); + return 0; + + case LVN_GETDISPINFO: + TRACE(shell,"LVN_GETDISPINFO %p\n",this); + pidl = (LPITEMIDLIST)lpdi->item.lParam; + + + if(lpdi->item.iSubItem) /*is the sub-item information being requested?*/ + { if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/ + { if(PidlMgr_IsValue(NULL,pidl)) /*is this a value or a folder?*/ + { PidlMgr_GetDataText(NULL,this->mpidl, pidl, lpdi->item.pszText, lpdi->item.cchTextMax); + if(!*lpdi->item.pszText) + sprintf(lpdi->item.pszText, "file attrib %u", lpdi->item.iSubItem ); + } + else /*its a folder*/ + { sprintf(lpdi->item.pszText, "folder attrib %u", lpdi->item.iSubItem ); + } + } + } + else /*the item text is being requested*/ + { if(lpdi->item.mask & LVIF_TEXT) /*is the text being requested?*/ + { if(S_OK==this->pSFParent->lpvtbl->fnGetDisplayNameOf(this->pSFParent,pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &str)) + { if(STRRET_WSTR == str.uType) + { WideCharToLocal32(lpdi->item.pszText, str.u.pOleStr, lpdi->item.cchTextMax); + SHFree(str.u.pOleStr); + } + if(STRRET_CSTR == str.uType) + { strncpy(lpdi->item.pszText, str.u.cStr, lpdi->item.cchTextMax); + } + } + } + + if(lpdi->item.mask & LVIF_IMAGE) /*is the image being requested?*/ + { if(S_OK == (this->pSFParent->lpvtbl->fnGetUIObjectOf(this->pSFParent,this->hWnd,1, + (LPCITEMIDLIST*)&pidl, (REFIID)&IID_IExtractIcon, NULL, (LPVOID*)&pei))) + { //GetIconLoaction will give us the index into our image list + pei->lpvtbl->fnGetIconLocation(pei, GIL_FORSHELL, NULL, 0, &lpdi->item.iImage, &uFlags); + pei->lpvtbl->fnRelease(pei); + } + } + } + TRACE(shell,"-- text=%s image=%x\n",lpdi->item.pszText, lpdi->item.iImage); + return 0; + + case NM_RCLICK: + TRACE(shell,"NM_RCLICK %p\n",this); + dwCursor = GetMessagePos(); + ShellView_DoContextMenu(this, LOWORD(dwCursor), HIWORD(dwCursor), FALSE); + + case NM_CLICK: + TRACE(shell,"NM_CLICK %p\n",this); + break; + + case LVN_ITEMCHANGING: + TRACE(shell,"LVN_ITEMCHANGING %p\n",this); + break; + + case NM_CUSTOMDRAW: + TRACE(shell,"NM_CUSTOMDRAW %p\n",this); + break; + + default: + WARN (shell,"-- WM_NOTIFY unhandled\n"); + return 0; + } + return 0; +} + +/************************************************************************** +* ShellView_WndProc +*/ +//windowsx.h +#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp) +#define GET_WM_COMMAND_HWND(wp, lp) (HWND32)(lp) +#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) +// winuser.h +#define WM_SETTINGCHANGE WM_WININICHANGE + +LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam) +{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA); + LPCREATESTRUCT32A lpcs; + + FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam); + + switch (uMessage) + { case WM_NCCREATE: + { TRACE(shell,"WM_NCCREATE\n"); + lpcs = (LPCREATESTRUCT32A)lParam; + pThis = (LPSHELLVIEW)(lpcs->lpCreateParams); + SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis); + pThis->hWnd = hWnd; /*set the window handle*/ + } + break; + + case WM_SIZE: + TRACE(shell,"WM_SIZE\n"); + return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam)); + + case WM_SETFOCUS: + TRACE(shell,"WM_SETFOCUS\n"); + return ShellView_OnSetFocus(pThis); + + case WM_KILLFOCUS: + TRACE(shell,"WM_KILLFOCUS\n"); + return ShellView_OnKillFocus(pThis); + + case WM_CREATE: + TRACE(shell,"WM_CREATE\n"); + return ShellView_OnCreate(pThis); + + case WM_SHOWWINDOW: + TRACE(shell,"WM_SHOWWINDOW\n"); + UpdateWindow32(pThis->hWndList); + break; + + case WM_ACTIVATE: + TRACE(shell,"WM_ACTIVATE\n"); + return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS); + + case WM_COMMAND: + TRACE(shell,"WM_COMMAND\n"); + return ShellView_OnCommand(pThis, GET_WM_COMMAND_ID(wParam, lParam), + GET_WM_COMMAND_CMD(wParam, lParam), + GET_WM_COMMAND_HWND(wParam, lParam)); + + case WM_INITMENUPOPUP: + TRACE(shell,"WM_INITMENUPOPUP\n"); + return ShellView_UpdateMenu(pThis, (HMENU32)wParam); + + case WM_NOTIFY: + TRACE(shell,"WM_NOTIFY\n"); + return ShellView_OnNotify(pThis,(UINT32)wParam, (LPNMHDR)lParam); + + case WM_SETTINGCHANGE: + TRACE(shell,"WM_SETTINGCHANGE\n"); + return ShellView_OnSettingChange(pThis,(LPCSTR)lParam); + +/* -------------*/ + case WM_MOVE: + TRACE(shell,"WM_MOVE\n"); + break; + + case WM_ACTIVATEAPP: + TRACE(shell,"WM_ACTIVATEAPP\n"); + break; + + case WM_NOTIFYFORMAT: + TRACE(shell,"WM_NOTIFYFORMAT\n"); + break; + + case WM_NCPAINT: + TRACE(shell,"WM_NCPAINT\n"); + break; + + case WM_ERASEBKGND: + TRACE(shell,"WM_ERASEBKGND\n"); + break; + + case WM_PAINT: + TRACE(shell,"WM_PAINT\n"); + break; + + case WM_NCCALCSIZE: + TRACE(shell,"WM_NCCALCSIZE\n"); + break; + + case WM_WINDOWPOSCHANGING: + TRACE(shell,"WM_WINDOWPOSCHANGING\n"); + break; + + case WM_WINDOWPOSCHANGED: + TRACE(shell,"WM_WINDOWPOSCHANGED\n"); + break; + + case WM_PARENTNOTIFY: + TRACE(shell,"WM_PARENTNOTIFY\n"); + break; + + case WM_MOUSEACTIVATE: + TRACE(shell,"WM_MOUSEACTIVATE\n"); + break; + + case WM_SETCURSOR: + TRACE(shell,"WM_SETCURSOR\n"); + break; + } + return DefWindowProc32A (hWnd, uMessage, wParam, lParam); +} + + +/************************************************************************** +* IShellView::QueryInterface +*/ +static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ + { *ppvObj = this; + } + else if(IsEqualIID(riid, &IID_IShellView)) /*IShellView*/ + { *ppvObj = (IShellView*)this; + } + + if(*ppvObj) + { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this); + TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + TRACE(shell,"-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} +/************************************************************************** +* IShellView::AddRef +*/ +static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this) +{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); + return ++(this->ref); +} +/************************************************************************** +* IShellView::Release +*/ +static ULONG WINAPI IShellView_Release(LPSHELLVIEW this) +{ TRACE(shell,"(%p)->()\n",this); + if (!--(this->ref)) + { TRACE(shell," destroying IEnumIDList(%p)\n",this); + + if(this->pSFParent) + this->pSFParent->lpvtbl->fnRelease(this->pSFParent); + + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} +/************************************************************************** +* IShellView::GetWindow +*/ +static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd) +{ TRACE(shell,"(%p) stub\n",this); + *phWnd = this->hWnd; + + return S_OK; +} +static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode) +{ FIXME(shell,"(%p) stub\n",this); + return E_NOTIMPL; +} +static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg) +{ FIXME(shell,"(%p)->(%p) stub\n",this,lpmsg); + return E_NOTIMPL; +} +static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable) +{ FIXME(shell,"(%p) stub\n",this); + return E_NOTIMPL; +} +static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState) +{ CHAR szName[MAX_PATH]; + LRESULT lResult; + int nPartArray[1] = {-1}; + + FIXME(shell,"(%p) stub\n",this); + //don't do anything if the state isn't really changing + if(this->uState == uState) + { return S_OK; + } + + //OnActivate handles the menu merging and internal state + ShellView_OnActivate(this, uState); + + //remove the docking window + if(g_bShowIDW) + { ShellView_AddRemoveDockingWindow(this, FALSE); + } + + //only do this if we are active + if(uState != SVUIA_DEACTIVATE) + { //update the status bar + strcpy(szName, "dummy32"); + + this->pSFParent->lpvtbl->fnGetFolderPath(this->pSFParent, szName + strlen(szName), sizeof(szName) - strlen(szName)); + + /* set the number of parts */ + this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,FCW_STATUS, + SB_SETPARTS, 1, (LPARAM)nPartArray, &lResult); + + /* set the text for the parts */ + this->pShellBrowser->lpvtbl->fnSendControlMsg(this->pShellBrowser,FCW_STATUS, + SB_SETTEXT32A, 0, (LPARAM)szName, &lResult); + + //add the docking window if necessary + if(g_bShowIDW) + { ShellView_AddRemoveDockingWindow(this, TRUE); + } + } + return S_OK; +} +static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this) +{ TRACE(shell,"(%p) stub\n",this); + ListView_DeleteAllItems(this->hWndList); + ShellView_FillList(this); + return S_OK; +} +static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView, + LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd) +{ WNDCLASS32A wc; + *phWnd = 0; + + TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd); + TRACE(shell,"-- left=%i top=%i right=%i bottom=%i\n",prcView->left,prcView->top, prcView->right, prcView->bottom); + +//if our window class has not been registered, then do so + if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc)) + { ZeroMemory(&wc, sizeof(wc)); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC32) ShellView_WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = shell32_hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor32A (0, IDC_ARROW32A); + wc.hbrBackground = (HBRUSH32) (COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = SV_CLASS_NAME; + + if(!RegisterClass32A(&wc)) + return E_FAIL; + } + //set up the member variables + this->pShellBrowser = psb; + this->FolderSettings = *lpfs; + + //get our parent window + this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent)); + + *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, + prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top, + this->hWndParent, 0, shell32_hInstance, (LPVOID)this); + + if(!*phWnd) + return E_FAIL; + + this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser); + + return S_OK; +} + +static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this) +{ TRACE(shell,"(%p) stub\n",this); + + /*Make absolutely sure all our UI is cleaned up.*/ + IShellView_UIActivate(this, SVUIA_DEACTIVATE); + if(this->hMenu) + { DestroyMenu32(this->hMenu); + } + DestroyWindow32(this->hWnd); + this->pShellBrowser->lpvtbl->fnRelease(this->pShellBrowser); + return S_OK; +} +static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs) +{ FIXME(shell,"(%p)->(%p)stub\n",this, lpfs); + + *lpfs = this->FolderSettings; + return S_OK; +} +static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam) +{ FIXME(shell,"(%p) stub\n",this); + return E_NOTIMPL; +} +static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this) +{ FIXME(shell,"(%p) stub\n",this); + return S_OK; +} +static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags) +{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags); + return E_NOTIMPL; +} +static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut) +{ char xriid[50]; + WINE_StringFromCLSID((LPCLSID)riid,xriid); + + FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut); + + *ppvOut = NULL; + return E_NOTIMPL; +} diff --git a/dlls/shell32/shres.rc b/dlls/shell32/shres.rc new file mode 100644 index 00000000000..508a31d6f0a --- /dev/null +++ b/dlls/shell32/shres.rc @@ -0,0 +1,21 @@ +#include "shresdef.h" + +// we have to find a solution for the icons +// IDI_FOLDER ICON DISCARDABLE "folder.ico" +// IDI_FOLDEROPEN ICON DISCARDABLE "folderop.ico" + +STRINGTABLE DISCARDABLE +BEGIN + IDS_FILE_TITLE "Files: " + IDS_MI_FILE "&Files" + IDS_MI_VIEW_FILES "&View Files" + IDS_TB_VIEW_FILES "View Filess" + IDS_MI_VIEW_IDW "Show &Docking Window" + IDS_TB_VIEW_IDW "Show Docking Window" + IDS_COLUMN1 "Name" + IDS_COLUMN2 "Date" + IDS_COLUMN3 "Size" + IDS_COLUMN4 "Attributes" +END + + diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h new file mode 100644 index 00000000000..7ce020246ec --- /dev/null +++ b/dlls/shell32/shresdef.h @@ -0,0 +1,21 @@ +#ifndef __WINE_SHELL_RES_H +#define __WINE_SHELL_RES_H + +#define IDS_FILE_TITLE 1 +#define IDS_MI_FILE 2 +#define IDS_MI_VIEW_FILES 3 +#define IDS_TB_VIEW_FILES 4 +#define IDS_MI_VIEW_IDW 5 +#define IDS_TB_VIEW_IDW 6 + +#define IDS_COLUMN1 7 +#define IDS_COLUMN2 8 +#define IDS_COLUMN3 9 +#define IDS_COLUMN4 10 + +#define IDS_MI_FILEITEM 12 + +#define IDI_FOLDER 101 +#define IDI_FOLDEROPEN 102 + +#endif diff --git a/documentation/Makefile.in b/documentation/Makefile.in index fdf44b148c7..fb551bde644 100644 --- a/documentation/Makefile.in +++ b/documentation/Makefile.in @@ -52,10 +52,16 @@ $(INCLUDES): install:: $(INSTALL_DATA) $(SRCDIR)/wine.man $(mandir)/wine$(manext) +uninstall:: + $(RM) $(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 +uninstall_info: + for i in $(INFOFILES); do $(RM) $(infodir)/$$i; done + clean:: $(RM) $(INFOFILES) $(DVIFILES) $(INCLUDES) $(RM) wine.aux wine.cp wine.cps wine.fn wine.fns wine.ky wine.log \ diff --git a/documentation/common_controls b/documentation/common_controls index 6f854a23119..43b44305727 100644 --- a/documentation/common_controls +++ b/documentation/common_controls @@ -199,7 +199,7 @@ - Basic functionality is almost done. (dll version 4.0) Notes: - Bitmaps are not correctly displayed. + - Bitmaps are not correctly displayed. 3.19 Tooltip Control @@ -212,7 +212,6 @@ Notes: - Unicode support is still missing. - - No subclassing. 3.20 Trackbar Control @@ -236,9 +235,6 @@ Status: - Dummy control. No functionality. - Notes: - Author needed!! Any volunteers?? - 3.22 Updown Control ------------------- @@ -270,7 +266,7 @@ ------------------------ There are quite a lot of undocumented functions like: - - DSA (Dynnamic String Array?) functions. + - DSA (Dynnamic Structure Array) functions. - DPA (Dymnamic Pointer Array?) functions. - MRU ("Most Recently Used" List) functions. - other unknown functions. @@ -278,12 +274,13 @@ Have a look at relay32/comctl32.spec. -5.1 Dymnamic String Arrays ??? (DSA) +5.1 Dymnamic Structure Arrays (DSA) ------------------------------------ Most of the DSA functions are implemented. I used TASKMAN.EXE to write them. Since TASKMAN.EXE doesn't bail out or crash I think I've done it right. Have a look at the source code to get more information. + Further documentation will be written... @@ -298,16 +295,32 @@ Further documentation will be written... -5.3 MenuHelp +5.3 "Most Recently Used" - List (MRU) +------------------------------------- + Currently no information available! + + +5.4 MenuHelp ------------ Has to be written... -5.4 GetEffectiveClientRect +5.5 GetEffectiveClientRect -------------------------- Has to be written... +5.6 ShowHideMenuCtl +------------------- + The official documentation provided by MS is incomplete. + + lpInfo: + ... + Both values of the first pair must be the handle to the applications main + menu. + ... + + 6. Epilogue ----------- You see, much work has still to be done. If you are interested in writing diff --git a/documentation/filehandles b/documentation/filehandles new file mode 100644 index 00000000000..d002e4a3213 --- /dev/null +++ b/documentation/filehandles @@ -0,0 +1,26 @@ +DOS treats the first 5 file handles as special cases. They map directly +to stdin, stdout, stderr, stdaux and stdprn. Windows 16 inherits this +behavoir, and in fact, win16 handles are interchangable with DOS handles. +Some nasty windows programs even do this! + +Windows32 issues file handles starting from 1, on the grounds that +most GUI processes don't need a stdin, out, etc. + +The wine handle code is implemented in the Win32 style, and the Win16 +functions use two macros to convert to and from the two types. + +The macros are defined in file.h as follows.: +#define HFILE16_TO_HFILE32(handle) \ +(((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \ + ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \ + ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \ + (handle)-5) + +#define HFILE32_TO_HFILE16(handle) ({ HFILE32 hnd=handle; \ + ((hnd==HFILE_ERROR32) ? HFILE_ERROR16 : \ + (HFILE16)hnd+5); }) + +WARNING: be careful not to use the macro HFILE16_TO_HFILE32 on +functions with side-effects, as it will cause them to be evaluated +several times. This could be considered a bug, but the use of this +macro is limited enough not to need a rewrite. diff --git a/documentation/internal-dll b/documentation/internal-dll new file mode 100644 index 00000000000..d90b70b18e5 --- /dev/null +++ b/documentation/internal-dll @@ -0,0 +1,75 @@ +This document describes some points you should know when you are going to +implement the internal counterparts to external DLL's. Only 32 bit DLL's +are considered. + +1. The LibMain function +----------------------- +These are the way to do some initialising when a process or thread is attached +to the dll. The function name is taken from a *.spec file line: + +init YourFunctionName + +the you have to implement the function: + + +BOOL32 WINAPI YourLibMain(HINSTANCE32 hinstDLL, + DWORD fdwReason, LPVOID lpvReserved) +{ if (fdwReason==DLL_PROCESS_ATTACH) + { ... + } + .... +} + + +2. Using functions from other build-in DLL's +-------------------------------------------- +The problem here is, that you can't know if you have to call the function from +the internal or the external DLL. If you just call the function you will get +the internal implementation. If the external DLL is loaded the executed program +will use the external and you the internal DLL. +When you -as example- fill a iconlist placed in the internal DLL the +application wont get the icons from the external DLL. + +To go around this you have to call the functions over pointer. + +/* definition of the pointer type*/ +void (CALLBACK* pDLLInitComctl)(); + +/* getting the function address this should be done in the + LibMain function when called with DLL_PROCESS_ATTACH*/ + +BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, + LPVOID lpvReserved) +{ HINSTANCE32 hComctl32; + if (fdwReason==DLL_PROCESS_ATTACH) + { /* load the external / internal DLL*/ + hComctl32 = LoadLibrary32A("COMCTL32.DLL"); + if (hComctl32) + { /* get the function pointer */ + pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx"); + + /* check it */ + if (pDLLInitComctl) + { /* use it */ + pDLLInitComctl(); + } + + /* free the DLL / decrease the ref count */ + FreeLibrary32(hComctl32); + } + else + { /* do some panic*/ + ERR(shell,"P A N I C error getting functionpointers\n"); + exit (1); + } + } + .... + +3. Getting resources from a *.rc file linked to the DLL +------------------------------------------------------- +< If you know how, write some lines> + + + +---------- + diff --git a/documentation/shell32 b/documentation/shell32 new file mode 100644 index 00000000000..4fcb2ef522c --- /dev/null +++ b/documentation/shell32 @@ -0,0 +1,71 @@ + SHELL32 + development status + + Author needed!! Any volunteers?? + mail to + +1. Introduction +--------------- +All parts of this DLL are currently under development. About a third of +base functionality is roughly in place. The missing parts are the icon +(shell icon cache) handling and the dialogs provided from the dll like +the file copy status window. + +The basis comes from Marcus Meissner and I +implemented the classes and filled function stubs. + +2. General Information +---------------------- + +3. Functions +------------ + +4. Classes +---------- + +4.1 IContextMenu +---------------- + Status: + - development started + +4.2 IShellExtInit +----------------- + only interface definition + +4.3 IEnumIDList +--------------- + Status: + - Almost finished. + + +4.4.IShellFolder +---------------- + Status: + - roughly finished. + + +4.5 IShellView +-------------- + Status: + - under development + + +4.6 IShellBrowser +----------------- + Status: + - only interface definition + it's implemented by the explorer + don't know if we need it + +4.7. PIDL Manager +----------------- + Status: + - roughly complete will be migrated to a set of functions because it's + not holding any instance data, + + +5. Structures +------------- + +5.1 PIDL +-------- diff --git a/files/dos_fs.c b/files/dos_fs.c index e61e8e71511..fd168c4fee1 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -24,6 +24,7 @@ #include "file.h" #include "heap.h" #include "msdos.h" +#include "syslevel.h" #include "debug.h" /* Define the VFAT ioctl to get both short and long file names */ @@ -74,16 +75,6 @@ BYTE DOS_ErrorClass; BYTE DOS_ErrorAction; BYTE DOS_ErrorLocus; -/* Info structure for FindFirstFile handle */ -typedef struct -{ - LPSTR path; - LPSTR mask; - int drive; - int skip; -} FIND_FIRST_INFO; - - /* Directory info for DOSFS_ReadDir */ typedef struct { @@ -95,6 +86,19 @@ typedef struct #endif } DOS_DIR; +/* Info structure for FindFirstFile handle */ +typedef struct +{ + LPSTR path; + LPSTR long_mask; + LPSTR short_mask; + BYTE attr; + int drive; + int cur_pos; + DOS_DIR *dir; +} FIND_FIRST_INFO; + + /*********************************************************************** * DOSFS_ValidDOSName @@ -1016,33 +1020,23 @@ DWORD WINAPI GetFullPathName32W( LPCWSTR name, DWORD len, LPWSTR buffer, return ret; } - /*********************************************************************** - * DOSFS_FindNext - * - * Find the next matching file. Return the number of entries read to find - * the matching one, or 0 if no more entries. - * 'short_mask' is the 8.3 mask (in FCB format), 'long_mask' is the long - * file name mask. Either or both can be NULL. + * DOSFS_FindNextEx */ -int DOSFS_FindNext( const char *path, const char *short_mask, - const char *long_mask, int drive, BYTE attr, - int skip, WIN32_FIND_DATA32A *entry ) +static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATA32A *entry ) { - static DOS_DIR *dir = NULL; - int count = 0; - static char buffer[MAX_PATHNAME_LEN]; - static int cur_pos = 0; - static int drive_root = 0; - char *p; - char dos_name[13]; + BYTE attr = info->attr | FA_UNUSED | FA_ARCHIVE | FA_RDONLY; + UINT32 flags = DRIVE_GetFlags( info->drive ); + char *p, buffer[MAX_PATHNAME_LEN]; + const char *drive_path; + int drive_root; LPCSTR long_name, short_name; - UINT32 flags; - BY_HANDLE_FILE_INFORMATION info; + BY_HANDLE_FILE_INFORMATION fileinfo; + char dos_name[13]; - if ((attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL) + if ((info->attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL) { - if (skip) return 0; + if (info->cur_pos) return 0; entry->dwFileAttributes = FILE_ATTRIBUTE_LABEL; DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftCreationTime, 0 ); DOSFS_UnixTimeToFileTime( (time_t)0, &entry->ftLastAccessTime, 0 ); @@ -1051,37 +1045,23 @@ int DOSFS_FindNext( const char *path, const char *short_mask, entry->nFileSizeLow = 0; entry->dwReserved0 = 0; entry->dwReserved1 = 0; - DOSFS_ToDosDTAFormat( DRIVE_GetLabel( drive ), entry->cFileName ); - strcpy( entry->cAlternateFileName, entry->cFileName ); + DOSFS_ToDosDTAFormat( DRIVE_GetLabel( info->drive ), entry->cFileName ); + strcpy( entry->cAlternateFileName, entry->cFileName ); + info->cur_pos++; return 1; } - /* Check the cached directory */ - if (dir && !strcmp( buffer, path ) && (cur_pos <= skip)) skip -= cur_pos; - else /* Not in the cache, open it anew */ - { - const char *drive_path; - TRACE(dosfs, "cache miss, path=%s skip=%d buf=%s cur=%d\n", - path, skip, buffer, cur_pos ); - cur_pos = skip; - if (dir) DOSFS_CloseDir(dir); - if (!*path) path = "/"; - if (!(dir = DOSFS_OpenDir(path))) return 0; - drive_path = path + strlen(DRIVE_GetRoot(drive)); - while ((*drive_path == '/') || (*drive_path == '\\')) drive_path++; - drive_root = !*drive_path; - TRACE(dosfs, "drive_root = %d\n", drive_root); - lstrcpyn32A( buffer, path, sizeof(buffer) - 1 ); - } + drive_path = info->path + strlen(DRIVE_GetRoot( info->drive )); + while ((*drive_path == '/') || (*drive_path == '\\')) drive_path++; + drive_root = !*drive_path; + + lstrcpyn32A( buffer, info->path, sizeof(buffer) - 1 ); strcat( buffer, "/" ); p = buffer + strlen(buffer); - attr |= FA_UNUSED | FA_ARCHIVE | FA_RDONLY; - flags = DRIVE_GetFlags( drive ); - while (DOSFS_ReadDir( dir, &long_name, &short_name )) + while (DOSFS_ReadDir( info->dir, &long_name, &short_name )) { - if (skip-- > 0) continue; - count++; + info->cur_pos++; /* Don't return '.' and '..' in the root of the drive */ if (drive_root && (long_name[0] == '.') && @@ -1090,15 +1070,15 @@ int DOSFS_FindNext( const char *path, const char *short_mask, /* Check the long mask */ - if (long_mask) + if (info->long_mask) { - if (!DOSFS_MatchLong( long_mask, long_name, + if (!DOSFS_MatchLong( info->long_mask, long_name, flags & DRIVE_CASE_SENSITIVE )) continue; } /* Check the short mask */ - if (short_mask) + if (info->short_mask) { if (!short_name) { @@ -1106,27 +1086,27 @@ int DOSFS_FindNext( const char *path, const char *short_mask, !(flags & DRIVE_CASE_SENSITIVE) ); short_name = dos_name; } - if (!DOSFS_MatchShort( short_mask, short_name )) continue; + if (!DOSFS_MatchShort( info->short_mask, short_name )) continue; } /* Check the file attributes */ lstrcpyn32A( p, long_name, sizeof(buffer) - (int)(p - buffer) ); - if (!FILE_Stat( buffer, &info )) + if (!FILE_Stat( buffer, &fileinfo )) { WARN(dosfs, "can't stat %s\n", buffer); continue; } - if (info.dwFileAttributes & ~attr) continue; + if (fileinfo.dwFileAttributes & ~attr) continue; /* We now have a matching entry; fill the result and return */ - entry->dwFileAttributes = info.dwFileAttributes; - entry->ftCreationTime = info.ftCreationTime; - entry->ftLastAccessTime = info.ftLastAccessTime; - entry->ftLastWriteTime = info.ftLastWriteTime; - entry->nFileSizeHigh = info.nFileSizeHigh; - entry->nFileSizeLow = info.nFileSizeLow; + entry->dwFileAttributes = fileinfo.dwFileAttributes; + entry->ftCreationTime = fileinfo.ftCreationTime; + entry->ftLastAccessTime = fileinfo.ftLastAccessTime; + entry->ftLastWriteTime = fileinfo.ftLastWriteTime; + entry->nFileSizeHigh = fileinfo.nFileSizeHigh; + entry->nFileSizeLow = fileinfo.nFileSizeLow; if (short_name) DOSFS_ToDosDTAFormat( short_name, entry->cAlternateFileName ); @@ -1139,15 +1119,75 @@ int DOSFS_FindNext( const char *path, const char *short_mask, TRACE(dosfs, "returning %s (%s) %02lx %ld\n", entry->cFileName, entry->cAlternateFileName, entry->dwFileAttributes, entry->nFileSizeLow ); - cur_pos += count; - p[-1] = '\0'; /* Remove trailing slash in buffer */ - return count; + return 1; } - DOSFS_CloseDir( dir ); - dir = NULL; return 0; /* End of directory */ } +/*********************************************************************** + * DOSFS_FindNext + * + * Find the next matching file. Return the number of entries read to find + * the matching one, or 0 if no more entries. + * 'short_mask' is the 8.3 mask (in FCB format), 'long_mask' is the long + * file name mask. Either or both can be NULL. + * + * NOTE: This is supposed to be only called by the int21 emulation + * routines. Thus, we should own the Win16Mutex anyway. + * Nevertheless, we explicitly enter it to ensure the static + * directory cache is protected. + */ +int DOSFS_FindNext( const char *path, const char *short_mask, + const char *long_mask, int drive, BYTE attr, + int skip, WIN32_FIND_DATA32A *entry ) +{ + static FIND_FIRST_INFO info = { NULL }; + LPCSTR short_name, long_name; + int count; + + SYSLEVEL_EnterWin16Lock(); + + /* Check the cached directory */ + if (!(info.dir && info.path == path && info.short_mask == short_mask + && info.long_mask == long_mask && info.drive == drive + && info.attr == attr && info.cur_pos <= skip)) + { + /* Not in the cache, open it anew */ + if (info.dir) DOSFS_CloseDir( info.dir ); + + info.path = (LPSTR)path; + info.long_mask = (LPSTR)long_mask; + info.short_mask = (LPSTR)short_mask; + info.attr = attr; + info.drive = drive; + info.cur_pos = 0; + info.dir = DOSFS_OpenDir( info.path ); + } + + /* Skip to desired position */ + while (info.cur_pos < skip) + if (DOSFS_ReadDir( info.dir, &long_name, &short_name )) + info.cur_pos++; + else + break; + + if (info.cur_pos == skip && DOSFS_FindNextEx( &info, entry )) + count = info.cur_pos - skip; + else + count = 0; + + if (!count) + { + DOSFS_CloseDir( info.dir ); + memset( &info, '\0', sizeof(info) ); + } + + SYSLEVEL_LeaveWin16Lock(); + + return count; +} + + /************************************************************************* * FindFirstFile16 (KERNEL.413) @@ -1165,11 +1205,16 @@ HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATA32A *data ) return INVALID_HANDLE_VALUE16; info = (FIND_FIRST_INFO *)GlobalLock16( handle ); info->path = HEAP_strdupA( SystemHeap, 0, full_name.long_name ); - info->mask = strrchr( info->path, '/' ); - *(info->mask++) = '\0'; + info->long_mask = strrchr( info->path, '/' ); + *(info->long_mask++) = '\0'; + info->short_mask = NULL; + info->attr = 0xff; if (path[0] && (path[1] == ':')) info->drive = toupper(*path) - 'A'; else info->drive = DRIVE_GetCurrentDrive(); - info->skip = 0; + info->cur_pos = 0; + + info->dir = DOSFS_OpenDir( info->path ); + GlobalUnlock16( handle ); if (!FindNextFile16( handle, data )) { @@ -1222,7 +1267,6 @@ HANDLE32 WINAPI FindFirstFile32W( LPCWSTR path, WIN32_FIND_DATA32W *data ) BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATA32A *data ) { FIND_FIRST_INFO *info; - int count; if (!(info = (FIND_FIRST_INFO *)GlobalLock16( handle ))) { @@ -1230,20 +1274,19 @@ BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATA32A *data ) return FALSE; } GlobalUnlock16( handle ); - if (!info->path) + if (!info->path || !info->dir) { DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk ); return FALSE; } - if (!(count = DOSFS_FindNext( info->path, NULL, info->mask, info->drive, - 0xff, info->skip, data ))) + if (!DOSFS_FindNextEx( info, data )) { + DOSFS_CloseDir( info->dir ); info->dir = NULL; HeapFree( SystemHeap, 0, info->path ); - info->path = info->mask = NULL; + info->path = info->long_mask = NULL; DOS_ERROR( ER_NoMoreFiles, EC_MediaError, SA_Abort, EL_Disk ); return FALSE; } - info->skip += count; return TRUE; } @@ -1289,6 +1332,7 @@ BOOL16 WINAPI FindClose16( HANDLE16 handle ) DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk ); return FALSE; } + if (info->dir) DOSFS_CloseDir( info->dir ); if (info->path) HeapFree( SystemHeap, 0, info->path ); GlobalUnlock16( handle ); GlobalFree16( handle ); diff --git a/files/file.c b/files/file.c index 6ae8d60197d..a2bd5dd3f98 100644 --- a/files/file.c +++ b/files/file.c @@ -871,7 +871,7 @@ error: /* We get here if there was an error opening the file */ */ HFILE16 WINAPI OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode ) { - return FILE_DoOpenFile( name, ofs, mode, FALSE ); + return HFILE32_TO_HFILE16(FILE_DoOpenFile( name, ofs, mode, FALSE )); } @@ -890,7 +890,7 @@ HFILE32 WINAPI OpenFile32( LPCSTR name, OFSTRUCT *ofs, UINT32 mode ) HFILE16 WINAPI _lclose16( HFILE16 hFile ) { TRACE(file, "handle %d\n", hFile ); - return CloseHandle( hFile ) ? 0 : HFILE_ERROR16; + return CloseHandle( HFILE16_TO_HFILE32( hFile ) ) ? 0 : HFILE_ERROR16; } @@ -917,7 +917,7 @@ LONG WINAPI WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count ) /* Some programs pass a count larger than the allocated buffer */ maxlen = GetSelectorLimit( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1; if (count > maxlen) count = maxlen; - return _lread32( hFile, PTR_SEG_TO_LIN(buffer), count ); + return _lread32(HFILE16_TO_HFILE32(hFile), PTR_SEG_TO_LIN(buffer), count ); } @@ -955,7 +955,7 @@ UINT32 WINAPI _lread32( HFILE32 handle, LPVOID buffer, UINT32 count ) */ UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count ) { - return (UINT16)_lread32( hFile, buffer, (LONG)count ); + return (UINT16)_lread32(HFILE16_TO_HFILE32(hFile), buffer, (LONG)count ); } @@ -966,7 +966,7 @@ HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr ) { int mode = (attr & 1) ? 0444 : 0666; TRACE(file, "%s %02x\n", path, attr ); - return (HFILE16)FILE_Create( path, mode, FALSE ); + return (HFILE16) HFILE32_TO_HFILE16(FILE_Create( path, mode, FALSE )); } @@ -1038,7 +1038,7 @@ DWORD WINAPI SetFilePointer( HFILE32 hFile, LONG distance, LONG *highword, */ LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin ) { - return SetFilePointer( hFile, lOffset, NULL, nOrigin ); + return SetFilePointer( HFILE16_TO_HFILE32(hFile), lOffset, NULL, nOrigin ); } @@ -1056,7 +1056,7 @@ LONG WINAPI _llseek32( HFILE32 hFile, LONG lOffset, INT32 nOrigin ) */ HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode ) { - return _lopen32( path, mode ); + return HFILE32_TO_HFILE16(_lopen32( path, mode )); } @@ -1091,7 +1091,7 @@ HFILE32 WINAPI _lopen32( LPCSTR path, INT32 mode ) */ UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count ) { - return (UINT16)_hwrite32( hFile, buffer, (LONG)count ); + return (UINT16)_hwrite32( HFILE16_TO_HFILE32(hFile), buffer, (LONG)count ); } /*********************************************************************** @@ -1108,7 +1108,7 @@ UINT32 WINAPI _lwrite32( HFILE32 hFile, LPCSTR buffer, UINT32 count ) */ LONG WINAPI _hread16( HFILE16 hFile, LPVOID buffer, LONG count) { - return _lread32( hFile, buffer, count ); + return _lread32( HFILE16_TO_HFILE32(hFile), buffer, count ); } @@ -1126,7 +1126,7 @@ LONG WINAPI _hread32( HFILE32 hFile, LPVOID buffer, LONG count) */ LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count ) { - return _hwrite32( hFile, buffer, count ); + return _hwrite32( HFILE16_TO_HFILE32(hFile), buffer, count ); } diff --git a/files/profile.c b/files/profile.c index ecdd09cba78..49b58d79add 100644 --- a/files/profile.c +++ b/files/profile.c @@ -945,7 +945,7 @@ INT32 WINAPI GetProfileString32W( LPCWSTR section, LPCWSTR entry, /*********************************************************************** * GetProfileSection32A (KERNEL32.268) */ -INT32 WINAPI GetProfileSection32A( LPCSTR section, LPSTR buffer, UINT32 len ) +INT32 WINAPI GetProfileSection32A( LPCSTR section, LPSTR buffer, DWORD len ) { return GetPrivateProfileSection32A( section, buffer, len, "win.ini" ); } @@ -1080,7 +1080,7 @@ INT32 WINAPI GetPrivateProfileString32W( LPCWSTR section, LPCWSTR entry, * GetPrivateProfileSection32A (KERNEL32.255) */ INT32 WINAPI GetPrivateProfileSection32A( LPCSTR section, LPSTR buffer, - UINT32 len, LPCSTR filename ) + DWORD len, LPCSTR filename ) { if (PROFILE_Open( filename )) return PROFILE_GetSection(CurProfile->section, section, buffer, len, @@ -1186,7 +1186,7 @@ WORD WINAPI GetPrivateProfileSectionNames16( LPSTR buffer, WORD size, /*********************************************************************** * GetPrivateProfileStruct32A (KERNEL32.370) */ -WORD WINAPI GetPrivateProfileStruct32A (LPCSTR section, LPCSTR key, +BOOL32 WINAPI GetPrivateProfileStruct32A (LPCSTR section, LPCSTR key, LPVOID buf, UINT32 len, LPCSTR filename) { PROFILEKEY *k; @@ -1204,7 +1204,7 @@ WORD WINAPI GetPrivateProfileStruct32A (LPCSTR section, LPCSTR key, /*********************************************************************** * WritePrivateProfileStruct32A (KERNEL32.744) */ -WORD WINAPI WritePrivateProfileStruct32A (LPCSTR section, LPCSTR key, +BOOL32 WINAPI WritePrivateProfileStruct32A (LPCSTR section, LPCSTR key, LPVOID buf, UINT32 bufsize, LPCSTR filename) { if ((!section) && (!key) && (!buf)) { /* flush the cache */ diff --git a/graphics/ddraw.c b/graphics/ddraw.c index 442089145b2..3c64fcc6d2a 100644 --- a/graphics/ddraw.c +++ b/graphics/ddraw.c @@ -1,4 +1,4 @@ -/* DirectDraw using DGA, XShm, or Xlib +/* DirectDraw using DGA or Xlib * * Copyright 1997,1998 Marcus Meissner */ @@ -10,52 +10,20 @@ * - A terminal connected to the serial port. Can be bought used for cheap. * (This is the method I am using.) * - Another machine connected over some kind of network. - */ -/* Progress on following programs: * - * - Diablo [640x480x8]: - * The movies play. The game doesn't work, it somehow tries to write - * into 2 lines _BEFORE_ the start of the surface. Don't know why. + * FIXME: The Xshm implementation has been temporarily removed. It will be + * later reintegrated into the Xlib implementation. * - * - WingCommander 4 / Win95 Patch [640x480x8]: - * The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine - * "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to - * my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual - * 555. Specifying it in DDPIXELFORMAT didn't help. - * Requires to be run in 640x480xdepth mode (doesn't seem to heed - * DDSURFACEDESC.lPitch). You can fly the first mission with Maniac, but - * it crashes as soon as you arrive at Blue Point Station... - * - * - Monkey Island 3 [640x480x8]: - * Goes to the easy/hard selection screen, then hangs due to MT problems. - * - * - DiscWorld 2 [640x480x8]: - * [Crashes with 'cli' in released version. Yes. Privileged instructions - * in 32bit code. Will they ever learn...] - * Plays through nearly all intro movies. Sound and animation skip a lot of - * stuff (possible DirectSound problem). - * - * - XvT [640x480x16]: - * Shows the splash screen, then fails with missing Joystick. - * - * - Tomb Raider 2 Demo (using 8 bit renderer) [640x480x8]: - * Playable. Sound is weird. - * - * - WingCommander Prophecy Demo (using software renderer) [640x480x16]: - * [Crashes with an invalid opcode (outb) in the release version.] - * Plays intromovie, hangs in selection screen (no keyboard input, probably - * DirectInput problem). + * FIXME: The Xlib implementation hangs the windowmanager and all other + * running X clients, even though I am polling X events and answering + * them. But you can switch to another console (ctrl-alt-fx) and + * "killall wine" processes. Any help on this one appreciated. -Marcus */ #include "config.h" #include #include #include "ts_xlib.h" -#ifdef HAVE_LIBXXSHM -#include "ts_xshm.h" -#include -#include -#endif #include #include "windows.h" @@ -78,6 +46,9 @@ #include "ts_xf86dga.h" #endif +/* define this if you want to play Diablo using XF86DGA. (bug workaround) */ +#undef DIABLO_HACK + /* restore signal handlers overwritten by XF86DGA * this is a define, for it will only work in emulator mode */ @@ -93,12 +64,7 @@ static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */ 0x11d1, {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02} }; -static GUID XSHM_DirectDraw_GUID = { /* 2e494ff0-dc61-11d1-8407-860cf3f59f7a */ - 0x2e494ff0, - 0xdc61, - 0x11d1, - {0x84, 0x07, 0x86, 0x0c, 0xf3, 0xf5, 0x9f, 0x7a} -}; + static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */ 0x1574a740, 0xdc61, @@ -106,25 +72,26 @@ static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */ {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79} }; -static struct IDirectDrawSurface3_VTable dga_dds3vt, xshm_dds3vt, xlib_dds3vt; -static struct IDirectDraw_VTable dga_ddvt, xshm_ddvt, xlib_ddvt; -static struct IDirectDraw2_VTable dga_dd2vt, xshm_dd2vt, xlib_dd2vt; +static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt; +static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt; +static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt; static struct IDirectDrawClipper_VTable ddclipvt; -static struct IDirectDrawPalette_VTable dga_ddpalvt, xshm_ddpalvt, xlib_ddpalvt; +static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt; static struct IDirect3D_VTable d3dvt; static struct IDirect3D2_VTable d3d2vt; void Xlib_MessagePump(HWND32 hwnd) { MSG32 msg32; - while (PeekMessage32A(&msg32,0,0,0,PM_NOYIELD)) { - GetMessage32A(&msg32,0,0,0); - TranslateMessage32(&msg32); - DispatchMessage32A(&msg32); + while (EVENT_WaitNetEvent(FALSE,FALSE)) { + while (PeekMessage32A(&msg32,0,0,0,0)) { + GetMessage32A(&msg32,0,0,0); + TranslateMessage32(&msg32); + DispatchMessage32A(&msg32); + } } } - BOOL32 DDRAW_DGA_Available() { @@ -136,24 +103,11 @@ DDRAW_DGA_Available() #endif /* defined(HAVE_LIBXXF86DGA) */ } -BOOL32 -DDRAW_XShm_Available() -{ -#ifdef HAVE_LIBXXSHM - return TSXShmQueryExtension(display); -#else /* defined(HAVE_LIBXXSHM) */ - return 0; -#endif /* defined(HAVE_LIBXXSHM) */ -} - HRESULT WINAPI DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) { if (DDRAW_DGA_Available()) { ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data); } - if (DDRAW_XShm_Available()) { - ddenumproc(&XSHM_DirectDraw_GUID,"WINE with MIT XShm","display",data); - } ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data); ddenumproc(NULL,"WINE","display",data); return 0; @@ -326,7 +280,7 @@ static void _dump_DDSD(DWORD flagmask) { DUMP("\n"); } -static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) { +static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) { static XVisualInfo *vi; XVisualInfo vt; int nitems; @@ -353,7 +307,7 @@ static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) { pf->xy.dwRGBAlphaBitMask= 0; return 0; } - FIXME(ddraw,"_getpixelformat:oops?\n"); + FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth); return DDERR_GENERIC; } @@ -374,7 +328,7 @@ static HRESULT WINAPI IDirectDrawSurface3_Lock( this,lprect,lpddsd,flags,(DWORD)hnd); if (lprect) { - TRACE(ddraw," lprect: %dx%d-%dx%d\n", + FIXME(ddraw," lprect: %dx%d-%dx%d\n", lprect->top,lprect->left,lprect->bottom,lprect->right ); lpddsd->y.lpSurface = this->s.surface + @@ -399,40 +353,14 @@ static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock( return 0; } -static HRESULT WINAPI XShm_IDirectDrawSurface3_Unlock( - LPDIRECTDRAWSURFACE3 this,LPVOID surface -) { -#ifdef HAVE_LIBXXSHM - TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); - /* FIXME: is it really right to display the image on unlock? - * or should it wait for a Flip()? */ - TSXShmPutImage(display, - this->s.ddraw->e.xshm.drawable, - DefaultGCOfScreen(screen), - this->t.xshm.image, - 0, 0, 0, 0, - this->t.xshm.image->width, - this->t.xshm.image->height, - False); -/* - if (this->s.palette && this->s.palette->cm) { - TSXInstallColormap(display,this->s.palette->cm); - } -*/ - /*TSXSync(display,False);*/ - EVENT_Synchronize(); - return 0; -#else /* defined(HAVE_LIBXXSHM) */ - return E_UNEXPECTED; -#endif /* defined(HAVE_LIBXXSHM) */ -} - static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock( LPDIRECTDRAWSURFACE3 this,LPVOID surface ) { Xlib_MessagePump(this->s.ddraw->e.xlib.window); TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); + if (!this->s.ddraw->e.xlib.paintable) + return 0; TSXPutImage( display, this->s.ddraw->e.xlib.drawable, DefaultGCOfScreen(screen), @@ -441,8 +369,6 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock( this->t.xlib.image->width, this->t.xlib.image->height ); - /*TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);*/ - EVENT_Synchronize(); return 0; } @@ -482,47 +408,14 @@ static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip( #endif /* defined(HAVE_LIBXXF86DGA) */ } -static HRESULT WINAPI XShm_IDirectDrawSurface3_Flip( - LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags -) { -#ifdef HAVE_LIBXXSHM - TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags); - if (!flipto) { - if (this->s.backbuffer) - flipto = this->s.backbuffer; - else - flipto = this; - } - TSXShmPutImage(display, - this->s.ddraw->e.xshm.drawable, - DefaultGCOfScreen(screen), - flipto->t.xshm.image, - 0, 0, 0, 0, - flipto->t.xshm.image->width, - flipto->t.xshm.image->height, - False); -/* - if (flipto->s.palette && flipto->s.palette->cm) { - TSXInstallColormap(display,flipto->s.palette->cm); - } -*/ - EVENT_Synchronize(); - if (flipto!=this) { - XImage *tmp; - tmp = this->t.xshm.image; - this->t.xshm.image = flipto->t.xshm.image; - flipto->t.xshm.image = tmp; - } - return 0; -#else /* defined(HAVE_LIBXXSHM) */ - return E_UNEXPECTED; -#endif /* defined(HAVE_LIBXXSHM) */ -} - static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip( LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags ) { TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags); + Xlib_MessagePump(this->s.ddraw->e.xlib.window); + if (!this->s.ddraw->e.xlib.paintable) + return 0; + if (!flipto) { if (this->s.backbuffer) flipto = this->s.backbuffer; @@ -537,7 +430,6 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip( flipto->t.xlib.image->width, flipto->t.xlib.image->height); TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm); - EVENT_Synchronize(); if (flipto!=this) { XImage *tmp; LPVOID *surf; @@ -712,24 +604,6 @@ static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) { return this->ref; } -static ULONG WINAPI XShm_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) { - TRACE(ddraw,"(%p)->Release()\n",this); -#ifdef HAVE_LIBXXSHM - if (!--(this->ref)) { - this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw); - HeapFree(GetProcessHeap(),0,this->s.surface); - this->t.xshm.image->data = NULL; - TSXShmDetach(display,&this->t.xshm.shminfo); - TSXDestroyImage(this->t.xshm.image); - shmdt(this->t.xshm.shminfo.shmaddr); - shmctl(this->t.xshm.shminfo.shmid, IPC_RMID, 0); - HeapFree(GetProcessHeap(),0,this); - return 0; - } -#endif /* defined(HAVE_LIBXXSHM) */ - return this->ref; -} - static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) { TRACE(ddraw,"(%p)->Release()\n",this); if (!--(this->ref)) { @@ -803,13 +677,13 @@ static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface( static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) { FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc); - *lphdc = GetDC32(this->s.ddraw->e.xlib.window); + *lphdc = BeginPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps); return 0; } static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) { FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc); - ReleaseDC32(this->s.ddraw->e.xlib.window,hdc); + EndPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps); return 0; } @@ -901,49 +775,6 @@ static struct IDirectDrawSurface3_VTable dga_dds3vt = { (void*)40, }; -static struct IDirectDrawSurface3_VTable xshm_dds3vt = { - IDirectDrawSurface3_QueryInterface, - IDirectDrawSurface3_AddRef, - XShm_IDirectDrawSurface3_Release, - IDirectDrawSurface3_AddAttachedSurface, - (void*)5, - IDirectDrawSurface3_Blt, - IDirectDrawSurface3_BltBatch, - IDirectDrawSurface3_BltFast, - (void*)9, - IDirectDrawSurface3_EnumAttachedSurfaces, - (void*)11, - XShm_IDirectDrawSurface3_Flip, - IDirectDrawSurface3_GetAttachedSurface, - IDirectDrawSurface3_GetBltStatus, - IDirectDrawSurface3_GetCaps, - (void*)16, - (void*)17, - IDirectDrawSurface3_GetDC, - (void*)19, - IDirectDrawSurface3_GetOverlayPosition, - (void*)21, - IDirectDrawSurface3_GetPixelFormat, - IDirectDrawSurface3_GetSurfaceDesc, - IDirectDrawSurface3_Initialize, - IDirectDrawSurface3_IsLost, - IDirectDrawSurface3_Lock, - IDirectDrawSurface3_ReleaseDC, - IDirectDrawSurface3_Restore, - IDirectDrawSurface3_SetClipper, - IDirectDrawSurface3_SetColorKey, - (void*)31, - IDirectDrawSurface3_SetPalette, - XShm_IDirectDrawSurface3_Unlock, - (void*)34, - (void*)35, - (void*)36, - (void*)37, - (void*)38, - (void*)39, - (void*)40, -}; - static struct IDirectDrawSurface3_VTable xlib_dds3vt = { IDirectDrawSurface3_QueryInterface, IDirectDrawSurface3_AddRef, @@ -1036,7 +867,7 @@ static struct IDirectDrawClipper_VTable ddclipvt = { * IDirectDrawPalette */ static HRESULT WINAPI IDirectDrawPalette_GetEntries( - LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent + LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent ) { XColor xc; int i; @@ -1045,52 +876,76 @@ static HRESULT WINAPI IDirectDrawPalette_GetEntries( FIXME(ddraw,"app tried to read colormap for non-palettized mode\n"); return DDERR_GENERIC; } - for (i=start;icm,&xc); - palent[i-start].peRed = xc.red>>8; - palent[i-start].peGreen = xc.green>>8; - palent[i-start].peBlue = xc.blue>>8; + palent[i].peRed = xc.red>>8; + palent[i].peGreen = xc.green>>8; + palent[i].peBlue = xc.blue>>8; } return 0; } -static HRESULT WINAPI common_IDirectDrawPalette_SetEntries( - LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent +static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries( + LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent ) { XColor xc; int i; TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", - this,x,start,end,palent + this,x,start,count,palent + ); + if (!this->cm) /* should not happen */ { + FIXME(ddraw,"app tried to set colormap in non-palettized mode\n"); + return DDERR_GENERIC; + } + if (!this->ddraw->e.xlib.paintable) + return 0; + for (i=0;icm,&xc); + this->palents[start+i].peRed = palent[i].peRed; + this->palents[start+i].peBlue = palent[i].peBlue; + this->palents[start+i].peGreen = palent[i].peGreen; + } + return 0; +} + +static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries( + LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent +) { +#ifdef HAVE_LIBXXF86DGA + XColor xc; + Colormap cm; + int i; + + TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", + this,x,start,count,palent ); if (!this->cm) /* should not happen */ { FIXME(ddraw,"app tried to set colormap in non-palettized mode\n"); return DDERR_GENERIC; } /* FIXME: free colorcells instead of freeing whole map */ - /*this->cm = TSXCopyColormapAndFree(display,this->cm);*/ - for (i=start;icm,&xc); - this->palents[i].peRed = palent[i-start].peRed; - this->palents[i].peBlue = palent[i-start].peBlue; - this->palents[i].peGreen = palent[i-start].peGreen; - } - return 0; -} + cm = this->cm; + this->cm = TSXCopyColormapAndFree(display,this->cm); + TSXFreeColormap(display,cm); -static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries( - LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent -) { -#ifdef HAVE_LIBXXF86DGA - HRESULT hres; - hres = common_IDirectDrawPalette_SetEntries(this,x,start,end,palent); - if (hres != 0) return hres; + for (i=0;icm,&xc); + this->palents[start+i].peRed = palent[i].peRed; + this->palents[start+i].peBlue = palent[i].peBlue; + this->palents[start+i].peGreen = palent[i].peGreen; + } TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm); return 0; #else /* defined(HAVE_LIBXXF86DGA) */ @@ -1130,16 +985,6 @@ static struct IDirectDrawPalette_VTable dga_ddpalvt = { DGA_IDirectDrawPalette_SetEntries }; -static struct IDirectDrawPalette_VTable xshm_ddpalvt = { - (void*)1, - IDirectDrawPalette_AddRef, - IDirectDrawPalette_Release, - (void*)4, - IDirectDrawPalette_GetEntries, - IDirectDrawPalette_Initialize, - common_IDirectDrawPalette_SetEntries -}; - static struct IDirectDrawPalette_VTable xlib_ddpalvt = { (void*)1, IDirectDrawPalette_AddRef, @@ -1147,7 +992,7 @@ static struct IDirectDrawPalette_VTable xlib_ddpalvt = { (void*)4, IDirectDrawPalette_GetEntries, IDirectDrawPalette_Initialize, - common_IDirectDrawPalette_SetEntries + Xlib_IDirectDrawPalette_SetEntries }; /******************************************************************************* @@ -1189,7 +1034,7 @@ static HRESULT WINAPI IDirect3D2_EnumDevices( d2.dwSize = sizeof(d2); d2.dwFlags = 0; - cb(&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context); + cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context); return 0; } @@ -1208,8 +1053,8 @@ static struct IDirect3D2_VTable d3d2vt = { /******************************************************************************* * IDirectDraw */ -static HRESULT WINAPI DGA_IDirectDraw_CreateSurface( - LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk +static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface( + LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk ) { #ifdef HAVE_LIBXXF86DGA int i; @@ -1288,50 +1133,8 @@ static HRESULT WINAPI DGA_IDirectDraw_CreateSurface( #endif /* defined(HAVE_LIBXXF86DGA) */ } -static HRESULT WINAPI XShm_IDirectDraw_CreateSurface( - LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk -) { -#ifdef HAVE_LIBXXSHM - XImage *img; - int shmid; - TRACE(ddraw,"(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk); - if (TRACE_ON(ddraw)) { - fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight); - _dump_DDSD(lpddsd->dwFlags); - fprintf(stderr,"caps "); - _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps); - fprintf(stderr,"]\n"); - } - - TRACE(ddraw,"using shared XImage for a primary surface\n"); - *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface)); - this->lpvtbl->fnAddRef(this); - (*lpdsf)->ref = 1; - (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xshm_dds3vt; - (*lpdsf)->t.xshm.image = img = - XShmCreateImage(display, /*FIXME:visual*/0, /*FIXME:depth*/8, ZPixmap, - NULL, &(*lpdsf)->t.xshm.shminfo, - /*FIXME:width*/640, /*FIXME:height*/480); - (*lpdsf)->t.xshm.shminfo.shmid = shmid = - shmget(IPC_PRIVATE, img->bytes_per_line*img->height, IPC_CREAT|0777); - (*lpdsf)->t.xshm.shminfo.shmaddr = img->data = shmat(shmid, 0, 0); - TSXShmAttach(display, &(*lpdsf)->t.xshm.shminfo); - /* POOLE FIXME: XShm: this will easily break */ - (*lpdsf)->s.surface = img->data; - /* END FIXME: XShm */ - (*lpdsf)->s.lpitch = img->bytes_per_line; - (*lpdsf)->s.width = img->width; - (*lpdsf)->s.height = img->height; - (*lpdsf)->s.ddraw = this; - (*lpdsf)->s.backbuffer = NULL; - return 0; -#else /* defined(HAVE_LIBXXSHM) */ - return E_UNEXPECTED; -#endif /* defined(HAVE_LIBXXSHM) */ -} - -static HRESULT WINAPI Xlib_IDirectDraw_CreateSurface( - LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk +static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface( + LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk ) { XImage *img; TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n", @@ -1360,11 +1163,17 @@ static HRESULT WINAPI Xlib_IDirectDraw_CreateSurface( } else { TRACE(ddraw,"using standard XImage for a primary surface\n"); /* FIXME: !8 bit images */ + if (!(lpddsd->dwFlags & DDSD_WIDTH)) + lpddsd->dwWidth = this->d.width; + if (!(lpddsd->dwFlags & DDSD_HEIGHT)) + lpddsd->dwHeight = this->d.height; (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwHeight*lpddsd->dwWidth); - (*lpdsf)->s.width = this->d.width; - (*lpdsf)->s.height = this->d.height; + (*lpdsf)->s.width = lpddsd->dwWidth; + (*lpdsf)->s.height = lpddsd->dwHeight; } (*lpdsf)->s.ddraw = this; + + { (*lpdsf)->t.xlib.image = img = TSXCreateImage( display, DefaultVisualOfScreen(screen), @@ -1379,8 +1188,8 @@ static HRESULT WINAPI Xlib_IDirectDraw_CreateSurface( /* FIXME: !8 bit images */ ); /* END FIXME: Xlib */ + } (*lpdsf)->s.lpitch = img->bytes_per_line; - assert(img); if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { LPDIRECTDRAWSURFACE3 back; @@ -1418,16 +1227,16 @@ static HRESULT WINAPI Xlib_IDirectDraw_CreateSurface( return 0; } -static HRESULT WINAPI IDirectDraw_DuplicateSurface( - LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst +static HRESULT WINAPI IDirectDraw2_DuplicateSurface( + LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst ) { FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst); *dst = src; /* FIXME */ return 0; } -static HRESULT WINAPI IDirectDraw_SetCooperativeLevel( - LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel +static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel( + LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel ) { int i; const struct { @@ -1445,9 +1254,7 @@ static HRESULT WINAPI IDirectDraw_SetCooperativeLevel( FE(DDSCL_CREATEDEVICEWINDOW) }; - TRACE(ddraw,"(%p)->(%08lx,%08lx)\n", - this,(DWORD)hwnd,cooplevel - ); + TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel); if(TRACE_ON(ddraw)){ dbg_decl_str(ddraw, 512); for (i=0;id.mainwindow = hwnd; +/* this->d.mainwindow = hwnd;*/ return 0; } @@ -1493,9 +1300,9 @@ static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode( * it works for the library too? */ TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics); -/* - TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->d.fb_height); - */ +#ifdef DIABLO_HACK + TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height); +#endif #ifdef RESTORE_SIGNALS SIGNAL_InitEmulator(); @@ -1506,44 +1313,6 @@ static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode( #endif /* defined(HAVE_LIBXXF86DGA) */ } -static HRESULT WINAPI XShm_IDirectDraw_SetDisplayMode( - LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth -) { -#ifdef HAVE_LIBXXSHM - int i,*depths,depcount; - char buf[200]; - - TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n", - this, width, height, depth); - - depths = TSXListDepths(display,DefaultScreen(display),&depcount); - for (i=0;id.width < width) { - sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.width); - MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP); - return DDERR_UNSUPPORTEDMODE; - } - this->d.width = width; - this->d.height = height; - /* adjust fb_height, so we don't overlap */ - if (this->e.dga.fb_height < height) - this->e.dga.fb_height = height; - this->d.depth = depth; - /* END FIXME: XShm */ - return 0; -#else /* defined(HAVE_LIBXXSHM) */ - return E_UNEXPECTED; -#endif /* defined(HAVE_LIBXXSHM) */ -} - static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode( LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth ) { @@ -1581,6 +1350,8 @@ static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode( 0, NULL ); + SetWindowLong32A(this->e.xlib.window,0,(LONG)this); + this->e.xlib.paintable = 1; ShowWindow32(this->e.xlib.window,TRUE); UpdateWindow32(this->e.xlib.window); assert(this->e.xlib.window); @@ -1594,8 +1365,8 @@ static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode( return 0; } -static HRESULT WINAPI DGA_IDirectDraw_GetCaps( - LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2 +static HRESULT WINAPI DGA_IDirectDraw2_GetCaps( + LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 ) { #ifdef HAVE_LIBXXF86DGA TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); @@ -1613,29 +1384,8 @@ static HRESULT WINAPI DGA_IDirectDraw_GetCaps( #endif /* defined(HAVE_LIBXXF86DGA) */ } -static HRESULT WINAPI XShm_IDirectDraw_GetCaps( - LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2 -) { -#ifdef HAVE_LIBXXSHM - TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); - /* FIXME: XShm */ - caps1->dwVidMemTotal = 2048*1024; - caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */ - caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ - if (caps2) { - caps2->dwVidMemTotal = 2048*1024; - caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */ - caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ - } - /* END FIXME: XShm */ - return 0; -#else /* defined(HAVE_LIBXXSHM) */ - return E_UNEXPECTED; -#endif /* defined(HAVE_LIBXXSHM) */ -} - -static HRESULT WINAPI Xlib_IDirectDraw_GetCaps( - LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2 +static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps( + LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 ) { TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); /* FIXME: Xlib */ @@ -1651,8 +1401,8 @@ static HRESULT WINAPI Xlib_IDirectDraw_GetCaps( return 0; } -static HRESULT WINAPI IDirectDraw_CreateClipper( - LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk +static HRESULT WINAPI IDirectDraw2_CreateClipper( + LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk ) { FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n", this,x,lpddclip,lpunk @@ -1663,13 +1413,13 @@ static HRESULT WINAPI IDirectDraw_CreateClipper( return 0; } -static HRESULT WINAPI common_IDirectDraw_CreatePalette( - LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk +static HRESULT WINAPI common_IDirectDraw2_CreatePalette( + LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk ) { *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette)); if (*lpddpal == NULL) return E_OUTOFMEMORY; (*lpddpal)->ref = 1; - (*lpddpal)->ddraw = this; + (*lpddpal)->ddraw = (LPDIRECTDRAW)this; (*lpddpal)->installed = 0; if (this->d.depth<=8) { (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll); @@ -1680,43 +1430,32 @@ static HRESULT WINAPI common_IDirectDraw_CreatePalette( return 0; } -static HRESULT WINAPI DGA_IDirectDraw_CreatePalette( - LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk +static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette( + LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk ) { HRESULT res; - TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n", - this,x,palent,lpddpal,lpunk - ); - res = common_IDirectDraw_CreatePalette(this,x,palent,lpddpal,lpunk); + TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk); + res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk); if (res != 0) return res; (*lpddpal)->lpvtbl = &dga_ddpalvt; return 0; } -static HRESULT WINAPI XShm_IDirectDraw_CreatePalette( - LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk -) { - HRESULT res; - TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk); - res = common_IDirectDraw_CreatePalette(this,x,palent,lpddpal,lpunk); - if (res != 0) return res; - (*lpddpal)->lpvtbl = &xshm_ddpalvt; - return 0; -} - -static HRESULT WINAPI Xlib_IDirectDraw_CreatePalette( - LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk +static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette( + LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk ) { TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk); *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette)); if (*lpddpal == NULL) return E_OUTOFMEMORY; (*lpddpal)->ref = 1; (*lpddpal)->installed = 0; - (*lpddpal)->ddraw = this; + (*lpddpal)->ddraw = (LPDIRECTDRAW)this; if (this->d.depth<=8) { (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll); - TSXInstallColormap(display,(*lpddpal)->cm); - TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm); + /* later installed ... + * TSXInstallColormap(display,(*lpddpal)->cm); + * TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm); + */ } else /* we don't want palettes in hicolor or truecolor */ (*lpddpal)->cm = 0; @@ -1724,7 +1463,7 @@ static HRESULT WINAPI Xlib_IDirectDraw_CreatePalette( return 0; } -static HRESULT WINAPI DGA_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) { +static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { #ifdef HAVE_LIBXXF86DGA TRACE(ddraw, "(%p)->()\n",this); Sleep(1000); @@ -1738,33 +1477,24 @@ static HRESULT WINAPI DGA_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) { #endif } -static HRESULT WINAPI XShm_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) { -#ifdef HAVE_LIBXXF86DGA +static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this); Sleep(1000); return 0; -#else /* defined(HAVE_LIBXXF86DGA) */ - return E_UNEXPECTED; -#endif } -static HRESULT WINAPI Xlib_IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) { - TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this); - return 0; -} - -static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank( - LPDIRECTDRAW this,DWORD x,HANDLE32 h +static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank( + LPDIRECTDRAW2 this,DWORD x,HANDLE32 h ) { TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h); return 0; } -static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) { +static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) { return ++(this->ref); } -static ULONG WINAPI DGA_IDirectDraw_Release(LPDIRECTDRAW this) { +static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) { #ifdef HAVE_LIBXXF86DGA if (!--(this->ref)) { TSXF86DGADirectVideo(display,DefaultScreen(display),0); @@ -1778,26 +1508,17 @@ static ULONG WINAPI DGA_IDirectDraw_Release(LPDIRECTDRAW this) { return this->ref; } -static ULONG WINAPI XShm_IDirectDraw_Release(LPDIRECTDRAW this) { -#ifdef HAVE_LIBXXSHM +static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) { if (!--(this->ref)) { HeapFree(GetProcessHeap(),0,this); return 0; } -#endif /* defined(HAVE_LIBXXSHM) */ + /* FIXME: destroy window ... */ return this->ref; } -static ULONG WINAPI Xlib_IDirectDraw_Release(LPDIRECTDRAW this) { - if (!--(this->ref)) { - HeapFree(GetProcessHeap(),0,this); - return 0; - } - return this->ref; -} - -static HRESULT WINAPI DGA_IDirectDraw_QueryInterface( - LPDIRECTDRAW this,REFIID refiid,LPVOID *obj +static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface( + LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj ) { char xrefiid[50]; @@ -1809,12 +1530,13 @@ static HRESULT WINAPI DGA_IDirectDraw_QueryInterface( return 0; } if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { - *obj = this; + this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt; this->lpvtbl->fnAddRef(this); + *obj = this; return 0; } if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { - this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dga_dd2vt; + this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt; this->lpvtbl->fnAddRef(this); *obj = this; return 0; @@ -1824,7 +1546,7 @@ static HRESULT WINAPI DGA_IDirectDraw_QueryInterface( d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; - d3d->ddraw = this; + d3d->ddraw = (LPDIRECTDRAW)this; this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3dvt; *obj = d3d; @@ -1835,7 +1557,7 @@ static HRESULT WINAPI DGA_IDirectDraw_QueryInterface( d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; - d3d->ddraw = this; + d3d->ddraw = (LPDIRECTDRAW)this; this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3d2vt; *obj = d3d; @@ -1845,57 +1567,8 @@ static HRESULT WINAPI DGA_IDirectDraw_QueryInterface( return OLE_E_ENUM_NOMORE; } -static HRESULT WINAPI XShm_IDirectDraw_QueryInterface( - LPDIRECTDRAW this,REFIID refiid,LPVOID *obj - ) { - char xrefiid[50]; - - WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); - TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj); - if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { - *obj = this; - this->lpvtbl->fnAddRef(this); - return 0; - } - if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { - *obj = this; - this->lpvtbl->fnAddRef(this); - return 0; - } - if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { - this->lpvtbl = (LPDIRECTDRAW_VTABLE)&xshm_dd2vt; - this->lpvtbl->fnAddRef(this); - *obj = this; - return 0; - } - if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { - LPDIRECT3D d3d; - - d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); - d3d->ref = 1; - d3d->ddraw = this; - this->lpvtbl->fnAddRef(this); - d3d->lpvtbl = &d3dvt; - *obj = d3d; - return 0; - } - if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { - LPDIRECT3D2 d3d; - - d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); - d3d->ref = 1; - d3d->ddraw = this; - this->lpvtbl->fnAddRef(this); - d3d->lpvtbl = &d3d2vt; - *obj = d3d; - return 0; - } - WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid); - return OLE_E_ENUM_NOMORE; -} - -static HRESULT WINAPI Xlib_IDirectDraw_QueryInterface( - LPDIRECTDRAW this,REFIID refiid,LPVOID *obj +static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface( + LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj ) { char xrefiid[50]; @@ -1907,12 +1580,13 @@ static HRESULT WINAPI Xlib_IDirectDraw_QueryInterface( return 0; } if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { - *obj = this; + this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt; this->lpvtbl->fnAddRef(this); + *obj = this; return 0; } if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { - this->lpvtbl = (LPDIRECTDRAW_VTABLE)&xlib_dd2vt; + this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt; this->lpvtbl->fnAddRef(this); *obj = this; return 0; @@ -1922,7 +1596,7 @@ static HRESULT WINAPI Xlib_IDirectDraw_QueryInterface( d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; - d3d->ddraw = this; + d3d->ddraw = (LPDIRECTDRAW)this; this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3dvt; *obj = d3d; @@ -1933,7 +1607,7 @@ static HRESULT WINAPI Xlib_IDirectDraw_QueryInterface( d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; - d3d->ddraw = this; + d3d->ddraw = (LPDIRECTDRAW)this; this->lpvtbl->fnAddRef(this); d3d->lpvtbl = &d3d2vt; *obj = d3d; @@ -1943,16 +1617,16 @@ static HRESULT WINAPI Xlib_IDirectDraw_QueryInterface( return OLE_E_ENUM_NOMORE; } -static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus( - LPDIRECTDRAW this,BOOL32 *status +static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus( + LPDIRECTDRAW2 this,BOOL32 *status ) { TRACE(ddraw,"(%p)->(%p)\n",this,status); *status = TRUE; return 0; } -static HRESULT WINAPI IDirectDraw_EnumDisplayModes( - LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb +static HRESULT WINAPI IDirectDraw2_EnumDisplayModes( + LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb ) { DDSURFACEDESC ddsfd; @@ -1987,8 +1661,8 @@ static HRESULT WINAPI IDirectDraw_EnumDisplayModes( return DD_OK; } -static HRESULT WINAPI DGA_IDirectDraw_GetDisplayMode( - LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd +static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode( + LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd ) { #ifdef HAVE_LIBXXF86DGA TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd); @@ -2006,29 +1680,8 @@ static HRESULT WINAPI DGA_IDirectDraw_GetDisplayMode( #endif /* defined(HAVE_LIBXXF86DGA) */ } -static HRESULT WINAPI XShm_IDirectDraw_GetDisplayMode( - LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd -) { -#ifdef HAVE_LIBXXSM - TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd); - lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; - lpddsfd->dwHeight = screenHeight; - lpddsfd->dwWidth = screenWidth; - /* POOLE FIXME: XShm */ - lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8; - /* END FIXME: XShm */ - lpddsfd->dwBackBufferCount = 1; - lpddsfd->x.dwRefreshRate = 60; - lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; - _getpixelformat(this,&(lpddsfd->ddpfPixelFormat)); - return DD_OK; -#else /* defined(HAVE_LIBXXSHM) */ - return E_UNEXPECTED; -#endif /* defined(HAVE_LIBXXSHM) */ -} - -static HRESULT WINAPI Xlib_IDirectDraw_GetDisplayMode( - LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd +static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode( + LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd ) { TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd); lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; @@ -2044,13 +1697,13 @@ static HRESULT WINAPI Xlib_IDirectDraw_GetDisplayMode( return DD_OK; } -static HRESULT WINAPI IDirectDraw_FlipToGDISurface(LPDIRECTDRAW this) { +static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) { TRACE(ddraw,"(%p)->()\n",this); return DD_OK; } -static HRESULT WINAPI IDirectDraw_GetMonitorFrequency( - LPDIRECTDRAW this,LPDWORD freq +static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency( + LPDIRECTDRAW2 this,LPDWORD freq ) { FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq); *freq = 60*100; /* 60 Hz */ @@ -2058,225 +1711,13 @@ static HRESULT WINAPI IDirectDraw_GetMonitorFrequency( } /* what can we directly decompress? */ -static HRESULT WINAPI IDirectDraw_GetFourCCCodes( - LPDIRECTDRAW this,LPDWORD x,LPDWORD y +static HRESULT WINAPI IDirectDraw2_GetFourCCCodes( + LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y ) { FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y); return 0; } -static struct IDirectDraw_VTable dga_ddvt = { - DGA_IDirectDraw_QueryInterface, - IDirectDraw_AddRef, - DGA_IDirectDraw_Release, - (void*)4, - IDirectDraw_CreateClipper, - DGA_IDirectDraw_CreatePalette, - DGA_IDirectDraw_CreateSurface, - IDirectDraw_DuplicateSurface, - IDirectDraw_EnumDisplayModes, - (void*)10, - IDirectDraw_FlipToGDISurface, - DGA_IDirectDraw_GetCaps, - DGA_IDirectDraw_GetDisplayMode, - IDirectDraw_GetFourCCCodes, - (void*)15, - IDirectDraw_GetMonitorFrequency, - (void*)17, - IDirectDraw_GetVerticalBlankStatus, - (void*)19, - DGA_IDirectDraw_RestoreDisplayMode, - IDirectDraw_SetCooperativeLevel, - DGA_IDirectDraw_SetDisplayMode, - IDirectDraw_WaitForVerticalBlank, -}; - -static struct IDirectDraw_VTable xshm_ddvt = { - XShm_IDirectDraw_QueryInterface, - IDirectDraw_AddRef, - XShm_IDirectDraw_Release, - (void*)4, - IDirectDraw_CreateClipper, - XShm_IDirectDraw_CreatePalette, - XShm_IDirectDraw_CreateSurface, - IDirectDraw_DuplicateSurface, - IDirectDraw_EnumDisplayModes, - (void*)10, - IDirectDraw_FlipToGDISurface, - XShm_IDirectDraw_GetCaps, - XShm_IDirectDraw_GetDisplayMode, - IDirectDraw_GetFourCCCodes, - (void*)15, - IDirectDraw_GetMonitorFrequency, - (void*)17, - IDirectDraw_GetVerticalBlankStatus, - (void*)19, - XShm_IDirectDraw_RestoreDisplayMode, - IDirectDraw_SetCooperativeLevel, - XShm_IDirectDraw_SetDisplayMode, - IDirectDraw_WaitForVerticalBlank, -}; - -static struct IDirectDraw_VTable xlib_ddvt = { - Xlib_IDirectDraw_QueryInterface, - IDirectDraw_AddRef, - Xlib_IDirectDraw_Release, - (void*)4, - IDirectDraw_CreateClipper, - Xlib_IDirectDraw_CreatePalette, - Xlib_IDirectDraw_CreateSurface, - IDirectDraw_DuplicateSurface, - IDirectDraw_EnumDisplayModes, - (void*)10, - IDirectDraw_FlipToGDISurface, - Xlib_IDirectDraw_GetCaps, - Xlib_IDirectDraw_GetDisplayMode, - IDirectDraw_GetFourCCCodes, - (void*)15, - IDirectDraw_GetMonitorFrequency, - (void*)17, - IDirectDraw_GetVerticalBlankStatus, - (void*)19, - Xlib_IDirectDraw_RestoreDisplayMode, - IDirectDraw_SetCooperativeLevel, - Xlib_IDirectDraw_SetDisplayMode, - IDirectDraw_WaitForVerticalBlank, -}; - -/***************************************************************************** - * IDirectDraw2 - * - */ -static HRESULT WINAPI IDirectDraw2_CreateClipper( - LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk -) { - return IDirectDraw_CreateClipper((LPDIRECTDRAW)this,x,lpddclip,lpunk); -} - -static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface( - LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk -) { - return DGA_IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk); -} - -static HRESULT WINAPI XShm_IDirectDraw2_CreateSurface( - LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk -) { - return XShm_IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface( - LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk -) { - return Xlib_IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk); -} - -static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface( - LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj -) { - return DGA_IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj); -} - -static HRESULT WINAPI XShm_IDirectDraw2_QueryInterface( - LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj -) { - return XShm_IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface( - LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj -) { - return Xlib_IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj); -} - -static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) { - return IDirectDraw_AddRef((LPDIRECTDRAW)this); -} - -static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) { - return DGA_IDirectDraw_Release((LPDIRECTDRAW)this); -} - -static ULONG WINAPI XShm_IDirectDraw2_Release(LPDIRECTDRAW2 this) { - return XShm_IDirectDraw_Release((LPDIRECTDRAW)this); -} - -static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) { - return Xlib_IDirectDraw_Release((LPDIRECTDRAW)this); -} - -static HRESULT WINAPI DGA_IDirectDraw2_GetCaps( - LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 -) { - return DGA_IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2); -} - -static HRESULT WINAPI XShm_IDirectDraw2_GetCaps( - LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 -) { - return XShm_IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps( - LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 -) { - return Xlib_IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2); -} - -static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel( - LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x -) { - return IDirectDraw_SetCooperativeLevel((LPDIRECTDRAW)this,hwnd,x); -} - -static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette( - LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk -) { - return DGA_IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk); -} - -static HRESULT WINAPI XShm_IDirectDraw2_CreatePalette( - LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk -) { - return XShm_IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette( - LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk -) { - return Xlib_IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk); -} - -static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode( - LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy -) { - return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); -} - -static HRESULT WINAPI XShm_IDirectDraw2_SetDisplayMode( - LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy -) { - return XShm_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode( - LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy -) { - return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); -} - -static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { - return DGA_IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this); -} - -static HRESULT WINAPI XShm_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { - return XShm_IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { - return Xlib_IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this); -} - static HRESULT WINAPI IDirectDraw2_EnumSurfaces( LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb ) { @@ -2284,28 +1725,80 @@ static HRESULT WINAPI IDirectDraw2_EnumSurfaces( return 0; } -static HRESULT WINAPI IDirectDraw2_EnumDisplayModes( - LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb +/* Note: Hack so we can reuse the old functions without compiler warnings */ +#ifdef __GNUC__ +# define XCAST(fun) (typeof(dga_ddvt.fn##fun)) +#else +# define XCAST(fun) (void*) +#endif + +static struct IDirectDraw_VTable dga_ddvt = { + XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface, + XCAST(AddRef)IDirectDraw2_AddRef, + XCAST(Release)DGA_IDirectDraw2_Release, + XCAST(Compact)4, + XCAST(CreateClipper)IDirectDraw2_CreateClipper, + XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette, + XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface, + XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface, + XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes, + XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces, + XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface, + XCAST(GetCaps)DGA_IDirectDraw2_GetCaps, + XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode, + XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes, + XCAST(GetGDISurface)15, + XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, + XCAST(GetScanLine)17, + XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, + XCAST(Initialize)19, + XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode, + XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, + DGA_IDirectDraw_SetDisplayMode, + XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, +}; + +static struct IDirectDraw_VTable xlib_ddvt = { + XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface, + XCAST(AddRef)IDirectDraw2_AddRef, + XCAST(Release)Xlib_IDirectDraw2_Release, + XCAST(Compact)4, + XCAST(CreateClipper)IDirectDraw2_CreateClipper, + XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette, + XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface, + XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface, + XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes, + XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces, + XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface, + XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps, + XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode, + XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes, + XCAST(GetGDISurface)15, + XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, + XCAST(GetScanLine)17, + XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, + XCAST(Initialize)19, + XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode, + XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, + Xlib_IDirectDraw_SetDisplayMode, + XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, +}; + +/***************************************************************************** + * IDirectDraw2 + * + */ + +static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode( + LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy ) { - return IDirectDraw_EnumDisplayModes((LPDIRECTDRAW)this,dwFlags,lpddsfd,context,modescb); + return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); } -static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode( - LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd +static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode( + LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy ) { - return DGA_IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd); -} - -static HRESULT WINAPI XShm_IDirectDraw2_GetDisplayMode( - LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd -) { - return XShm_IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd); -} - -static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode( - LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd -) { - return Xlib_IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd); + return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); } static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem( @@ -2330,24 +1823,6 @@ static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem( return 0; } -static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency( - LPDIRECTDRAW2 this,LPDWORD freq -) { - return IDirectDraw_GetMonitorFrequency((LPDIRECTDRAW)this,freq); -} - -static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus( - LPDIRECTDRAW2 this,BOOL32 *status -) { - return IDirectDraw_GetVerticalBlankStatus((LPDIRECTDRAW)this,status); -} - -static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank( - LPDIRECTDRAW2 this,DWORD x,HANDLE32 h -) { - return IDirectDraw_WaitForVerticalBlank((LPDIRECTDRAW)this,x,h); -} - static IDirectDraw2_VTable dga_dd2vt = { DGA_IDirectDraw2_QueryInterface, IDirectDraw2_AddRef, @@ -2359,10 +1834,10 @@ static IDirectDraw2_VTable dga_dd2vt = { (void*)8, IDirectDraw2_EnumDisplayModes, IDirectDraw2_EnumSurfaces, - (void*)11, + IDirectDraw2_FlipToGDISurface, DGA_IDirectDraw2_GetCaps, DGA_IDirectDraw2_GetDisplayMode, - (void*)14, + IDirectDraw2_GetFourCCCodes, (void*)15, IDirectDraw2_GetMonitorFrequency, (void*)17, @@ -2375,33 +1850,6 @@ static IDirectDraw2_VTable dga_dd2vt = { DGA_IDirectDraw2_GetAvailableVidMem }; -static IDirectDraw2_VTable xshm_dd2vt = { - XShm_IDirectDraw2_QueryInterface, - IDirectDraw2_AddRef, - XShm_IDirectDraw2_Release, - (void*)4, - IDirectDraw2_CreateClipper, - XShm_IDirectDraw2_CreatePalette, - XShm_IDirectDraw2_CreateSurface, - (void*)8, - IDirectDraw2_EnumDisplayModes, - IDirectDraw2_EnumSurfaces, - (void*)11, - XShm_IDirectDraw2_GetCaps, - XShm_IDirectDraw2_GetDisplayMode, - (void*)14, - (void*)15, - IDirectDraw2_GetMonitorFrequency, - (void*)17, - IDirectDraw2_GetVerticalBlankStatus, - (void*)19, - XShm_IDirectDraw2_RestoreDisplayMode, - IDirectDraw2_SetCooperativeLevel, - XShm_IDirectDraw2_SetDisplayMode, - IDirectDraw2_WaitForVerticalBlank, - Xlib_IDirectDraw2_GetAvailableVidMem -}; - static struct IDirectDraw2_VTable xlib_dd2vt = { Xlib_IDirectDraw2_QueryInterface, IDirectDraw2_AddRef, @@ -2413,10 +1861,10 @@ static struct IDirectDraw2_VTable xlib_dd2vt = { (void*)8, IDirectDraw2_EnumDisplayModes, IDirectDraw2_EnumSurfaces, - (void*)11, + IDirectDraw2_FlipToGDISurface, Xlib_IDirectDraw2_GetCaps, Xlib_IDirectDraw2_GetDisplayMode, - (void*)14, + IDirectDraw2_GetFourCCCodes, (void*)15, IDirectDraw2_GetMonitorFrequency, (void*)17, @@ -2468,7 +1916,11 @@ HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height); TSXF86DGASetViewPort(display,DefaultScreen(display),0,0); (*lplpDD)->e.dga.fb_height = screenHeight; +#ifdef DIABLO_HACK + (*lplpDD)->e.dga.vpmask = 1; +#else (*lplpDD)->e.dga.vpmask = 0; +#endif /* just assume the default depth is the DGA depth too */ (*lplpDD)->d.depth = DefaultDepthOfScreen(screen); @@ -2481,38 +1933,28 @@ HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) #endif /* defined(HAVE_LIBXXF86DGA) */ } -HRESULT WINAPI XShm_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) { -#ifdef HAVE_LIBXXSHM - if (!DDRAW_XShm_Available()) { - fprintf(stderr,"No XShm detected.\n"); - return DDERR_GENERIC; - } - *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw)); - (*lplpDD)->lpvtbl = &xshm_ddvt; - (*lplpDD)->ref = 1; - (*lplpDD)->e.xshm.drawable = DefaultRootWindow(display); /* FIXME: make a window */ - (*lplpDD)->d.depth = DefaultDepthOfScreen(screen); - (*lplpDD)->d.height = screenHeight; - (*lplpDD)->d.width = screenWidth; - return 0; -#else /* defined(HAVE_LIBXXSHM) */ - return DDERR_INVALIDDIRECTDRAWGUID; -#endif /* defined(HAVE_LIBXXSHM) */ -} LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam) { LRESULT ret; /*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */ + if (msg==WM_PAINT){ + LPDIRECTDRAW ddraw = (LPDIRECTDRAW)GetWindowLong32A(hwnd,0); + + if (ddraw) + ddraw->e.xlib.paintable = 1; + } ret = DefWindowProc32A(hwnd,msg,wParam,lParam); return ret; } HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) { WNDCLASS32A wc; + int have_xshm = 0; *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw)); (*lplpDD)->lpvtbl = &xlib_ddvt; (*lplpDD)->ref = 1; (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */ + (*lplpDD)->e.xlib.use_xshm = have_xshm; wc.style = CS_GLOBALCLASS; wc.lpfnWndProc = Xlib_DDWndProc; wc.cbClsExtra = 0; @@ -2549,16 +1991,12 @@ HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN * supported one */ if (DDRAW_DGA_Available()) lpGUID = &DGA_DirectDraw_GUID; - else if (DDRAW_XShm_Available()) - lpGUID = &XSHM_DirectDraw_GUID; else lpGUID = &XLIB_DirectDraw_GUID; } if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID))) return DGA_DirectDrawCreate(lplpDD, pUnkOuter); - else if (!memcmp(lpGUID, &XSHM_DirectDraw_GUID, sizeof(GUID))) - return XShm_DirectDrawCreate(lplpDD, pUnkOuter); else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID))) return Xlib_DirectDrawCreate(lplpDD, pUnkOuter); diff --git a/graphics/painting.c b/graphics/painting.c index 6797fccd348..57b3316c787 100644 --- a/graphics/painting.c +++ b/graphics/painting.c @@ -755,8 +755,8 @@ BOOL32 WINAPI PolyPolygon32( HDC32 hdc, LPPOINT32 pt, LPINT32 counts, /********************************************************************** * PolyPolyline32 (GDI32.272) */ -BOOL32 WINAPI PolyPolyline32( HDC32 hdc, LPPOINT32 pt, LPINT32 counts, - UINT32 polylines ) +BOOL32 WINAPI PolyPolyline32( HDC32 hdc, LPPOINT32 pt, LPDWORD counts, + DWORD polylines ) { DC * dc = DC_GetDCPtr( hdc ); diff --git a/graphics/psdrv/driver.c b/graphics/psdrv/driver.c index ead31bb7443..ee62d63fa0e 100644 --- a/graphics/psdrv/driver.c +++ b/graphics/psdrv/driver.c @@ -44,8 +44,10 @@ void PSDRV_MergeDevmodes(PSDRV_DEVMODE16 *dm1, PSDRV_DEVMODE16 *dm2, } if(page) { dm1->dmPublic.dmPaperSize = dm2->dmPublic.dmPaperSize; - dm1->dmPublic.dmPaperWidth = page->PaperDimension->x * 25.4 / 72.0; - dm1->dmPublic.dmPaperLength = page->PaperDimension->y * 25.4 / 72.0; + dm1->dmPublic.dmPaperWidth = page->PaperDimension->x * + 254.0 / 72.0; + dm1->dmPublic.dmPaperLength = page->PaperDimension->y * + 254.0 / 72.0; TRACE(psdrv, "Changing page to %s %d x %d\n", page->FullName, dm1->dmPublic.dmPaperWidth, dm1->dmPublic.dmPaperLength ); } else { diff --git a/graphics/psdrv/init.c b/graphics/psdrv/init.c index 3195200de44..6a62a5a3a90 100644 --- a/graphics/psdrv/init.c +++ b/graphics/psdrv/init.c @@ -169,6 +169,12 @@ static PSDRV_DEVMODE16 DefaultDevmode = HANDLE32 PSDRV_Heap = 0; +static HANDLE32 PSDRV_DefaultFont = 0; +static LOGFONT32A DefaultLogFont = { + 100, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, + DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" +}; + /********************************************************************* * PSDRV_Init * @@ -180,6 +186,7 @@ BOOL32 PSDRV_Init(void) TRACE(psdrv, "\n"); PSDRV_Heap = HeapCreate(0, 0x10000, 0); PSDRV_GetFontMetrics(); + PSDRV_DefaultFont = CreateFontIndirect32A(&DefaultLogFont); return DRIVER_RegisterDriver( "WINEPS", &PSDRV_Funcs ); } @@ -225,11 +232,11 @@ static BOOL32 PSDRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, memcpy(devCaps, &PSDRV_DevCaps, sizeof(PSDRV_DevCaps)); if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_PORTRAIT) { - devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperWidth; - devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperLength; + devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperWidth / 10; + devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperLength / 10; } else { - devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperLength; - devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperWidth; + devCaps->horzSize = physDev->Devmode->dmPublic.dmPaperLength / 10; + devCaps->vertSize = physDev->Devmode->dmPublic.dmPaperWidth / 10; } devCaps->horzRes = physDev->pi->ppd->DefaultResolution * @@ -252,6 +259,7 @@ static BOOL32 PSDRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, dc->w.hVisRgn = CreateRectRgn32(0, 0, dc->w.devCaps->horzRes, dc->w.devCaps->vertRes); + dc->w.hFont = PSDRV_DefaultFont; physDev->job.output = HEAP_strdupA( PSDRV_Heap, 0, output ); physDev->job.hJob = 0; return TRUE; diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c index ef1cf1c4da0..3e5f189572d 100644 --- a/graphics/x11drv/graphics.c +++ b/graphics/x11drv/graphics.c @@ -753,7 +753,7 @@ X11DRV_PolyPolygon( DC *dc, LPPOINT32 pt, LPINT32 counts, UINT32 polygons) * X11DRV_PolyPolyline */ BOOL32 -X11DRV_PolyPolyline( DC *dc, LPPOINT32 pt, LPINT32 counts, UINT32 polylines ) +X11DRV_PolyPolyline( DC *dc, LPPOINT32 pt, LPDWORD counts, DWORD polylines ) { if (DC_SetupGCForPen ( dc )) { diff --git a/if1632/gdi.spec b/if1632/gdi.spec index d0a7ef17912..8fdcc887f0c 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -218,7 +218,7 @@ file gdi.exe 305 stub ENGINEGETGLYPHBMP 306 stub ENGINEMAKEFONTDIR 307 pascal16 GetCharABCWidths(word word word ptr) GetCharABCWidths16 -308 pascal GetOutlineTextMetrics(word word ptr) GetOutlineTextMetrics +308 pascal GetOutlineTextMetrics(word word ptr) GetOutlineTextMetrics16 309 pascal GetGlyphOutline(word word word ptr long ptr ptr) GetGlyphOutline16 310 pascal16 CreateScalableFontResource(word str str str) CreateScalableFontResource16 311 stub GetFontData diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec index 354c5afa260..50e996087ed 100644 --- a/if1632/keyboard.spec +++ b/if1632/keyboard.spec @@ -8,7 +8,7 @@ type win16 5 pascal16 AnsiToOem(str ptr) AnsiToOem16 6 pascal16 OemToAnsi(str ptr) OemToAnsi16 7 return SetSpeed 2 65535 -#100 pascal ScreenSwitchEnable +100 pascal ScreenSwitchEnable(word) ScreenSwitchEnable #126 pascal GetTableSeg #127 pascal NewTable 128 pascal OemKeyScan(word) OemKeyScan diff --git a/if1632/relay.c b/if1632/relay.c index ca9f6bb85c9..2d5e33e0574 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -236,7 +236,7 @@ void RELAY_Unimplemented16(void) MSG("No handler for Win16 routine %s (called from %04x:%04x)\n", BUILTIN_GetEntryPoint16(frame->entry_cs,frame->entry_ip,&ordinal), frame->cs, frame->ip ); - TASK_KillCurrentTask(1); + ExitProcess(1); } diff --git a/if1632/user.spec b/if1632/user.spec index 299977b20b0..3c925a42af2 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -368,7 +368,7 @@ file user.exe 398 pascal16 GetClassInfoEx(word segstr ptr) GetClassInfoEx16 399 stub ChildWindowFromPointEx 400 stub FinalUserInit -402 pascal16 GetPriorityClipboardFormat(word ptr s_word) GetPriorityClipboardFormat16 +402 pascal16 GetPriorityClipboardFormat(ptr s_word) GetPriorityClipboardFormat16 403 pascal16 UnregisterClass(segstr word) UnregisterClass16 404 pascal16 GetClassInfo(word segstr ptr) GetClassInfo16 406 pascal16 CreateCursor(word word word word word ptr ptr) CreateCursor16 diff --git a/include/authors.h b/include/authors.h new file mode 100644 index 00000000000..2cfc70b26a6 --- /dev/null +++ b/include/authors.h @@ -0,0 +1,147 @@ +#ifndef __WINE_AUTHORS_H +#define __WINE_AUTHORS_H + +static const char * const SHELL_People[] = +{ + "Bob Amstadt", + "Dag Asheim", + "Martin Ayotte", + "Karl Backström", + "Peter Bajusz", + "Marcel Baur", + "Georg Beyerle", + "Ross Biro", + "Martin Boehme", + "Uwe Bonnes", + "Erik Bos", + "Fons Botman", + "John Brezak", + "Andrew Bulhak", + "John Burton", + "Niels de Carpentier", + "Gordon Chaffee", + "Jimen Ching", + "Pascal Cuoq", + "David A. Cuthbert", + "Huw D. M. Davies", + "Roman Dolejsi", + "Frans van Dorsselaer", + "Chris Faherty", + "Carsten Fallesen", + "Paul Falstad", + "David Faure", + "Claus Fischer", + "Olaf Flebbe", + "Chad Fraleigh", + "Matthew Francis", + "Peter Galbavy", + "Ramon Garcia", + "Matthew Ghio", + "Jody Goldberg", + "Hans de Graaff", + "Charles M. Hannum", + "Adrian Harvey", + "John Harvey", + "Bill Hawes", + "Cameron Heide", + "Jochen Hoenicke", + "Onno Hovers", + "Jeffrey Hsu", + "Miguel de Icaza", + "Jukka Iivonen", + "Lee Jaekil", + "Alexandre Julliard", + "Bang Jun-Young", + "Pavel Kankovsky", + "Jochen Karrer", + "Andreas Kirschbaum", + "Rein Klazes", + "Albrecht Kleine", + "Eric Kohl", + "Jon Konrath", + "Alex Korobka", + "Greg Kreider", + "Anand Kumria", + "Ove Kåven", + "Scott A. Laird", + "David Lee Lambert", + "Andrew Lewycky", + "Per Lindström", + "Martin von Loewis", + "Michiel van Loon", + "Kenneth MacDonald", + "Peter MacDonald", + "William Magro", + "Juergen Marquardt", + "Ricardo Massaro", + "Marcus Meissner", + "Graham Menhennitt", + "David Metcalfe", + "Bruce Milner", + "Steffen Moeller", + "Andreas Mohr", + "James Moody", + "Philippe De Muyter", + "Itai Nahshon", + "Kristian Nielsen", + "Henrik Olsen", + "Michael Patra", + "Dimitrie O. Paun", + "Jim Peterson", + "Robert Pouliot", + "Keith Reynolds", + "Slaven Rezic", + "John Richardson", + "Rick Richardson", + "Doug Ridgway", + "Bernhard Rosenkraenzer", + "Johannes Ruscheinski", + "Thomas Sandford", + "Constantine Sapuntzakis", + "Pablo Saratxaga", + "Daniel Schepler", + "Peter Schlaile", + "Ulrich Schmid", + "Bernd Schmidt", + "Juergen Schmied", + "Ingo Schneider", + "Victor Schneider", + "Yngvi Sigurjonsson", + "Stephen Simmons", + "Rick Sladkey", + "William Smith", + "Dominik Strasser", + "Vadim Strizhevsky", + "Bertho Stultiens", + "Erik Svendsen", + "Tristan Tarrant", + "Andrew Taylor", + "Duncan C Thomson", + "Goran Thyni", + "Jimmy Tirtawangsa", + "Jon Tombs", + "Linus Torvalds", + "Gregory Trubetskoy", + "Petri Tuomola", + "Michael Veksler", + "Sven Verdoolaege", + "Ronan Waide", + "Eric Warnke", + "Manfred Weichel", + "Ulrich Weigand", + "Morten Welinder", + "Len White", + "Lawson Whitney", + "Jan Willamowius", + "Carl Williams", + "Karl Guenter Wuensch", + "Eric Youngdale", + "James Youngman", + "Nikita V. Youshchenko", + "Mikolaj Zalewski", + "John Zero", + "Luiz Otavio L. Zorzella", + NULL +}; + +#endif /* __WINE_AUTHORS_H */ diff --git a/include/commctrl.h b/include/commctrl.h index 04f29ff6cbb..3284c98664e 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -55,14 +55,64 @@ BOOL32 WINAPI InitCommonControlsEx (LPINITCOMMONCONTROLSEX); #define CCM_FIRST 0x2000 #define CCM_SETBKCOLOR (CCM_FIRST+1) /* lParam = bkColor */ - +#define CCM_SETCOLORSCHEME (CCM_FIRST+2) +#define CCM_GETCOLORSCHEME (CCM_FIRST+3) +#define CCM_GETDROPTARGET (CCM_FIRST+4) #define CCM_SETUNICODEFORMAT (CCM_FIRST+5) #define CCM_GETUNICODEFORMAT (CCM_FIRST+6) -/* common notification codes */ -#define NM_FIRST (0U-0U) -#define NM_LAST (0U-99U) +/* common notification codes (WM_NOTIFY)*/ +#define NM_FIRST (0U- 0U) // generic to all controls +#define NM_LAST (0U- 99U) + +#define LVN_FIRST (0U-100U) // listview +#define LVN_LAST (0U-199U) + +#define HDN_FIRST (0U-300U) // header +#define HDN_LAST (0U-399U) + +#define TVN_FIRST (0U-400U) // treeview +#define TVN_LAST (0U-499U) + +#define TTN_FIRST (0U-520U) // tooltips +#define TTN_LAST (0U-549U) + +#define TCN_FIRST (0U-550U) // tab control +#define TCN_LAST (0U-580U) + +// Shell reserved (0U-580U) - (0U-589U) + +#define CDN_FIRST (0U-601U) // common dialog (new) +#define CDN_LAST (0U-699U) + +#define TBN_FIRST (0U-700U) // toolbar +#define TBN_LAST (0U-720U) + +#define UDN_FIRST (0U-721) // updown +#define UDN_LAST (0U-740) + +#define MCN_FIRST (0U-750U) // monthcal +#define MCN_LAST (0U-759U) + +#define DTN_FIRST (0U-760U) // datetimepick +#define DTN_LAST (0U-799U) + +#define CBEN_FIRST (0U-800U) // combo box ex +#define CBEN_LAST (0U-830U) + +#define RBN_FIRST (0U-831U) // rebar +#define RBN_LAST (0U-859U) + +#define IPN_FIRST (0U-860U) // internet address +#define IPN_LAST (0U-879U) // internet address + +#define SBN_FIRST (0U-880U) // status bar +#define SBN_LAST (0U-899U) + +#define PGN_FIRST (0U-900U) // Pager Control +#define PGN_LAST (0U-950U) + #define NM_OUTOFMEMORY (NM_FIRST-1) #define NM_CLICK (NM_FIRST-2) @@ -81,6 +131,66 @@ BOOL32 WINAPI InitCommonControlsEx (LPINITCOMMONCONTROLSEX); #define NM_CHAR (NM_FIRST-18) #define NM_TOOLTIPSCREATED (NM_FIRST-19) +#define HDN_ITEMCHANGINGA (HDN_FIRST-0) +#define HDN_ITEMCHANGINGW (HDN_FIRST-20) +#define HDN_ITEMCHANGEDA (HDN_FIRST-1) +#define HDN_ITEMCHANGEDW (HDN_FIRST-21) +#define HDN_ITEMCLICKA (HDN_FIRST-2) +#define HDN_ITEMCLICKW (HDN_FIRST-22) +#define HDN_ITEMDBLCLICKA (HDN_FIRST-3) +#define HDN_ITEMDBLCLICKW (HDN_FIRST-23) +#define HDN_DIVIDERDBLCLICKA (HDN_FIRST-5) +#define HDN_DIVIDERDBLCLICKW (HDN_FIRST-25) +#define HDN_BEGINTRACKA (HDN_FIRST-6) +#define HDN_BEGINTRACKW (HDN_FIRST-26) +#define HDN_ENDTRACKA (HDN_FIRST-7) +#define HDN_ENDTRACKW (HDN_FIRST-27) +#define HDN_TRACKA (HDN_FIRST-8) +#define HDN_TRACKW (HDN_FIRST-28) +#define HDN_GETDISPINFOA (HDN_FIRST-9) +#define HDN_GETDISPINFOW (HDN_FIRST-29) +#define HDN_BEGINDRAG (HDN_FIRST-10) +#define HDN_ENDDRAG (HDN_FIRST-11) + + +#define HDN_ITEMCHANGING HDN_ITEMCHANGINGA +#define HDN_ITEMCHANGED HDN_ITEMCHANGEDA +#define HDN_ITEMCLICK HDN_ITEMCLICKA +#define HDN_ITEMDBLCLICK HDN_ITEMDBLCLICKA +#define HDN_DIVIDERDBLCLICK HDN_DIVIDERDBLCLICKA +#define HDN_BEGINTRACK HDN_BEGINTRACKA +#define HDN_ENDTRACK HDN_ENDTRACKA +#define HDN_TRACK HDN_TRACKA +#define HDN_GETDISPINFO HDN_GETDISPINFOA + +#define LVN_ITEMCHANGING (LVN_FIRST-0) +#define LVN_ITEMCHANGED (LVN_FIRST-1) +#define LVN_INSERTITEM (LVN_FIRST-2) +#define LVN_DELETEITEM (LVN_FIRST-3) +#define LVN_DELETEALLITEMS (LVN_FIRST-4) +#define LVN_BEGINLABELEDITA (LVN_FIRST-5) +#define LVN_BEGINLABELEDITW (LVN_FIRST-75) +#define LVN_ENDLABELEDITA (LVN_FIRST-6) +#define LVN_ENDLABELEDITW (LVN_FIRST-76) +#define LVN_COLUMNCLICK (LVN_FIRST-8) +#define LVN_BEGINDRAG (LVN_FIRST-9) +#define LVN_BEGINRDRAG (LVN_FIRST-11) +#define LVN_ODCACHEHINT (LVN_FIRST-13) +#define LVN_ODFINDITEMA (LVN_FIRST-52) +#define LVN_ODFINDITEMW (LVN_FIRST-79) +#define LVN_ITEMACTIVATE (LVN_FIRST-14) +#define LVN_ODSTATECHANGED (LVN_FIRST-15) +#define LVN_HOTTRACK (LVN_FIRST-21) +#define LVN_GETDISPINFOA (LVN_FIRST-50) +#define LVN_GETDISPINFOW (LVN_FIRST-77) +#define LVN_SETDISPINFOA (LVN_FIRST-51) +#define LVN_SETDISPINFOW (LVN_FIRST-78) + +#define LVN_ODFINDITEM LVN_ODFINDITEMA +#define LVN_BEGINLABELEDIT LVN_BEGINLABELEDITA +#define LVN_ENDLABELEDIT LVN_ENDLABELEDITA +#define LVN_GETDISPINFO LVN_GETDISPINFOA +#define LVN_SETDISPINFO LVN_SETDISPINFOA /* callback constants */ #define LPSTR_TEXTCALLBACK32A ((LPSTR)-1L) @@ -952,6 +1062,103 @@ typedef struct tagNMTTDISPINFOW #define REBARCLASSNAME32W L"ReBarWindow32" #define REBARCLASSNAME WINELIB_NAME_AW(REBARCLASSNAME) +#define RBIM_IMAGELIST 0x00000001 + +#define RBBIM_STYLE 0x00000001 +#define RBBIM_COLORS 0x00000002 +#define RBBIM_TEXT 0x00000004 +#define RBBIM_IMAGE 0x00000008 +#define RBBIM_CHILD 0x00000010 +#define RBBIM_CHILDSIZE 0x00000020 +#define RBBIM_SIZE 0x00000040 +#define RBBIM_BACKGROUND 0x00000080 +#define RBBIM_ID 0x00000100 +#define RBBIM_IDEALSIZE 0x00000200 +#define RBBIM_LPARAM 0x00000400 +#define RBBIM_HEADERSIZE 0x00000800 + + +#define RB_INSERTBAND32A (WM_USER+1) +#define RB_INSERTBAND32W (WM_USER+10) +#define RB_INSERTBANND WINELIB_NAME_AW(RB_INSERTBAND) +#define RB_DELETEBAND (WM_USER+2) +#define RB_GETBARINFO (WM_USER+3) +#define RB_SETBARINFO (WM_USER+4) +#define RB_GETBANDINFO32 (WM_USER+5) /* just for compatibility */ +#define RB_SETBANDINFO32A (WM_USER+6) +#define RB_SETBANDINFO32W (WM_USER+11) +#define RB_SETBANDINFO WINELIB_NAME_AW(RB_SETBANDINFO) +#define RB_SETPARENT (WM_USER+7) +#define RB_HITTEST (WM_USER+8) +#define RB_GETRECT (WM_USER+9) +#define RB_GETBANDCOUNT (WM_USER+12) +#define RB_GETROWCOUNT (WM_USER+13) +#define RB_GETROWHEIGHT (WM_USER+14) +#define RB_IDTOINDEX (WM_USER+16) +#define RB_GETTOOLTIPS (WM_USER+17) +#define RB_SETTOOLTIPS (WM_USER+18) +#define RB_SETBKCOLOR (WM_USER+19) +#define RB_GETBKCOLOR (WM_USER+20) +#define RB_SETTEXTCOLOR (WM_USER+21) +#define RB_GETTEXTCOLOR (WM_USER+22) +#define RB_SIZETORECT (WM_USER+23) +#define RB_BEGINDRAG (WM_USER+24) +#define RB_ENDDRAG (WM_USER+25) +#define RB_DRAGMOVE (WM_USER+26) +#define RB_GETBARHEIGHT (WM_USER+27) +#define RB_GETBANDINFO32W (WM_USER+28) +#define RB_GETBANDINFO32A (WM_USER+29) +#define RB_GETBANDINFO WINELIB_NAME_AW(RB_GETBANDINFO) +#define RB_MINIMIZEBAND (WM_USER+30) +#define RB_MAXIMIZEBAND (WM_USER+31) + +#define RB_GETBANDORDERS (WM_USER+34) +#define RB_SHOWBAND (WM_USER+35) + +#define RB_SETPALETTE (WM_USER+37) +#define RB_GETPALETTE (WM_USER+38) +#define RB_MOVEBAND (WM_USER+39) +#define RB_GETDROPTARGET CCS_GETDROPTARGET +#define RB_SETCOLORSCHEME CCS_SETCOLORSCHEME +#define RB_GETCOLORSCHEME CCS_GETCOLORSCHEME +#define RB_SETUNICODEFORMAT CCS_SETUNICODEFORMAT +#define RB_GETUNICODEFORMAT CCS_GETUNICODEFORMAT + + +typedef struct tagREBARINFO +{ + UINT32 cbSize; + UINT32 fMask; + HIMAGELIST himl; +} REBARINFO, *LPREBARINFO; + +typedef struct tagREBARBANDINFOA +{ + UINT32 cbSize; + UINT32 fMask; + UINT32 fStyle; + COLORREF clrFore; + COLORREF clrBack; + LPSTR lpText; + UINT32 cch; + INT32 iImage; + HWND32 hwndChild; + UINT32 cxMinChild; + UINT32 cyMinChild; + UINT32 cx; + HBITMAP32 hbmBack; + UINT32 wID; + UINT32 cyChild; + UINT32 cyMaxChild; + UINT32 cyIntegral; + UINT32 cxIdeal; + LPARAM lParam; + UINT32 cxHeader; +} REBARBANDINFO32A, *LPREBARBANDINFO32A; + + + + /* Trackbar control */ @@ -1119,8 +1326,196 @@ typedef struct tagNMTTDISPINFOW #define LVM_FIRST 0x1000 #define LVM_SETBKCOLOR (LVM_FIRST+1) +#define LVM_GETIMAGELIST (LVM_FIRST+2) #define LVM_SETIMAGELIST (LVM_FIRST+3) +#define LVM_GETITEMCOUNT (LVM_FIRST+4) +#define LVM_GETITEM (LVM_FIRST+5) +#define LVM_INSERTITEM (LVM_FIRST+7) +#define LVM_DELETEALLITEMS (LVM_FIRST+9) +#define LVM_SETITEMPOSITION (LVM_FIRST+15) +#define LVM_INSERTCOLUMN (LVM_FIRST+27) +#define LVM_SORTITEMS (LVM_FIRST+48) +#define LVM_GETSELECTEDCOUNT (LVM_FIRST+50) +#define LVS_ICON 0x0000 +#define LVS_REPORT 0x0001 +#define LVS_SMALLICON 0x0002 +#define LVS_LIST 0x0003 +#define LVS_TYPEMASK 0x0003 +#define LVS_SINGLESEL 0x0004 +#define LVS_SHOWSELALWAYS 0x0008 +#define LVS_SORTASCENDING 0x0010 +#define LVS_SORTDESCENDING 0x0020 +#define LVS_SHAREIMAGELISTS 0x0040 +#define LVS_NOLABELWRAP 0x0080 +#define LVS_AUTOARRANGE 0x0100 +#define LVS_EDITLABELS 0x0200 +#define LVS_OWNERDATA 0x1000 +#define LVS_NOSCROLL 0x2000 +#define LVS_TYPESTYLEMASK 0xfc00 +#define LVS_ALIGNTOP 0x0000 +#define LVS_ALIGNLEFT 0x0800 +#define LVS_ALIGNMASK 0x0c00 +#define LVS_OWNERDRAWFIXED 0x0400 +#define LVS_NOCOLUMNHEADER 0x4000 +#define LVS_NOSORTHEADER 0x8000 + +#define I_IMAGECALLBACK (-1) +#define I_INDENTCALLBACK (-1) +#define LV_ITEMA LVITEMA +#define LV_ITEMW LVITEMW + +#define LV_ITEM LVITEM + +#define LVITEMA_V1_SIZE CCSIZEOF_STRUCT(LVITEMA, lParam) +#define LVITEMW_V1_SIZE CCSIZEOF_STRUCT(LVITEMW, lParam) + +typedef struct tagLVITEMA +{ + UINT32 mask; + int iItem; + int iSubItem; + UINT32 state; + UINT32 stateMask; + LPSTR pszText; + int cchTextMax; + int iImage; + LPARAM lParam; + int iIndent; //(_WIN32_IE >= 0x0300) +} LVITEMA, * LPLVITEMA; + +typedef struct tagLVITEMW +{ + UINT32 mask; + int iItem; + int iSubItem; + UINT32 state; + UINT32 stateMask; + LPWSTR pszText; + int cchTextMax; + int iImage; + LPARAM lParam; + int iIndent; //(_WIN32_IE >= 0x0300) +} LVITEMW, * LPLVITEMW; + +#define LVITEM LVITEMA +#define LPLVITEM LPLVITEMA +#define LVITEM_V1_SIZE LVITEMA_V1_SIZE + +#define LV_COLUMNA LVCOLUMNA +#define LV_COLUMNW LVCOLUMNW +#define LV_COLUMN LVCOLUMN +#define LVCOLUMNA_V1_SIZE CCSIZEOF_STRUCT(LVCOLUMNA, iSubItem) +#define LVCOLUMNW_V1_SIZE CCSIZEOF_STRUCT(LVCOLUMNW, iSubItem) + +typedef struct tagLVCOLUMNA +{ UINT32 mask; + int fmt; + int cx; + LPSTR pszText; + int cchTextMax; + int iSubItem; + int iImage; //(_WIN32_IE >= 0x0300) + int iOrder; //(_WIN32_IE >= 0x0300) +} LVCOLUMNA,* LPLVCOLUMNA; + +typedef struct tagLVCOLUMNW +{ UINT32 mask; + int fmt; + int cx; + LPWSTR pszText; + int cchTextMax; + int iSubItem; + int iImage; //(_WIN32_IE >= 0x0300) + int iOrder; //(_WIN32_IE >= 0x0300) +} LVCOLUMNW,* LPLVCOLUMNW; + +#define LVCOLUMN LVCOLUMNA +#define LPLVCOLUMN LPLVCOLUMNA +#define LVCOLUMN_V1_SIZE LVCOLUMNA_V1_SIZE + +#define LVCF_FMT 0x0001 +#define LVCF_WIDTH 0x0002 +#define LVCF_TEXT 0x0004 +#define LVCF_SUBITEM 0x0008 +#define LVCF_IMAGE 0x0010 +#define LVCF_ORDER 0x0020 + + +#define LVCFMT_LEFT 0x0000 +#define LVCFMT_RIGHT 0x0001 +#define LVCFMT_CENTER 0x0002 +#define LVCFMT_JUSTIFYMASK 0x0003 +#define LVCFMT_IMAGE 0x0800 +#define LVCFMT_BITMAP_ON_RIGHT 0x1000 +#define LVCFMT_COL_HAS_IMAGES 0x8000 + +#define SNDMSG SendMessage32A +#define ListView_GetImageList(hwnd, iImageList) (HIMAGELIST)SNDMSG((hwnd), LVM_GETIMAGELIST, (WPARAM)(INT)(iImageList), 0L) + +#define LVSIL_NORMAL 0 +#define LVSIL_SMALL 1 +#define LVSIL_STATE 2 + + +#define ListView_SetImageList(hwnd, himl, iImageList) (HIMAGELIST)(UINT32)SNDMSG((hwnd), LVM_SETIMAGELIST, (WPARAM32)(iImageList), (LPARAM)(UINT32)(HIMAGELIST)(himl)) +#define ListView_GetItemCount(hwnd)(int)SNDMSG((hwnd), LVM_GETITEMCOUNT, 0, 0L) +#define ListView_GetItem(hwnd, pitem)(BOOL32)SNDMSG((hwnd), LVM_GETITEM, 0, (LPARAM)(LV_ITEM *)(pitem)) +#define ListView_InsertItem(hwnd, pitem) (int)SNDMSG((hwnd), LVM_INSERTITEM, 0, (LPARAM)(const LV_ITEM *)(pitem)) +#define ListView_DeleteAllItems(hwnd) (BOOL32)SNDMSG((hwnd), LVM_DELETEALLITEMS, 0, 0L) +#define ListView_InsertColumn(hwnd, iCol, pcol)(int)SNDMSG((hwnd), LVM_INSERTCOLUMN, (WPARAM32)(int)(iCol), (LPARAM)(const LV_COLUMN *)(pcol)) +typedef int (CALLBACK *PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); +#define ListView_SortItems(hwndLV, _pfnCompare, _lPrm)(BOOL32)SNDMSG((hwndLV), LVM_SORTITEMS, (WPARAM32)(LPARAM)_lPrm,(LPARAM)(PFNLVCOMPARE)_pfnCompare) +#define ListView_SetItemPosition(hwndLV, i, x, y)(BOOL32)SNDMSG((hwndLV), LVM_SETITEMPOSITION, (WPARAM32)(int)(i), MAKELPARAM((x), (y))) +#define ListView_GetSelectedCount(hwndLV)(UINT32)SNDMSG((hwndLV), LVM_GETSELECTEDCOUNT, 0, 0L) + +#define LVIF_TEXT 0x0001 +#define LVIF_IMAGE 0x0002 +#define LVIF_PARAM 0x0004 +#define LVIF_STATE 0x0008 +#define LVIF_INDENT 0x0010 +#define LVIF_NORECOMPUTE 0x0800 + +#define LVIS_FOCUSED 0x0001 +#define LVIS_SELECTED 0x0002 +#define LVIS_CUT 0x0004 +#define LVIS_DROPHILITED 0x0008 +#define LVIS_ACTIVATING 0x0020 + +#define LVIS_OVERLAYMASK 0x0F00 +#define LVIS_STATEIMAGEMASK 0xF000 + +#define LPNM_LISTVIEW LPNMLISTVIEW +#define NM_LISTVIEW NMLISTVIEW + +typedef struct tagNMLISTVIEW +{ NMHDR hdr; + int iItem; + int iSubItem; + UINT32 uNewState; + UINT32 uOldState; + UINT32 uChanged; + POINT32 ptAction; + LPARAM lParam; +} NMLISTVIEW,*LPNMLISTVIEW; + + +#define LV_DISPINFOA NMLVDISPINFOA +#define LV_DISPINFOW NMLVDISPINFOW + +#define LV_DISPINFO NMLVDISPINFO + +typedef struct tagLVDISPINFO { + NMHDR hdr; + LVITEMA item; +} NMLVDISPINFOA, *LPNMLVDISPINFOA; + +typedef struct tagLVDISPINFOW { + NMHDR hdr; + LVITEMW item; +} NMLVDISPINFOW, * LPNMLVDISPINFOW; + +#define NMLVDISPINFO NMLVDISPINFOA #endif /* __WINE_COMMCTRL_H */ diff --git a/include/ddraw.h b/include/ddraw.h index 58ea6ff9374..db8766646f9 100644 --- a/include/ddraw.h +++ b/include/ddraw.h @@ -876,7 +876,6 @@ FAR * ) PURE; struct _common_directdrawdata { DWORD depth; DWORD height,width; /* SetDisplayMode */ - HWND32 mainwindow; }; struct _dga_directdrawdata { @@ -887,12 +886,16 @@ struct _dga_directdrawdata { struct _xlib_directdrawdata { Window drawable; + int use_xshm; /* are these needed for anything? (draw_surf is the active surface) - IDirectDrawSurface *surfs; - DWORD num_surfs, alloc_surfs, draw_surf; */ + IDirectDrawSurface *surfs; + DWORD num_surfs, alloc_surfs, draw_surf; */ + int paintable; - ATOM winclass; - HWND32 window; +/* current window implementation */ + ATOM winclass; + HWND32 window; + PAINTSTRUCT32 ps; }; struct IDirectDraw { @@ -901,7 +904,6 @@ struct IDirectDraw { struct _common_directdrawdata d; union { struct _xlib_directdrawdata xlib; - struct _xlib_directdrawdata xshm; struct _dga_directdrawdata dga; } e; }; @@ -957,8 +959,6 @@ struct IDirectDraw2 { struct _common_directdrawdata d; union { struct _xlib_directdrawdata xlib; - /* only different in image create&put */ - struct _xlib_directdrawdata xshm; struct _dga_directdrawdata dga; } e; }; @@ -967,7 +967,7 @@ struct IDirectDraw2 { #define THIS LPDIRECTDRAWSURFACE this struct _common_directdrawsurface { LPDIRECTDRAWPALETTE palette; - LPDIRECTDRAW ddraw; + LPDIRECTDRAW2 ddraw; LPDIRECTDRAWSURFACE3 backbuffer; LPVOID surface; DWORD lpitch,width,height; @@ -977,16 +977,12 @@ struct _dga_directdrawsurface { DWORD fb_height; }; -struct _xshm_directdrawsurface { +struct _xlib_directdrawsurface { XImage *image; #ifdef HAVE_LIBXXSHM XShmSegmentInfo shminfo; #endif }; -struct _xlib_directdrawsurface { - XImage *image; - BOOL32 surface_is_image_data; -}; typedef struct IDirectDrawSurface_VTable { /*** IUnknown methods ***/ @@ -1034,7 +1030,6 @@ struct IDirectDrawSurface { struct _common_directdrawsurface s; union { struct _dga_directdrawsurface dga; - struct _xshm_directdrawsurface xshm; struct _xlib_directdrawsurface xlib; } t; }; @@ -1181,5 +1176,8 @@ struct IDirectDrawColorControl { #undef STDMETHOD #undef STDMETHOD_ -extern HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID,LPDIRECTDRAW *lplpDD,LPUNKNOWN pUnkOuter ); +HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN); +HRESULT WINAPI DirectDrawEnumerate32A(LPDDENUMCALLBACK32A,LPVOID); +HRESULT WINAPI DirectDrawEnumerate32W(LPDDENUMCALLBACK32W,LPVOID); +#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate) #endif diff --git a/include/debug.h b/include/debug.h index 9056a5c1cd1..962d8260b74 100644 --- a/include/debug.h +++ b/include/debug.h @@ -87,58 +87,59 @@ #define dbch_ole 79 #define dbch_pager 80 #define dbch_palette 81 -#define dbch_print 82 -#define dbch_process 83 -#define dbch_profile 84 -#define dbch_progress 85 -#define dbch_prop 86 -#define dbch_psdrv 87 -#define dbch_rebar 88 -#define dbch_reg 89 -#define dbch_region 90 -#define dbch_relay 91 -#define dbch_resource 92 -#define dbch_s 93 -#define dbch_scroll 94 -#define dbch_security 95 -#define dbch_segment 96 -#define dbch_selector 97 -#define dbch_sem 98 -#define dbch_sendmsg 99 -#define dbch_shell 100 -#define dbch_shm 101 -#define dbch_snoop 102 -#define dbch_sound 103 -#define dbch_static 104 -#define dbch_statusbar 105 -#define dbch_stress 106 -#define dbch_string 107 -#define dbch_syscolor 108 -#define dbch_system 109 -#define dbch_task 110 -#define dbch_text 111 -#define dbch_thread 112 -#define dbch_thunk 113 -#define dbch_timer 114 -#define dbch_toolbar 115 -#define dbch_toolhelp 116 -#define dbch_tooltips 117 -#define dbch_trackbar 118 -#define dbch_treeview 119 -#define dbch_tweak 120 -#define dbch_uitools 121 -#define dbch_updown 122 -#define dbch_ver 123 -#define dbch_virtual 124 -#define dbch_vxd 125 -#define dbch_win 126 -#define dbch_win16drv 127 -#define dbch_win32 128 -#define dbch_wing 129 -#define dbch_winsock 130 -#define dbch_wnet 131 -#define dbch_x11 132 -#define dbch_x11drv 133 +#define dbch_pidl 82 +#define dbch_print 83 +#define dbch_process 84 +#define dbch_profile 85 +#define dbch_progress 86 +#define dbch_prop 87 +#define dbch_psdrv 88 +#define dbch_rebar 89 +#define dbch_reg 90 +#define dbch_region 91 +#define dbch_relay 92 +#define dbch_resource 93 +#define dbch_s 94 +#define dbch_scroll 95 +#define dbch_security 96 +#define dbch_segment 97 +#define dbch_selector 98 +#define dbch_sem 99 +#define dbch_sendmsg 100 +#define dbch_shell 101 +#define dbch_shm 102 +#define dbch_snoop 103 +#define dbch_sound 104 +#define dbch_static 105 +#define dbch_statusbar 106 +#define dbch_stress 107 +#define dbch_string 108 +#define dbch_syscolor 109 +#define dbch_system 110 +#define dbch_task 111 +#define dbch_text 112 +#define dbch_thread 113 +#define dbch_thunk 114 +#define dbch_timer 115 +#define dbch_toolbar 116 +#define dbch_toolhelp 117 +#define dbch_tooltips 118 +#define dbch_trackbar 119 +#define dbch_treeview 120 +#define dbch_tweak 121 +#define dbch_uitools 122 +#define dbch_updown 123 +#define dbch_ver 124 +#define dbch_virtual 125 +#define dbch_vxd 126 +#define dbch_win 127 +#define dbch_win16drv 128 +#define dbch_win32 129 +#define dbch_wing 130 +#define dbch_winsock 131 +#define dbch_wnet 132 +#define dbch_x11 133 +#define dbch_x11drv 134 /* Definitions for classes identifiers */ #define dbcl_fixme 0 #define dbcl_err 1 diff --git a/include/debugdefs.h b/include/debugdefs.h index 14450def2f8..60cededb660 100644 --- a/include/debugdefs.h +++ b/include/debugdefs.h @@ -4,7 +4,7 @@ #include "debugtools.h" #endif -#define DEBUG_CHANNEL_COUNT 134 +#define DEBUG_CHANNEL_COUNT 135 #ifdef DEBUG_RUNTIME short debug_msg_enabled[][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, @@ -141,6 +141,7 @@ short debug_msg_enabled[][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, {1, 1, 0, 0}, {1, 1, 0, 0}, +{1, 1, 0, 0}, }; const char* debug_ch_name[] = { "1", @@ -225,6 +226,7 @@ const char* debug_ch_name[] = { "ole", "pager", "palette", +"pidl", "print", "process", "profile", diff --git a/include/dosexe.h b/include/dosexe.h index 56cd478af16..ad3a89205d8 100644 --- a/include/dosexe.h +++ b/include/dosexe.h @@ -15,24 +15,25 @@ typedef struct _DOSTASK { LPVOID img; unsigned img_ofs; + WORD psp_seg,load_seg; HMODULE16 hModule; struct vm86plus_struct VM86; int fn, state; -#ifdef MZ_USESYSV - /* SYSV IPC is not quite supported yet... */ - key_t shm_key; - int shm_id; -#else char mm_name[128]; int mm_fd; -#endif int read_pipe,write_pipe; pid_t task; } DOSTASK, *LPDOSTASK; -extern HINSTANCE16 MZ_LoadModule( LPCSTR name, LPCSTR cmdline, LPCSTR env, UINT16 show_cmd ); +#define MZ_SUPPORTED + +extern int MZ_InitTask( LPDOSTASK lpDosTask ); extern int MZ_RunModule( LPDOSTASK lpDosTask ); extern void MZ_KillModule( LPDOSTASK lpDosTask ); extern int DOSVM_Process( LPDOSTASK lpDosTask ); #endif /* linux */ + +extern HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, + LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info ); +extern int DOSVM_Enter( PCONTEXT context ); diff --git a/include/file.h b/include/file.h index 564314fb327..fc5f8067bc7 100644 --- a/include/file.h +++ b/include/file.h @@ -40,6 +40,17 @@ typedef struct int flags; } DOS_DEVICE; +/* Macros to convert 16 bit to 32 bit file handles and back */ +#define HFILE16_TO_HFILE32(handle) \ +(((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \ + ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \ + ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \ + (handle)-5) + +#define HFILE32_TO_HFILE16(handle) ({ HFILE32 hnd=handle; \ + ((hnd==HFILE_ERROR32) ? HFILE_ERROR16 : \ + (HFILE16)hnd+5); }) + /* files/file.c */ extern FILE_OBJECT *FILE_GetFile( HFILE32 handle ); diff --git a/include/gdi.h b/include/gdi.h index fcb1786b339..c8ca418f7c7 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -200,7 +200,7 @@ typedef struct tagDC_FUNCS BOOL32 (*pPatBlt)(DC*,INT32,INT32,INT32,INT32,DWORD); BOOL32 (*pPie)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32); BOOL32 (*pPolyPolygon)(DC*,LPPOINT32,LPINT32,UINT32); - BOOL32 (*pPolyPolyline)(DC*,LPPOINT32,LPINT32,UINT32); + BOOL32 (*pPolyPolyline)(DC*,LPPOINT32,LPDWORD,DWORD); BOOL32 (*pPolygon)(DC*,LPPOINT32,INT32); BOOL32 (*pPolyline)(DC*,LPPOINT32,INT32); BOOL32 (*pPolyBezier)(DC*,POINT32, LPPOINT32,DWORD); diff --git a/include/header.h b/include/header.h index 710b1e4f43c..298f67bd46d 100644 --- a/include/header.h +++ b/include/header.h @@ -18,32 +18,32 @@ typedef struct INT32 fmt; LPARAM lParam; INT32 iImage; - INT32 iOrder; + INT32 iOrder; /* see documentation of HD_ITEM */ - BOOL32 bDown; - RECT32 rect; + BOOL32 bDown; /* is item pressed? (used for drawing) */ + RECT32 rect; /* bounding rectangle of the item */ } HEADER_ITEM; typedef struct { - UINT32 uNumItem; - INT32 nHeight; - HFONT32 hFont; - HCURSOR32 hcurArrow; - HCURSOR32 hcurDivider; - HCURSOR32 hcurDivopen; - BOOL32 bCaptured; - BOOL32 bPressed; - BOOL32 bTracking; - INT32 iMoveItem; - INT32 xTrackOffset; - INT32 xOldTrack; - INT32 nOldWidth; - INT32 iHotItem; + UINT32 uNumItem; /* number of items (columns) */ + INT32 nHeight; /* height of the header (pixels) */ + HFONT32 hFont; /* handle to the current font */ + HCURSOR32 hcurArrow; /* handle to the arrow cursor */ + HCURSOR32 hcurDivider; /* handle to a cursor (used over dividers) <-|-> */ + HCURSOR32 hcurDivopen; /* handle to a cursor (used over dividers) <-||-> */ + BOOL32 bCaptured; /* Is the mouse captured? */ + BOOL32 bPressed; /* Is a header item pressed (down)? */ + BOOL32 bTracking; /* Is in tracking mode? */ + INT32 iMoveItem; /* index of tracked item. (Tracking mode) */ + INT32 xTrackOffset; /* distance between the right side of the tracked item and the cursor */ + INT32 xOldTrack; /* track offset (see above) after the last WM_MOUSEMOVE */ + INT32 nOldWidth; /* width of a sizing item after the last WM_MOUSEMOVE */ + INT32 iHotItem; /* index of hot item (cursor is over this item) */ - HIMAGELIST himl; - HEADER_ITEM *items; + HIMAGELIST himl; /* handle to a image list (may be 0) */ + HEADER_ITEM *items; /* pointer to array of HEADER_ITEM's */ } HEADER_INFO; diff --git a/include/miscemu.h b/include/miscemu.h index 5f4c7669706..6855762913b 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -17,6 +17,7 @@ extern DWORD DOSMEM_CollateTable; extern BOOL32 DOSMEM_Init(HMODULE16 hModule); extern void DOSMEM_Tick(void); extern WORD DOSMEM_AllocSelector(WORD); +extern char * DOSMEM_MemoryBase(HMODULE16 hModule); extern LPVOID DOSMEM_GetBlock(HMODULE16 hModule, UINT32 size, UINT16* p); extern BOOL32 DOSMEM_FreeBlock(HMODULE16 hModule, void* ptr); extern LPVOID DOSMEM_ResizeBlock(HMODULE16 hModule, void* ptr, UINT32 size, UINT16* p); @@ -36,6 +37,10 @@ extern void IO_outport( int port, int count, DWORD value ); /* msdos/int1a.c */ extern DWORD INT1A_GetTicksSinceMidnight(void); +extern void WINAPI INT_Int1aHandler(CONTEXT*); + +/* msdos/int2f.c */ +extern void WINAPI INT_Int2fHandler(CONTEXT*); /* loader/signal.c */ extern BOOL32 SIGNAL_Init(void); diff --git a/include/module.h b/include/module.h index 485d78420dd..bc0e25fb105 100644 --- a/include/module.h +++ b/include/module.h @@ -52,6 +52,7 @@ typedef struct _NE_MODULE HMODULE16 self; /* 44 Handle for this module */ WORD self_loading_sel; /* 46 Selector used for self-loading apps. */ struct _DOSTASK *lpDosTask; + LPVOID dos_image; /* pointer to DOS memory (for DOS apps) */ } NE_MODULE; @@ -98,7 +99,7 @@ typedef struct { LPSTR lpEnvAddress; LPSTR lpCmdLine; - LPSTR lpCmdShow; + UINT16 *lpCmdShow; DWORD dwReserved; } LOADPARAMS32; @@ -140,8 +141,6 @@ extern FARPROC32 MODULE_GetProcAddress32( struct _PDB32*pdb,HMODULE32 hModule,LP extern WINE_MODREF *MODULE32_LookupHMODULE( struct _PDB32 *process, HMODULE32 hModule ); extern HMODULE32 MODULE_FindModule32( struct _PDB32 *process, LPCSTR path ); extern HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs ); -extern HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit, LPCSTR cmd_line, - LPCSTR env, UINT32 show_cmd ); extern FARPROC16 MODULE_GetWndProcEntry16( const char *name ); extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPCSTR name ); diff --git a/include/pager.h b/include/pager.h index fe992ff4655..0808084875c 100644 --- a/include/pager.h +++ b/include/pager.h @@ -14,7 +14,8 @@ typedef struct tagPAGER_INFO COLORREF clrBk; INT32 iBorder; INT32 iButtonSize; - + INT32 iPos; + BOOL32 bForward; } PAGER_INFO; diff --git a/include/pe_image.h b/include/pe_image.h index 5b91461f0ce..bba57335e3f 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -40,8 +40,9 @@ extern HRSRC32 PE_FindResourceEx32W(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD); extern DWORD PE_SizeofResource32(HMODULE32,HRSRC32); extern HMODULE32 PE_LoadLibraryEx32A(LPCSTR,struct _PDB32*,HFILE32,DWORD); extern HGLOBAL32 PE_LoadResource32(struct _wine_modref *wm,HRSRC32); -extern HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line, - LPCSTR env, UINT16 showCmd ); +extern HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line, + LPCSTR env, LPSTARTUPINFO32A startup, + LPPROCESS_INFORMATION info ); struct _PDB32; /* forward definition */ struct _THDB; /* forward definition */ diff --git a/include/process.h b/include/process.h index 8f822943a41..539aee17453 100644 --- a/include/process.h +++ b/include/process.h @@ -142,7 +142,7 @@ extern PDB32 *PROCESS_GetPtr( HANDLE32 handle, DWORD access, int *server_handle extern PDB32 *PROCESS_IdToPDB( DWORD id ); extern PDB32 *PROCESS_Create( struct _NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, HINSTANCE16 hInstance, - HINSTANCE16 hPrevInstance, UINT32 cmdShow, + HINSTANCE16 hPrevInstance, STARTUPINFO32A *startup, PROCESS_INFORMATION *info ); extern void PROCESS_SuspendOtherThreads(void); extern void PROCESS_ResumeOtherThreads(void); diff --git a/include/queue.h b/include/queue.h index 38136c54086..f864dfe0a73 100644 --- a/include/queue.h +++ b/include/queue.h @@ -80,6 +80,8 @@ extern void QUEUE_WalkQueues(void); extern BOOL32 QUEUE_IsExitingQueue( HQUEUE16 hQueue ); extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue ); extern MESSAGEQUEUE *QUEUE_GetSysQueue(void); +extern void QUEUE_Signal( HTASK16 hTask ); +extern void QUEUE_Wait(void); extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit ); extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit ); extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue ); diff --git a/include/rebar.h b/include/rebar.h index 152d6ee1359..ff925129770 100644 --- a/include/rebar.h +++ b/include/rebar.h @@ -7,10 +7,38 @@ #ifndef __WINE_REBAR_H #define __WINE_REBAR_H +typedef struct tagREBAR_BAND +{ + UINT32 fStyle; + COLORREF clrFore; + COLORREF clrBack; + INT32 iImage; + HWND32 hwndChild; + UINT32 cxMinChild; + UINT32 cyMinChild; + UINT32 cx; + HBITMAP32 hbmBack; + UINT32 wID; + UINT32 cyChild; + UINT32 cyMaxChild; + UINT32 cyIntegral; + UINT32 cxIdeal; + LPARAM lParam; + UINT32 cxHeader; + + LPSTR lpText; + +} REBAR_BAND; + typedef struct tagREBAR_INFO { - UINT32 uDummy; /* this is just a dummy to keep the compiler happy */ + COLORREF clrBk; /* background color */ + COLORREF clrText; /* text color */ + HIMAGELIST himl; /* handle to imagelist */ + UINT32 uNumBands; /* number of bands in the rebar */ + + REBAR_BAND *bands; /* pointer to the array of rebar bands */ } REBAR_INFO; diff --git a/include/server.h b/include/server.h index 0b80e48a6b2..30e09acbe48 100644 --- a/include/server.h +++ b/include/server.h @@ -86,6 +86,18 @@ struct get_process_info_reply }; +/* Retrieve information about a thread */ +struct get_thread_info_request +{ + int handle; /* thread handle */ +}; +struct get_thread_info_reply +{ + void* pid; /* server thread id */ + int exit_code; /* thread exit code */ +}; + + /* Close a handle for the current process */ struct close_handle_request { @@ -123,6 +135,23 @@ struct open_process_reply }; +/* Wait for handles */ +struct select_request +{ + int count; /* handles count */ + int flags; /* wait flags (see below) */ + int timeout; /* timeout in ms */ + /* int handles[] */ +}; +struct select_reply +{ + int signaled; /* signaled handle */ +}; +#define SELECT_ALL 1 +#define SELECT_MSG 2 +#define SELECT_ALERTABLE 4 +#define SELECT_TIMEOUT 8 + /* client-side functions */ #ifndef __WINE_SERVER__ @@ -134,8 +163,10 @@ extern int CLIENT_TerminateThread( int handle, int exit_code ); extern int CLIENT_CloseHandle( int handle ); extern int CLIENT_DuplicateHandle( int src_process, int src_handle, int dst_process, int dst_handle, DWORD access, BOOL32 inherit, DWORD options ); +extern int CLIENT_GetThreadInfo( int handle, struct get_thread_info_reply *reply ); extern int CLIENT_GetProcessInfo( int handle, struct get_process_info_reply *reply ); extern int CLIENT_OpenProcess( void *pid, DWORD access, BOOL32 inherit ); +extern int CLIENT_Select( int count, int *handles, int flags, int timeout ); #endif /* __WINE_SERVER__ */ #endif /* __WINE_SERVER_H */ diff --git a/include/server/object.h b/include/server/object.h index bf6dcd34b54..52680619a51 100644 --- a/include/server/object.h +++ b/include/server/object.h @@ -18,17 +18,22 @@ struct object; struct object_name; +struct thread; struct object_ops { - void (*dump)(struct object *,int); /* dump the object (for debugging) */ - void (*destroy)(struct object *); /* destroy on refcount == 0 */ + void (*dump)(struct object *,int); /* dump the object (for debugging) */ + int (*signaled)(struct object *,struct thread *); /* is object signaled? */ + int (*satisfied)(struct object *,struct thread *); /* wait satisfied; return 1 if abandoned */ + void (*destroy)(struct object *); /* destroy on refcount == 0 */ }; struct object { unsigned int refcount; const struct object_ops *ops; + struct wait_queue_entry *head; + struct wait_queue_entry *tail; struct object_name *name; }; diff --git a/include/server/request.h b/include/server/request.h index 574b73253d9..b882ebc50aa 100644 --- a/include/server/request.h +++ b/include/server/request.h @@ -10,9 +10,11 @@ enum request REQ_TERMINATE_PROCESS, REQ_TERMINATE_THREAD, REQ_GET_PROCESS_INFO, + REQ_GET_THREAD_INFO, REQ_CLOSE_HANDLE, REQ_DUP_HANDLE, REQ_OPEN_PROCESS, + REQ_SELECT, REQ_NB_REQUESTS }; @@ -26,9 +28,11 @@ DECL_HANDLER(init_thread); DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_thread); DECL_HANDLER(get_process_info); +DECL_HANDLER(get_thread_info); DECL_HANDLER(close_handle); DECL_HANDLER(dup_handle); DECL_HANDLER(open_process); +DECL_HANDLER(select); static const struct handler { void (*handler)(); @@ -39,9 +43,11 @@ static const struct handler { { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) }, { (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) }, { (void(*)())req_get_process_info, sizeof(struct get_process_info_request) }, + { (void(*)())req_get_thread_info, sizeof(struct get_thread_info_request) }, { (void(*)())req_close_handle, sizeof(struct close_handle_request) }, { (void(*)())req_dup_handle, sizeof(struct dup_handle_request) }, { (void(*)())req_open_process, sizeof(struct open_process_request) }, + { (void(*)())req_select, sizeof(struct select_request) }, }; #endif /* WANT_REQUEST_HANDLERS */ diff --git a/include/server/thread.h b/include/server/thread.h index 9edbfdf4e59..7f7df8d8328 100644 --- a/include/server/thread.h +++ b/include/server/thread.h @@ -16,21 +16,26 @@ /* thread structure */ struct process; +struct thread_wait; + +enum run_state { STARTING, RUNNING, TERMINATED }; struct thread { - struct object obj; /* object header */ - struct thread *next; /* system-wide thread list */ - struct thread *prev; - struct thread *proc_next; /* per-process thread list */ - struct thread *proc_prev; - struct process *process; - int error; /* current error code */ - int exit_code; /* thread exit code */ - int client_fd; /* client fd for socket communications */ - int unix_pid; /* Unix pid of client */ - enum request last_req; /* last request received (for debugging) */ - char *name; + struct object obj; /* object header */ + struct thread *next; /* system-wide thread list */ + struct thread *prev; + struct thread *proc_next; /* per-process thread list */ + struct thread *proc_prev; + struct process *process; + struct thread_wait *wait; /* current wait condition if sleeping */ + int error; /* current error code */ + enum run_state state; /* running state */ + int exit_code; /* thread exit code */ + int client_fd; /* client fd for socket communications */ + int unix_pid; /* Unix pid of client */ + enum request last_req; /* last request received (for debugging) */ + char *name; }; extern struct thread *current; @@ -41,10 +46,16 @@ extern struct thread *create_thread( int fd, void *pid, int *thread_handle, int *process_handle ); extern struct thread *get_thread_from_id( void *id ); extern struct thread *get_thread_from_handle( int handle, unsigned int access ); +extern void get_thread_info( struct thread *thread, + struct get_thread_info_reply *reply ); extern int send_reply( struct thread *thread, int pass_fd, int n, ... /* arg_1, len_1, ..., arg_n, len_n */ ); extern void kill_thread( struct thread *thread, int exit_code ); extern void thread_killed( struct thread *thread, int exit_code ); +extern void thread_timeout(void); +extern void sleep_on( struct thread *thread, int count, int *handles, + int flags, int timeout ); +extern void wake_up( struct object *obj, int max ); #define SET_ERROR(err) (current->error = (err)) #define CLEAR_ERROR() (current->error = 0) diff --git a/include/shell.h b/include/shell.h index cda641c0924..e9dc4c52925 100644 --- a/include/shell.h +++ b/include/shell.h @@ -6,15 +6,29 @@ #include "windows.h" #include "winreg.h" +#include "imagelist.h" #ifndef MAX_PATH #define MAX_PATH 260 #endif +/**************************************************************************** +* shell 16 +*/ extern void SHELL_LoadRegistry(); extern void SHELL_SaveRegistry(); extern void SHELL_Init(); +/* global functions used from shell32 */ +extern HINSTANCE32 SHELL_FindExecutable(LPCSTR,LPCSTR ,LPSTR); +extern HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16,LPCSTR,UINT16,WORD); + +/**************************************************************************** +* shell 32 +*/ +/**************************************************************************** +* common return codes +*/ #define SHELL_ERROR_SUCCESS 0L #define SHELL_ERROR_BADDB 1L #define SHELL_ERROR_BADKEY 2L @@ -25,8 +39,8 @@ extern void SHELL_Init(); #define SHELL_ERROR_INVALID_PARAMETER 7L #define SHELL_ERROR_ACCESS_DENIED 8L -/****************************** -* common shell file structures +/**************************************************************************** +* common shell file structures */ #define FO_MOVE 0x0001 #define FO_COPY 0x0002 @@ -63,8 +77,8 @@ typedef struct { /* structure for dropped files */ /* memory block with filenames follows */ } DROPFILESTRUCT, *LPDROPFILESTRUCT; -/****************************** -* NOTIFYICONDATA +/**************************************************************************** +* NOTIFYICONDATA */ typedef struct _NOTIFYICONDATA { DWORD cbSize; @@ -76,8 +90,8 @@ typedef struct _NOTIFYICONDATA { CHAR szTip[64]; } NOTIFYICONDATA, *PNOTIFYICONDATA; -/******************************* -* SHITEMID, ITEMIDLIST, PIDL API +/**************************************************************************** +* SHITEMID, ITEMIDLIST, PIDL API */ typedef struct { WORD cb; /* nr of bytes in this item */ @@ -89,6 +103,7 @@ typedef struct } ITEMIDLIST,*LPITEMIDLIST,*LPCITEMIDLIST; LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl); +LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl); LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST iil1,LPCITEMIDLIST iil2); DWORD WINAPI ILGetSize(LPITEMIDLIST pidl); @@ -97,7 +112,7 @@ DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath); #define SHGetPathFromIDList WINELIB_NAME_AW(SHGetPathFromIDList) /**************************************************************************** -* SHFILEINFO API +* SHFILEINFO API */ typedef struct tagSHFILEINFO32A { HICON32 hIcon; /* icon */ @@ -122,7 +137,7 @@ DWORD WINAPI SHGetFileInfo32W(LPCWSTR,DWORD,SHFILEINFO32W*,UINT32,UINT32); #define SHGetFileInfo WINELIB_NAME_AW(SHGetFileInfo) /**************************************************************************** -* SHFILEOPSTRUCT API +* SHFILEOPSTRUCT API */ typedef struct _SHFILEOPSTRUCTA { HWND32 hwnd; @@ -153,7 +168,7 @@ DECL_WINELIB_TYPE_AW(SHFILEOPSTRUCT) DWORD WINAPI SHFileOperation32(LPSHFILEOPSTRUCT32 lpFileOp); -/**************** +/**************************************************************************** * APPBARDATA */ typedef struct _AppBarData { @@ -188,6 +203,7 @@ typedef struct { LPITEMIDLIST pidl; DWORD unknown; } IDSTRUCT; + DWORD WINAPI SHChangeNotifyRegister(HWND32 hwnd,LONG events1,LONG events2,DWORD msg,int count,IDSTRUCT *idlist); DWORD WINAPI SHChangeNotifyDeregister(LONG x1,LONG x2); @@ -199,14 +215,18 @@ DWORD WINAPI SHChangeNotifyDeregister(LONG x1,LONG x2); DWORD WINAPI SHAddToRecentDocs(UINT32 uFlags, LPCVOID pv); +/**************************************************************************** +* string and path functions +*/ +LPSTR WINAPI PathAddBackslash(LPSTR path); +LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2); +LPSTR WINAPI PathRemoveBlanks(LPSTR str); +LPSTR WINAPI PathFindFilename(LPSTR fn); /**************************************************************************** * other functions */ LPVOID WINAPI SHAlloc(DWORD len); DWORD WINAPI SHFree(LPVOID x); -LPSTR WINAPI PathAddBackslash(LPSTR path); -LPSTR WINAPI PathCombine(LPSTR target,LPSTR x1,LPSTR x2); -LPSTR WINAPI PathRemoveBlanks(LPSTR str); #define SE_ERR_SHARE 26 #define SE_ERR_ASSOCINCOMPLETE 27 @@ -233,10 +253,4 @@ LPSTR WINAPI PathRemoveBlanks(LPSTR str); #define CSIDL_FONTS 0x0014 #define CSIDL_TEMPLATES 0x0015 -/******************************************* -* global SHELL32.DLL variables -*/ -extern HINSTANCE32 shell32_hInstance; -extern UINT32 shell32_DllRefCount; - #endif /* __WINE_SHELL_H */ diff --git a/include/shlobj.h b/include/shlobj.h index 350fe57dbfc..4a900ac4c20 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -7,6 +7,7 @@ #include "compobj.h" #include "storage.h" #include "commctrl.h" +#include "interfaces.h" #define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn) #define STDMETHOD_(type,xfn) type (CALLBACK *fn##xfn) @@ -25,11 +26,15 @@ DWORD WINAPI SHELL32_DllGetClassObject(LPCLSID,REFIID,LPVOID*); typedef LPVOID LPBC; /* *IBindCtx really */ /* foreward declaration of the objects*/ -typedef struct IEnumIDList IEnumIDList,*LPENUMIDLIST; -typedef struct tagSHELLFOLDER *LPSHELLFOLDER,IShellFolder; -typedef struct tagSHELLVIEW *LPSHELLVIEW,IShellView; -typedef struct tagSHELLBROWSER *LPSHELLBROWSER,IShellBrowser; +typedef struct IContextMenu IContextMenu, *LPCONTEXTMENU; +typedef struct IShellExtInit IShellExtInit, *LPSHELLEXTINIT; +typedef struct IEnumIDList IEnumIDList, *LPENUMIDLIST; +typedef struct tagSHELLFOLDER *LPSHELLFOLDER, IShellFolder; +typedef struct tagSHELLVIEW *LPSHELLVIEW, IShellView; +typedef struct tagSHELLBROWSER *LPSHELLBROWSER,IShellBrowser; + +typedef struct IDataObject IDataObject, *LPDATAOBJECT; /**************************************************************************** * SHELL ID */ @@ -114,17 +119,18 @@ typedef struct PidlMgr_VTable STDMETHOD_(LPITEMIDLIST, CreateDrive) (THIS_ LPCSTR); STDMETHOD_(LPITEMIDLIST, CreateFolder) (THIS_ LPCSTR); STDMETHOD_(LPITEMIDLIST, CreateValue) (THIS_ LPCSTR); -/* STDMETHOD_(void, Delete) (THIS_ LPITEMIDLIST);*/ - STDMETHOD_(LPITEMIDLIST, GetNextItem) (THIS_ LPCITEMIDLIST); + STDMETHOD_(BOOL32, GetDesktop) (THIS_ LPCITEMIDLIST, LPSTR); STDMETHOD_(BOOL32, GetDrive) (THIS_ LPCITEMIDLIST, LPSTR, UINT16); STDMETHOD_(LPITEMIDLIST, GetLastItem) (THIS_ LPCITEMIDLIST); STDMETHOD_(DWORD, GetItemText) (THIS_ LPCITEMIDLIST, LPSTR, UINT16); + STDMETHOD_(BOOL32, IsDesktop) (THIS_ LPCITEMIDLIST); STDMETHOD_(BOOL32, IsMyComputer) (THIS_ LPCITEMIDLIST); STDMETHOD_(BOOL32, IsDrive) (THIS_ LPCITEMIDLIST); STDMETHOD_(BOOL32, IsFolder) (THIS_ LPCITEMIDLIST); STDMETHOD_(BOOL32, IsValue) (THIS_ LPCITEMIDLIST); + STDMETHOD_(BOOL32, HasFolders) (THIS_ LPSTR, LPCITEMIDLIST); STDMETHOD_(DWORD, GetFolderText) (THIS_ LPCITEMIDLIST, LPSTR, DWORD); STDMETHOD_(DWORD, GetValueText) (THIS_ LPCITEMIDLIST, LPSTR, DWORD); @@ -147,6 +153,136 @@ extern LPPIDLMGR PidlMgr_Constructor(); extern void PidlMgr_Destructor(THIS); #endif +#undef THIS +/***************************************************************************** + * IContextMenu interface + */ +#define THIS LPCONTEXTMENU this + +/* QueryContextMenu uFlags */ +#define CMF_NORMAL 0x00000000 +#define CMF_DEFAULTONLY 0x00000001 +#define CMF_VERBSONLY 0x00000002 +#define CMF_EXPLORE 0x00000004 +#define CMF_NOVERBS 0x00000008 +#define CMF_CANRENAME 0x00000010 +#define CMF_NODEFAULT 0x00000020 +#define CMF_INCLUDESTATIC 0x00000040 +#define CMF_RESERVED 0xffff0000 // View specific + +/* GetCommandString uFlags */ +#define GCS_VERBA 0x00000000 // canonical verb +#define GCS_HELPTEXTA 0x00000001 // help text (for status bar) +#define GCS_VALIDATEA 0x00000002 // validate command exists +#define GCS_VERBW 0x00000004 // canonical verb (unicode) +#define GCS_HELPTEXTW 0x00000005 // help text (unicode version) +#define GCS_VALIDATEW 0x00000006 // validate command exists (unicode) +#define GCS_UNICODE 0x00000004 // for bit testing - Unicode string + +#define GCS_VERB GCS_VERBA +#define GCS_HELPTEXT GCS_HELPTEXTA +#define GCS_VALIDATE GCS_VALIDATEA + +#define CMDSTR_NEWFOLDERA "NewFolder" +#define CMDSTR_VIEWLISTA "ViewList" +#define CMDSTR_VIEWDETAILSA "ViewDetails" +#define CMDSTR_NEWFOLDERW L"NewFolder" +#define CMDSTR_VIEWLISTW L"ViewList" +#define CMDSTR_VIEWDETAILSW L"ViewDetails" + +#define CMDSTR_NEWFOLDER CMDSTR_NEWFOLDERA +#define CMDSTR_VIEWLIST CMDSTR_VIEWLISTA +#define CMDSTR_VIEWDETAILS CMDSTR_VIEWDETAILSA + +#define CMIC_MASK_HOTKEY SEE_MASK_HOTKEY +#define CMIC_MASK_ICON SEE_MASK_ICON +#define CMIC_MASK_FLAG_NO_UI SEE_MASK_FLAG_NO_UI +#define CMIC_MASK_UNICODE SEE_MASK_UNICODE +#define CMIC_MASK_NO_CONSOLE SEE_MASK_NO_CONSOLE +#define CMIC_MASK_HASLINKNAME SEE_MASK_HASLINKNAME +#define CMIC_MASK_FLAG_SEP_VDM SEE_MASK_FLAG_SEPVDM +#define CMIC_MASK_HASTITLE SEE_MASK_HASTITLE +#define CMIC_MASK_ASYNCOK SEE_MASK_ASYNCOK + +#define CMIC_MASK_PTINVOKE 0x20000000 + +/*NOTE: When SEE_MASK_HMONITOR is set, hIcon is treated as hMonitor */ +typedef struct _CMINVOKECOMMANDINFO +{ DWORD cbSize; // sizeof(CMINVOKECOMMANDINFO) + DWORD fMask; // any combination of CMIC_MASK_* + HWND32 hwnd; // might be NULL (indicating no owner window) + LPCSTR lpVerb; // either a string or MAKEINTRESOURCE(idOffset) + LPCSTR lpParameters; // might be NULL (indicating no parameter) + LPCSTR lpDirectory; // might be NULL (indicating no specific directory) + int nShow; // one of SW_ values for ShowWindow() API + + DWORD dwHotKey; + HANDLE32 hIcon; +} CMINVOKECOMMANDINFO, *LPCMINVOKECOMMANDINFO; + +typedef struct _CMInvokeCommandInfoEx +{ DWORD cbSize; // must be sizeof(CMINVOKECOMMANDINFOEX) + DWORD fMask; // any combination of CMIC_MASK_* + HWND32 hwnd; // might be NULL (indicating no owner window) + LPCSTR lpVerb; // either a string or MAKEINTRESOURCE(idOffset) + LPCSTR lpParameters; // might be NULL (indicating no parameter) + LPCSTR lpDirectory; // might be NULL (indicating no specific directory) + int nShow; // one of SW_ values for ShowWindow() API + + DWORD dwHotKey; + + HANDLE32 hIcon; + LPCSTR lpTitle; // For CreateProcess-StartupInfo.lpTitle + LPCWSTR lpVerbW; // Unicode verb (for those who can use it) + LPCWSTR lpParametersW; // Unicode parameters (for those who can use it) + LPCWSTR lpDirectoryW; // Unicode directory (for those who can use it) + LPCWSTR lpTitleW; // Unicode title (for those who can use it) + POINT32 ptInvoke; // Point where it's invoked + +} CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX; + + +typedef struct IContextMenu_VTable +{ // *** IUnknown methods *** + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + STDMETHOD(QueryContextMenu)(THIS_ HMENU32 hmenu,UINT32 indexMenu,UINT32 idCmdFirst, UINT32 idCmdLast,UINT32 uFlags) PURE; + STDMETHOD(InvokeCommand)(THIS_ LPCMINVOKECOMMANDINFO lpici) PURE; + STDMETHOD(GetCommandString)(THIS_ UINT32 idCmd,UINT32 uType,UINT32 * pwReserved,LPSTR pszName,UINT32 cchMax) PURE; +} IContextMenu_VTable,*LPCONTEXTMENU_VTABLE; + +struct IContextMenu +{ LPCONTEXTMENU_VTABLE lpvtbl; + DWORD ref; + LPSHELLFOLDER pSFParent; + LPITEMIDLIST *aPidls; + LPPIDLMGR pPidlMgr; + BOOL32 bAllValues; +}; + +#undef THIS +/***************************************************************************** + * IShellExtInit interface + */ +#define THIS LPSHELLEXTINIT this + +typedef struct IShellExtInit_VTable +{ // *** IUnknown methods *** + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // *** IShellExtInit methods *** + STDMETHOD(Initialize)(THIS_ LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY hkeyProgID) PURE; +} IShellExtInit_VTable,*LPSHELLEXTINIT_VTABLE; + +struct IShellExtInit +{ LPSHELLEXTINIT_VTABLE lpvtbl; + DWORD ref; +}; + #undef THIS /***************************************************************************** @@ -310,16 +446,20 @@ typedef struct IShellFolder_VTable { 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,LPCOLESTR32 lpszName, DWORD uFlags,LPITEMIDLIST * ppidlOut) PURE; + + /* utility functions */ + STDMETHOD_(BOOL32,GetFolderPath)(THIS_ LPSTR, DWORD); + } *LPSHELLFOLDER_VTABLE,IShellFolder_VTable; struct tagSHELLFOLDER { LPSHELLFOLDER_VTABLE lpvtbl; - DWORD ref; - LPSTR mlpszFolder; - LPPIDLMGR pPidlMgr; - LPITEMIDLIST mpidl; - LPITEMIDLIST mpidlNSRoot; - LPSHELLFOLDER mpSFParent; + DWORD ref; + LPSTR mlpszFolder; + LPPIDLMGR pPidlMgr; + LPITEMIDLIST mpidl; + LPITEMIDLIST mpidlNSRoot; + LPSHELLFOLDER mpSFParent; }; extern LPSHELLFOLDER pdesktopfolder; @@ -330,6 +470,12 @@ extern LPSHELLFOLDER pdesktopfolder; */ #define THIS LPSHELLBROWSER this +#define FCW_STATUS 0x0001 +#define FCW_TOOLBAR 0x0002 +#define FCW_TREE 0x0003 +#define FCW_INTERNETBAR 0x0006 +#define FCW_PROGRESS 0x0008 + typedef struct IShellBrowser_VTable { // *** IUnknown methods *** STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; @@ -383,6 +529,42 @@ struct tagSHELLBROWSER #define SVGIO_SELECTION 0x00000001 #define SVGIO_ALLVIEW 0x00000002 +/* The explorer dispatches WM_COMMAND messages based on the range of + command/menuitem IDs. All the IDs of menuitems that the view (right + pane) inserts must be in FCIDM_SHVIEWFIRST/LAST (otherwise, the explorer + won't dispatch them). The view should not deal with any menuitems + in FCIDM_BROWSERFIRST/LAST (otherwise, it won't work with the future + version of the shell). + + FCIDM_SHVIEWFIRST/LAST for the right pane (IShellView) + FCIDM_BROWSERFIRST/LAST for the explorer frame (IShellBrowser) + FCIDM_GLOBAL/LAST for the explorer's submenu IDs +*/ +#define FCIDM_SHVIEWFIRST 0x0000 +#define FCIDM_SHVIEWLAST 0x7fff +#define FCIDM_BROWSERFIRST 0xa000 +#define FCIDM_BROWSERLAST 0xbf00 +#define FCIDM_GLOBALFIRST 0x8000 +#define FCIDM_GLOBALLAST 0x9fff + +/* +* Global submenu IDs and separator IDs +*/ +#define FCIDM_MENU_FILE (FCIDM_GLOBALFIRST+0x0000) +#define FCIDM_MENU_EDIT (FCIDM_GLOBALFIRST+0x0040) +#define FCIDM_MENU_VIEW (FCIDM_GLOBALFIRST+0x0080) +#define FCIDM_MENU_VIEW_SEP_OPTIONS (FCIDM_GLOBALFIRST+0x0081) +#define FCIDM_MENU_TOOLS (FCIDM_GLOBALFIRST+0x00c0) +#define FCIDM_MENU_TOOLS_SEP_GOTO (FCIDM_GLOBALFIRST+0x00c1) +#define FCIDM_MENU_HELP (FCIDM_GLOBALFIRST+0x0100) +#define FCIDM_MENU_FIND (FCIDM_GLOBALFIRST+0x0140) +#define FCIDM_MENU_EXPLORE (FCIDM_GLOBALFIRST+0x0150) +#define FCIDM_MENU_FAVORITES (FCIDM_GLOBALFIRST+0x0170) + +/* control IDs known to the view */ +#define FCIDM_TOOLBAR (FCIDM_BROWSERFIRST + 0) +#define FCIDM_STATUS (FCIDM_BROWSERFIRST + 1) + /* uState values for IShellView::UIActivate */ typedef enum { SVUIA_DEACTIVATE = 0, @@ -424,8 +606,11 @@ struct tagSHELLVIEW LPSHELLFOLDER pSFParent; LPSHELLBROWSER pShellBrowser; HWND32 hWnd; + HWND32 hWndList; FOLDERSETTINGS FolderSettings; HWND32 hWndParent; + HMENU32 hMenu; + UINT32 uState; }; typedef GUID SHELLVIEWID; @@ -498,19 +683,173 @@ struct IShellLink { #undef THIS -#ifdef __WINE__ +/**************************************************************************** + * IExtractIcon interface + * + * FIXME + * Is the ExtractIconA interface + */ +#define THIS LPEXTRACTICON this +/* GetIconLocation() input flags*/ +#define GIL_OPENICON 0x0001 // allows containers to specify an "open" look +#define GIL_FORSHELL 0x0002 // icon is to be displayed in a ShellFolder +#define GIL_ASYNC 0x0020 // this is an async extract, return E_ASYNC + +/* GetIconLocation() return flags */ +#define GIL_SIMULATEDOC 0x0001 // simulate this document icon for this +#define GIL_PERINSTANCE 0x0002 // icons from this class are per instance (each file has its own) +#define GIL_PERCLASS 0x0004 // icons from this class per class (shared for all files of this type) +#define GIL_NOTFILENAME 0x0008 // location is not a filename, must call ::ExtractIcon +#define GIL_DONTCACHE 0x0010 // this icon should not be cached + +typedef struct IExtractIcon IExtractIcon,*LPEXTRACTICON; +typedef struct IExtractIcon_VTable +{ /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IExtractIcon methods ***/ + STDMETHOD(GetIconLocation)(THIS_ UINT32 uFlags, LPSTR szIconFile, UINT32 cchMax, int * piIndex, UINT32 * pwFlags) PURE; + STDMETHOD(Extract)(THIS_ LPCSTR pszFile, UINT32 nIconIndex, HICON32 *phiconLarge, HICON32 *phiconSmall, UINT32 nIconSize) PURE; +}IExtractIccon_VTable,*LPEXTRACTICON_VTABLE; + +struct IExtractIcon +{ LPEXTRACTICON_VTABLE lpvtbl; + DWORD ref; + LPITEMIDLIST pidl; +}; + +#undef THIS +/**************************************************************************** + * IShellIcon interface + */ + +#define THIS LPSHELLICON this +typedef struct IShellIcon IShellIcon,*LPSHELLICON; +typedef struct IShellIcon_VTable +{ /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IShellIcon methods ***/ + STDMETHOD(GetIconOf)(THIS_ LPCITEMIDLIST pidl, UINT32 flags, LPINT32 lpIconIndex) PURE; +} IShellIcon_VTable,*LPSHELLICON_VTABLE; + +struct IShellIcon +{ LPSHELLICON_VTABLE lpvtbl; + DWORD ref; +}; +#undef THIS + + +/**************************************************************************** + * Class constructors + */ +#ifdef __WINE__ extern LPCLASSFACTORY IClassFactory_Constructor(); +extern LPCONTEXTMENU IContextMenu_Constructor(LPSHELLFOLDER, LPCITEMIDLIST *, UINT32); extern LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER,LPITEMIDLIST); extern LPSHELLVIEW IShellView_Constructor(); extern LPSHELLLINK IShellLink_Constructor(); extern LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD,HRESULT*); +extern LPEXTRACTICON IExtractIcon_Constructor(LPITEMIDLIST); #endif +/**************************************************************************** + * Shell Execute API + */ +#define SE_ERR_FNF 2 // file not found +#define SE_ERR_PNF 3 // path not found +#define SE_ERR_ACCESSDENIED 5 // access denied +#define SE_ERR_OOM 8 // out of memory +#define SE_ERR_DLLNOTFOUND 32 +#define SE_ERR_SHARE 26 +#define SE_ERR_ASSOCINCOMPLETE 27 +#define SE_ERR_DDETIMEOUT 28 +#define SE_ERR_DDEFAIL 29 +#define SE_ERR_DDEBUSY 30 +#define SE_ERR_NOASSOC 31 + +#define SEE_MASK_CLASSNAME 0x00000001 +#define SEE_MASK_CLASSKEY 0x00000003 +#define SEE_MASK_IDLIST 0x00000004 +#define SEE_MASK_INVOKEIDLIST 0x0000000c +#define SEE_MASK_ICON 0x00000010 +#define SEE_MASK_HOTKEY 0x00000020 +#define SEE_MASK_NOCLOSEPROCESS 0x00000040 +#define SEE_MASK_CONNECTNETDRV 0x00000080 +#define SEE_MASK_FLAG_DDEWAIT 0x00000100 +#define SEE_MASK_DOENVSUBST 0x00000200 +#define SEE_MASK_FLAG_NO_UI 0x00000400 +#define SEE_MASK_UNICODE 0x00004000 +#define SEE_MASK_NO_CONSOLE 0x00008000 +#define SEE_MASK_ASYNCOK 0x00100000 +#define SEE_MASK_HMONITOR 0x00200000 + +typedef struct _SHELLEXECUTEINFOA +{ DWORD cbSize; + ULONG fMask; + HWND32 hwnd; + LPCSTR lpVerb; + LPCSTR lpFile; + LPCSTR lpParameters; + LPCSTR lpDirectory; + int nShow; + HINSTANCE32 hInstApp; + /* Optional fields */ + LPVOID lpIDList; + LPCSTR lpClass; + HKEY hkeyClass; + DWORD dwHotKey; + union + { HANDLE32 hIcon; + HANDLE32 hMonitor; + } u; + HANDLE32 hProcess; +} SHELLEXECUTEINFOA, *LPSHELLEXECUTEINFOA; + +typedef struct _SHELLEXECUTEINFOW +{ DWORD cbSize; + ULONG fMask; + HWND32 hwnd; + LPCWSTR lpVerb; + LPCWSTR lpFile; + LPCWSTR lpParameters; + LPCWSTR lpDirectory; + int nShow; + HINSTANCE32 hInstApp; + /* Optional fields*/ + LPVOID lpIDList; + LPCWSTR lpClass; + HKEY hkeyClass; + DWORD dwHotKey; + union + { HANDLE32 hIcon; + HANDLE32 hMonitor; + } u; + HANDLE32 hProcess; +} SHELLEXECUTEINFOW, *LPSHELLEXECUTEINFOW; + +DECL_WINELIB_TYPE_AW(SHELLEXECUTEINFO) + +typedef SHELLEXECUTEINFOA SHELLEXECUTEINFO; +typedef LPSHELLEXECUTEINFOA LPSHELLEXECUTEINFO; + +BOOL32 WINAPI ShellExecuteEx32A(LPSHELLEXECUTEINFOA lpExecInfo); +BOOL32 WINAPI ShellExecuteEx32W(LPSHELLEXECUTEINFOW lpExecInfo); +#define ShellExecuteEx WINELIB_NAME_AW(ShellExecuteEx) + +void WINAPI WinExecErrorA(HWND32 hwnd, int error, LPCSTR lpstrFileName, LPCSTR lpstrTitle); +void WINAPI WinExecErrorW(HWND32 hwnd, int error, LPCWSTR lpstrFileName, LPCWSTR lpstrTitle); +#define WinExecError WINELIB_NAME_AW(WinExecError) + + /**************************************************************************** * SHBrowseForFolder API */ - typedef int (CALLBACK* BFFCALLBACK)(HWND32 hwnd, UINT32 uMsg, LPARAM lParam, LPARAM lpData); typedef struct tagBROWSEINFO32A { @@ -585,8 +924,9 @@ LPITEMIDLIST WINAPI SHBrowseForFolder32A(LPBROWSEINFO32A lpbi); #define SHBrowseForFolder WINELIB_NAME_AW(SHBrowseForFolder) /**************************************************************************** - * shlview structures - */ +* shlview structures +*/ + /* * IShellFolderViewCallback Callback * This "callback" is called by the shells default IShellView implementation (that @@ -619,6 +959,29 @@ typedef struct _SHELLVIEWDATA // idl DWORD viewmode; // NF_* enum } SHELLVIEWDATA, * LPSHELLVIEWDATA; +/* + The shell keeps track of some per-user state to handle display + options that is of major interest to ISVs. + The key one requested right now is "DoubleClickInWebView". +*/ +typedef struct +{ BOOL32 fShowAllObjects : 1; + BOOL32 fShowExtensions : 1; + BOOL32 fNoConfirmRecycle : 1; + BOOL32 fShowSysFiles : 1; + BOOL32 fShowCompColor : 1; + BOOL32 fDoubleClickInWebView : 1; + BOOL32 fDesktopHTML : 1; + BOOL32 fWin95Classic : 1; + BOOL32 fDontPrettyPath : 1; + BOOL32 fShowAttribCol : 1; + BOOL32 fMapNetDrvBtn : 1; + BOOL32 fShowInfoTip : 1; + BOOL32 fHideIcons : 1; + UINT32 fRestFlags : 3; +} SHELLFLAGSTATE, * LPSHELLFLAGSTATE; + + #undef PURE #undef FAR #undef THIS diff --git a/include/sig_context.h b/include/sig_context.h index 595d91cab9f..315564f47f4 100644 --- a/include/sig_context.h +++ b/include/sig_context.h @@ -217,10 +217,10 @@ typedef struct _CONTEXT /* Note 1 */ #define FL_sig(context) (*(WORD*)&EFL_sig(context)) #ifdef FS_sig -extern WORD CALLTO16_Current_fs; +#include "syslevel.h" #define HANDLER_INIT() \ SET_FS(IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)) ? \ - FS_sig(HANDLER_CONTEXT) : CALLTO16_Current_fs) + FS_sig(HANDLER_CONTEXT) : SYSLEVEL_Win16CurrentTeb) #else #define HANDLER_INIT() /* nothing */ #endif diff --git a/include/syslevel.h b/include/syslevel.h index 56ac8461843..e1510758ea4 100644 --- a/include/syslevel.h +++ b/include/syslevel.h @@ -10,6 +10,8 @@ #include "wintypes.h" #include "winbase.h" +extern WORD SYSLEVEL_Win16CurrentTeb; + void SYSLEVEL_Init(void); VOID SYSLEVEL_EnterWin16Lock(VOID); VOID SYSLEVEL_LeaveWin16Lock(VOID); diff --git a/include/task.h b/include/task.h index 85f38cb62a4..bde03512b2f 100644 --- a/include/task.h +++ b/include/task.h @@ -147,6 +147,7 @@ extern THHOOK *pThhook; extern HTASK16 TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule, HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance, UINT16 cmdShow ); +extern void TASK_StartTask( HTASK16 hTask ); extern void TASK_KillCurrentTask( INT16 exitCode ); extern HTASK16 TASK_GetNextTask( HTASK16 hTask ); extern void TASK_Reschedule(void); diff --git a/include/thread.h b/include/thread.h index e033b297fa7..58ad89a64e9 100644 --- a/include/thread.h +++ b/include/thread.h @@ -44,6 +44,7 @@ typedef struct BOOL32 wait_all; /* Wait for all objects flag */ BOOL32 wait_msg; /* Wait for message flag */ K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */ + int server[MAXIMUM_WAIT_OBJECTS]; /* Server handles */ } WAIT_STRUCT; /* Thread database */ @@ -128,6 +129,7 @@ extern THDB *THREAD_Create( struct _PDB32 *pdb, DWORD stack_size, int *server_thandle, int *server_phandle, LPTHREAD_START_ROUTINE start_addr, LPVOID param ); extern THDB *THREAD_Current(void); +extern BOOL32 THREAD_IsWin16( THDB *thdb ); extern void THREAD_Start( THDB *thdb ); extern THDB *THREAD_GetPtr( HANDLE32 handle, DWORD access, int *server_handle ); extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread ); diff --git a/include/toolbar.h b/include/toolbar.h index fc0573928fa..4af9f98ff8b 100644 --- a/include/toolbar.h +++ b/include/toolbar.h @@ -32,17 +32,18 @@ typedef struct tagTOOLBAR_INFO INT32 nBitmapHeight; INT32 nBitmapWidth; INT32 nIndent; - INT32 nMaxRows; /* maximum number of rows */ - + INT32 nMaxRows; /* maximum number of button rows */ + INT32 nMaxTextRows; /* maximum number of text rows */ + INT32 cxMin; /* minimum button width */ + INT32 cxMax; /* maximum button width */ INT32 nNumButtons; /* number of buttons */ INT32 nNumBitmaps; /* number of bitmaps */ INT32 nNumStrings; /* number of strings */ - - BOOL32 bCaptured; + BOOL32 bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */ + BOOL32 bCaptured; /* mouse captured? */ INT32 nButtonDown; INT32 nOldHit; INT32 nHotItem; /* index of the "hot" item */ - HFONT32 hFont; /* text font */ HIMAGELIST himlDef; /* default image list */ HIMAGELIST himlHot; /* hot image list */ @@ -50,12 +51,13 @@ typedef struct tagTOOLBAR_INFO HWND32 hwndToolTip; /* handle to tool tip control */ HWND32 hwndNotify; /* handle to the window that gets notifications */ BOOL32 bTransparent; /* background transparency flag */ - BOOL32 bAutoSize; + BOOL32 bAutoSize; /* auto size deadlock indicator */ DWORD dwExStyle; /* extended toolbar style */ + SIZE32 maxSize; /* maximum toolbar size */ COLORREF clrInsertMark; /* insert mark color */ - TBUTTON_INFO *buttons; + TBUTTON_INFO *buttons; /* pointer to button array */ CHAR **strings; } TOOLBAR_INFO; diff --git a/include/tooltips.h b/include/tooltips.h index b4875c08834..2750cb47b55 100644 --- a/include/tooltips.h +++ b/include/tooltips.h @@ -8,6 +8,14 @@ #define __WINE_TOOLTIPS_H +typedef struct tagTT_SUBCLASS_INFO +{ + WNDPROC32 wpOrigProc; + HWND32 hwndToolTip; + UINT32 uRefCount; +} TT_SUBCLASS_INFO, *LPTT_SUBCLASS_INFO; + + typedef struct tagTTTOOL_INFO { UINT32 uFlags; @@ -17,8 +25,6 @@ typedef struct tagTTTOOL_INFO HINSTANCE32 hinst; LPSTR lpszText; LPARAM lParam; - - WNDPROC32 lpfnOrigProc; } TTTOOL_INFO; diff --git a/include/tweak.h b/include/tweak.h index 346f6a06f6a..06bffee88d1 100644 --- a/include/tweak.h +++ b/include/tweak.h @@ -11,8 +11,8 @@ #include "wintypes.h" -int TWEAK_Init(); -int TWEAK_CheckConfiguration(); +int TWEAK_Init(void); +int TWEAK_CheckConfiguration(void); void TWEAK_DrawReliefRect95(HDC32, RECT32 const *); void TWEAK_DrawRevReliefRect95(HDC32, RECT32 const *); void TWEAK_DrawMenuSeparatorHoriz95(HDC32, UINT32, UINT32, UINT32); diff --git a/include/version.h b/include/version.h index 2311c019d8e..a6ca1205389 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define WINE_RELEASE_INFO "Wine release 980809" +#define WINE_RELEASE_INFO "Wine release 980822" diff --git a/include/winbase.h b/include/winbase.h index b4cc23666e2..16938f22e23 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -7,6 +7,7 @@ #define WAIT_OBJECT_0 0 #define WAIT_ABANDONED STATUS_ABANDONED_WAIT_0 #define WAIT_ABANDONED_0 STATUS_ABANDONED_WAIT_0 +#define WAIT_IO_COMPLETION STATUS_USER_APC #define WAIT_TIMEOUT STATUS_TIMEOUT #define PAGE_NOACCESS 0x01 @@ -189,6 +190,7 @@ void WINAPI InitializeCriticalSection(CRITICAL_SECTION *lpCrit); void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit); HANDLE32 WINAPI OpenProcess(DWORD access, BOOL32 inherit, DWORD id); void WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD); -int WINAPI TerminateProcess(HANDLE32 h, int ret); +BOOL32 WINAPI TerminateProcess(HANDLE32,DWORD); +BOOL32 WINAPI TerminateThread(HANDLE32,DWORD); #endif /* __WINE_WINBASE_H */ diff --git a/include/windows.h b/include/windows.h index a94c819d02b..e5c9f74f69e 100644 --- a/include/windows.h +++ b/include/windows.h @@ -1073,6 +1073,10 @@ typedef DWORD COLORREF; #define CTLCOLOR_SCROLLBAR 5 #define CTLCOLOR_STATIC 6 +#define ICM_OFF 1 +#define ICM_ON 2 +#define ICM_QUERY 3 + /* Bitmaps */ typedef struct @@ -2165,6 +2169,7 @@ typedef struct BYTE pad0; WORD key; WORD cmd; + WORD pad1; } ACCEL32, *LPACCEL32; DECL_WINELIB_TYPE(ACCEL) @@ -3178,6 +3183,7 @@ typedef struct #define WM_MDICASCADE 0x0227 #define WM_MDIICONARRANGE 0x0228 #define WM_MDIGETACTIVE 0x0229 +#define WM_MDIREFRESHMENU 0x0234 /* D&D messages */ #define WM_DROPOBJECT 0x022A @@ -5282,6 +5288,27 @@ typedef struct { #define TIME_ZONE_ID_STANDARD 1 #define TIME_ZONE_ID_DAYLIGHT 2 +/* CreateProcess: dwCreationFlag values + */ +#define DEBUG_PROCESS 0x00000001 +#define DEBUG_ONLY_THIS_PROCESS 0x00000002 +#define CREATE_SUSPENDED 0x00000004 +#define DETACHED_PROCESS 0x00000008 +#define CREATE_NEW_CONSOLE 0x00000010 +#define NORMAL_PRIORITY_CLASS 0x00000020 +#define IDLE_PRIORITY_CLASS 0x00000040 +#define HIGH_PRIORITY_CLASS 0x00000080 +#define REALTIME_PRIORITY_CLASS 0x00000100 +#define CREATE_NEW_PROCESS_GROUP 0x00000200 +#define CREATE_UNICODE_ENVIRONMENT 0x00000400 +#define CREATE_SEPARATE_WOW_VDM 0x00000800 +#define CREATE_SHARED_WOW_VDM 0x00001000 +#define CREATE_DEFAULT_ERROR_MODE 0x04000000 +#define CREATE_NO_WINDOW 0x08000000 +#define PROFILE_USER 0x10000000 +#define PROFILE_KERNEL 0x20000000 +#define PROFILE_SERVER 0x40000000 + /* File object type definitions */ @@ -6312,6 +6339,7 @@ INT16 WINAPI GetCommError(INT16,LPCOMSTAT); UINT16 WINAPI GetCommEventMask(INT16,UINT16); HBRUSH16 WINAPI GetControlBrush(HWND16,HDC16,UINT16); VOID WINAPI GetCodeInfo(FARPROC16,LPVOID); +HFONT16 WINAPI GetCurLogFont(HDC16); HANDLE16 WINAPI GetCurrentPDB(void); DWORD WINAPI GetCurrentPosition(HDC16); HTASK16 WINAPI GetCurrentTask(void); @@ -6336,6 +6364,7 @@ FARPROC16 WINAPI GetMouseEventProc(void); UINT16 WINAPI GetNumTasks(void); DWORD WINAPI GetSelectorBase(WORD); DWORD WINAPI GetSelectorLimit(WORD); +FARPROC16 WINAPI GetSetKernelDOSProc(FARPROC16 DosProc); HINSTANCE16 WINAPI GetTaskDS(void); HQUEUE16 WINAPI GetTaskQueue(HTASK16); BYTE WINAPI GetTempDrive(BYTE); @@ -6375,6 +6404,7 @@ WORD WINAPI LocalHandleDelta(WORD); WORD WINAPI LocalHeapSize(void); HICON16 WINAPI LoadIconHandler(HGLOBAL16,BOOL16); BOOL16 WINAPI LocalInit(HANDLE16,WORD,WORD); +HMODULE32 WINAPI LoadLibraryEx32W16(LPCSTR,HANDLE16,DWORD); FARPROC16 WINAPI LocalNotify(FARPROC16); HTASK16 WINAPI LockCurrentTask(BOOL16); HMENU16 WINAPI LookupMenuHandle(HMENU16,INT16); @@ -6467,6 +6497,13 @@ HICON32 WINAPI CreateIconIndirect(LPICONINFO); HANDLE32 WINAPI CreateMutex32A(LPSECURITY_ATTRIBUTES,BOOL32,LPCSTR); HANDLE32 WINAPI CreateMutex32W(LPSECURITY_ATTRIBUTES,BOOL32,LPCWSTR); #define CreateMutex WINELIB_NAME_AW(CreateMutex) +BOOL32 WINAPI CreateProcess32A(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES,BOOL32,DWORD,LPVOID,LPCSTR, + LPSTARTUPINFO32A,LPPROCESS_INFORMATION); +BOOL32 WINAPI CreateProcess32W(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES,BOOL32,DWORD,LPVOID,LPCWSTR, + LPSTARTUPINFO32W,LPPROCESS_INFORMATION); +#define CreateProcess WINELIB_NAME_AW(CreateProcess) HANDLE32 WINAPI CreateSemaphore32A(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR); HANDLE32 WINAPI CreateSemaphore32W(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR); #define CreateSemaphore WINELIB_NAME_AW(CreateSemaphore) @@ -6508,12 +6545,19 @@ DWORD WINAPI ExpandEnvironmentStrings32A(LPCSTR,LPSTR,DWORD); DWORD WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD); #define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings) HRGN32 WINAPI ExtCreateRegion(LPXFORM,DWORD,LPRGNDATA); +INT32 WINAPI ExtEscape32(HDC32,INT32,INT32,LPCSTR,INT32,LPSTR); BOOL32 WINAPI FileTimeToDosDateTime(const FILETIME*,LPWORD,LPWORD); BOOL32 WINAPI FileTimeToLocalFileTime(const FILETIME*,LPFILETIME); BOOL32 WINAPI FileTimeToSystemTime(const FILETIME*,LPSYSTEMTIME); +HANDLE32 WINAPI FindFirstChangeNotification32A(LPCSTR,BOOL32,DWORD); +HANDLE32 WINAPI FindFirstChangeNotification32W(LPCWSTR,BOOL32,DWORD); +#define FindFirstChangeNotification WINELIB_NAME_AW(FindFirstChangeNotification) +BOOL32 WINAPI FindNextChangeNotification(HANDLE32); +BOOL32 WINAPI FindCloseChangeNotification(HANDLE32); HRSRC32 WINAPI FindResourceEx32A(HMODULE32,LPCSTR,LPCSTR,WORD); HRSRC32 WINAPI FindResourceEx32W(HMODULE32,LPCWSTR,LPCWSTR,WORD); #define FindResourceEx WINELIB_NAME_AW(FindResourceEx) +BOOL32 WINAPI FixBrushOrgEx(HDC32,INT32,INT32,LPPOINT32); BOOL32 WINAPI FlushConsoleInputBuffer(HANDLE32); BOOL32 WINAPI FlushFileBuffers(HFILE32); BOOL32 WINAPI FlushViewOfFile(LPCVOID, DWORD); @@ -6525,16 +6569,16 @@ BOOL32 WINAPI FreeEnvironmentStrings32A(LPSTR); BOOL32 WINAPI FreeEnvironmentStrings32W(LPWSTR); #define FreeEnvironmentStrings WINELIB_NAME_AW(FreeEnvironmentStrings) UINT32 WINAPI GetACP(void); -LPCSTR WINAPI GetCommandLine32A(); -LPCWSTR WINAPI GetCommandLine32W(); +LPCSTR WINAPI GetCommandLine32A(void); +LPCWSTR WINAPI GetCommandLine32W(void); #define GetCommandLine WINELIB_NAME_AW(GetCommandLine) BOOL32 WINAPI GetCommTimeouts(INT32,LPCOMMTIMEOUTS); BOOL32 WINAPI GetComputerName32A(LPSTR,LPDWORD); BOOL32 WINAPI GetComputerName32W(LPWSTR,LPDWORD); #define GetComputerName WINELIB_NAME_AW(GetComputerName) -UINT32 WINAPI GetConsoleCP(); +UINT32 WINAPI GetConsoleCP(void); BOOL32 WINAPI GetConsoleMode(HANDLE32,LPDWORD); -UINT32 WINAPI GetConsoleOutputCP(); +UINT32 WINAPI GetConsoleOutputCP(void); DWORD WINAPI GetConsoleTitle32A(LPSTR,DWORD); DWORD WINAPI GetConsoleTitle32W(LPWSTR,DWORD); #define GetConsoleTitle WINELIB_NAME_AW(GetConsoleTitle) @@ -6580,6 +6624,8 @@ DWORD WINAPI GetLogicalDrives(void); DWORD WINAPI GetLongPathName32A(LPCSTR,LPSTR,DWORD); DWORD WINAPI GetLongPathName32W(LPCWSTR,LPWSTR,DWORD); #define GetLongPathName WINELIB_NAME_AW(GetLongPathName) +UINT32 WINAPI GetMenuDefaultItem32(HMENU32,UINT32,UINT32); +#define GetMenuDefaultItem WINELIB_NAME(GetMenuDefaultItem) BOOL32 WINAPI GetMenuItemInfo32A(HMENU32,UINT32,BOOL32,MENUITEMINFO32A*); BOOL32 WINAPI GetMenuItemInfo32W(HMENU32,UINT32,BOOL32,MENUITEMINFO32W*); #define GetMenuItemInfo WINELIB_NAME_AW(GetMenuItemInfo) @@ -6589,9 +6635,6 @@ BOOL32 WINAPI GetNumberOfConsoleMouseButtons(LPDWORD); DWORD WINAPI GetObjectType(HANDLE32); UINT32 WINAPI GetOEMCP(void); DWORD WINAPI GetPriorityClass(HANDLE32); -INT32 WINAPI GetPrivateProfileSection32A(LPCSTR,LPSTR,UINT32,LPCSTR); -INT32 WINAPI GetPrivateProfileSection32W(LPCWSTR,LPWSTR,UINT32,LPCWSTR); -#define GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection) HANDLE32 WINAPI GetProcessHeap(void); DWORD WINAPI GetRegionData(HRGN32,DWORD,LPRGNDATA); DWORD WINAPI GetShortPathName32A(LPCSTR,LPSTR,DWORD); @@ -6613,7 +6656,7 @@ BOOL32 WINAPI GetTextExtentExPoint32W(HDC32,LPCWSTR,INT32,INT32, INT32 WINAPI GetTimeFormat32A(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT32); INT32 WINAPI GetTimeFormat32W(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT32); #define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat) -LCID WINAPI GetThreadLocale(); +LCID WINAPI GetThreadLocale(void); INT32 WINAPI GetThreadPriority(HANDLE32); BOOL32 WINAPI GetThreadSelectorEntry(HANDLE32,DWORD,LPLDT_ENTRY); BOOL32 WINAPI GetUserName32A(LPSTR,LPDWORD); @@ -6645,6 +6688,8 @@ BOOL32 WINAPI LockFile(HFILE32,DWORD,DWORD,DWORD,DWORD); BOOL32 WINAPI LookupPrivilegeValue32A(LPCSTR,LPCSTR,LPVOID); BOOL32 WINAPI LookupPrivilegeValue32W(LPCWSTR,LPCWSTR,LPVOID); #define LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue) +HMODULE32 WINAPI MapHModuleSL(HMODULE16); +HMODULE16 WINAPI MapHModuleLS(HMODULE32); SEGPTR WINAPI MapLS(LPVOID); LPVOID WINAPI MapSL(SEGPTR); LPVOID WINAPI MapViewOfFile(HANDLE32,DWORD,DWORD,DWORD,DWORD); @@ -6682,8 +6727,10 @@ HANDLE32 WINAPI OpenSemaphore32W(DWORD,BOOL32,LPCWSTR); HANDLE32 WINAPI OpenService32A(HANDLE32,LPCSTR,DWORD); HANDLE32 WINAPI OpenService32W(HANDLE32,LPCWSTR,DWORD); #define OpenService WINELIB_NAME_AW(OpenService) +BOOL32 WINAPI PaintDesktop(HDC32); BOOL32 WINAPI PlayEnhMetaFile(HDC32,HENHMETAFILE32,const RECT32*); BOOL32 WINAPI PlayEnhMetaFileRecord(HDC32,LPHANDLETABLE32,const ENHMETARECORD*,UINT32); +BOOL32 WINAPI PolyPolyline32(HDC32,LPPOINT32,LPDWORD,DWORD); BOOL32 WINAPI PulseEvent(HANDLE32); DWORD WINAPI QueryDosDevice32A(LPCSTR,LPSTR,DWORD); DWORD WINAPI QueryDosDevice32W(LPCWSTR,LPWSTR,DWORD); @@ -6775,6 +6822,8 @@ BOOL32 WINAPI SetFileTime(HFILE32,const FILETIME*,const FILETIME*, INT32 WINAPI SetGraphicsMode(HDC32,INT32); BOOL32 WINAPI SetHandleInformation(HANDLE32,DWORD,DWORD); VOID WINAPI SetLastErrorEx(DWORD,DWORD); +BOOL32 WINAPI SetMenuDefaultItem32(HMENU32,UINT32,UINT32); +#define SetMenuDefaultItem WINELIB_NAME(SetMenuDefaultItem) BOOL32 WINAPI SetMenuItemInfo32A(HMENU32,UINT32,BOOL32,const MENUITEMINFO32A*); BOOL32 WINAPI SetMenuItemInfo32W(HMENU32,UINT32,BOOL32,const MENUITEMINFO32W*); #define SetMenuItemInfo WINELIB_NAME_AW(SetMenuItemInfo) @@ -6802,6 +6851,7 @@ DWORD WINAPI TlsAlloc(void); BOOL32 WINAPI TlsFree(DWORD); LPVOID WINAPI TlsGetValue(DWORD); BOOL32 WINAPI TlsSetValue(DWORD,LPVOID); +BOOL32 WINAPI TranslateCharsetInfo(LPDWORD,LPCHARSETINFO,DWORD); VOID WINAPI UnMapLS(SEGPTR); BOOL32 WINAPI UnlockFile(HFILE32,DWORD,DWORD,DWORD,DWORD); BOOL32 WINAPI UnmapViewOfFile(LPVOID); @@ -6862,6 +6912,7 @@ LANGID WINAPI GetUserDefaultLangID(void); LCID WINAPI GetUserDefaultLCID(void); ATOM WINAPI GlobalDeleteAtom(ATOM); VOID WINAPI LZDone(void); +VOID WINAPI ScreenSwitchEnable(WORD); DWORD WINAPI OemKeyScan(WORD); DWORD WINAPI RegCloseKey(HKEY); DWORD WINAPI RegFlushKey(HKEY); @@ -7023,6 +7074,9 @@ DWORD WINAPI CheckMenuItem32(HMENU32,UINT32,UINT32); BOOL16 WINAPI CheckMenuRadioButton16(HMENU16,UINT16,UINT16,UINT16,BOOL16); BOOL32 WINAPI CheckMenuRadioButton32(HMENU32,UINT32,UINT32,UINT32,BOOL32); #define CheckMenuRadioButton WINELIB_NAME(CheckMenuRadioButton) +BOOL16 WINAPI CheckMenuRadioItem16(HMENU16,UINT16,UINT16,UINT16,UINT16); +BOOL32 WINAPI CheckMenuRadioItem32(HMENU32,UINT32,UINT32,UINT32,UINT32); +#define CheckMenuRadioItem WINELIB_NAME(CheckMenuRadioItem) BOOL16 WINAPI CheckRadioButton16(HWND16,UINT16,UINT16,UINT16); BOOL32 WINAPI CheckRadioButton32(HWND32,UINT32,UINT32,UINT32); #define CheckRadioButton WINELIB_NAME(CheckRadioButton) @@ -7067,6 +7121,9 @@ HCURSOR16 WINAPI CopyCursor16(HINSTANCE16,HCURSOR16); HICON16 WINAPI CopyIcon16(HINSTANCE16,HICON16); HICON32 WINAPI CopyIcon32(HICON32); #define CopyIcon WINELIB_NAME(CopyIcon) +HICON16 WINAPI CopyImage16(HANDLE16,UINT16,INT16,INT16,UINT16); +HICON32 WINAPI CopyImage32(HANDLE32,UINT32,INT32,INT32,UINT32); +#define CopyImage WINELIB_NAME(CopyImage) LONG WINAPI CopyLZFile16(HFILE16,HFILE16); LONG WINAPI CopyLZFile32(HFILE32,HFILE32); #define CopyLZFile WINELIB_NAME(CopyLZFile) @@ -7377,6 +7434,10 @@ BOOL32 WINAPI DrawIconEx32(HDC32,INT32,INT32,HICON32,INT32,INT32, VOID WINAPI DrawMenuBar16(HWND16); BOOL32 WINAPI DrawMenuBar32(HWND32); #define DrawMenuBar WINELIB_NAME(DrawMenuBar) +BOOL16 WINAPI DrawState16A(HDC16,HBRUSH16,DRAWSTATEPROC16,LPARAM,WPARAM16,INT16,INT16,INT16,INT16,UINT16); +BOOL32 WINAPI DrawState32A(HDC32,HBRUSH32,DRAWSTATEPROC32,LPARAM,WPARAM32,INT32,INT32,INT32,INT32,UINT32); +BOOL32 WINAPI DrawState32W(HDC32,HBRUSH32,DRAWSTATEPROC32,LPARAM,WPARAM32,INT32,INT32,INT32,INT32,UINT32); +#define DrawState WINELIB_NAME_AW(DrawState) INT16 WINAPI DrawText16(HDC16,LPCSTR,INT16,LPRECT16,UINT16); INT32 WINAPI DrawText32A(HDC32,LPCSTR,INT32,LPRECT32,UINT32); INT32 WINAPI DrawText32W(HDC32,LPCWSTR,INT32,LPRECT32,UINT32); @@ -7572,6 +7633,9 @@ UINT16 WINAPI GetAtomName16(ATOM,LPSTR,INT16); UINT32 WINAPI GetAtomName32A(ATOM,LPSTR,INT32); UINT32 WINAPI GetAtomName32W(ATOM,LPWSTR,INT32); #define GetAtomName WINELIB_NAME_AW(GetAtomName) +BOOL16 WINAPI GetAspectRatioFilterEx16(HDC16,LPSIZE16); +BOOL32 WINAPI GetAspectRatioFilterEx32(HDC32,LPSIZE32); +#define GetAspectRatioFilterEx WINELIB_NAME(GetAspectRatioFilterEx) LONG WINAPI GetBitmapBits16(HBITMAP16,LONG,LPVOID); LONG WINAPI GetBitmapBits32(HBITMAP32,LONG,LPVOID); #define GetBitmapBits WINELIB_NAME(GetBitmapBits) @@ -7600,6 +7664,9 @@ BOOL16 WINAPI GetCharABCWidths16(HDC16,UINT16,UINT16,LPABC16); BOOL32 WINAPI GetCharABCWidths32A(HDC32,UINT32,UINT32,LPABC32); BOOL32 WINAPI GetCharABCWidths32W(HDC32,UINT32,UINT32,LPABC32); #define GetCharABCWidths WINELIB_NAME_AW(GetCharABCWidths) +DWORD WINAPI GetCharacterPlacement32A(HDC32,LPCSTR,INT32,INT32,GCP_RESULTS32A*,DWORD); +DWORD WINAPI GetCharacterPlacement32W(HDC32,LPCWSTR,INT32,INT32,GCP_RESULTS32W*,DWORD); +#define GetCharacterPlacement WINELIB_NAME_AW(GetCharacterPlacement) BOOL16 WINAPI GetCharWidth16(HDC16,UINT16,UINT16,LPINT16); BOOL32 WINAPI GetCharWidth32A(HDC32,UINT32,UINT32,LPINT32); BOOL32 WINAPI GetCharWidth32W(HDC32,UINT32,UINT32,LPINT32); @@ -7689,6 +7756,9 @@ BOOL16 WINAPI GetDiskFreeSpace16(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); BOOL32 WINAPI GetDiskFreeSpace32A(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); BOOL32 WINAPI GetDiskFreeSpace32W(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); #define GetDiskFreeSpace WINELIB_NAME_AW(GetDiskFreeSpace) +BOOL32 WINAPI GetDiskFreeSpaceEx32A(LPCSTR,LPULARGE_INTEGER,LPULARGE_INTEGER,LPULARGE_INTEGER); +BOOL32 WINAPI GetDiskFreeSpaceEx32W(LPCWSTR,LPULARGE_INTEGER,LPULARGE_INTEGER,LPULARGE_INTEGER); +#define GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx) INT16 WINAPI GetDlgCtrlID16(HWND16); INT32 WINAPI GetDlgCtrlID32(HWND32); #define GetDlgCtrlID WINELIB_NAME(GetDlgCtrlID) @@ -7728,6 +7798,11 @@ DWORD WINAPI GetFileVersionInfo32W(LPCWSTR,DWORD,DWORD,LPVOID); HWND16 WINAPI GetFocus16(void); HWND32 WINAPI GetFocus32(void); #define GetFocus WINELIB_NAME(GetFocus) +DWORD WINAPI GetFontData32(HDC32,DWORD,DWORD,LPVOID,DWORD); +#define GetFontData WINELIB_NAME(GetFontData) +DWORD WINAPI GetFontLanguageInfo16(HDC16); +DWORD WINAPI GetFontLanguageInfo32(HDC32); +#define GetFontLanguageInfo WINELIB_NAME(GetFontLanguageInfo) HWND16 WINAPI GetForegroundWindow16(void); HWND32 WINAPI GetForegroundWindow32(void); #define GetForegroundWindow WINELIB_NAME(GetForegroundWindow) @@ -7831,6 +7906,11 @@ INT32 WINAPI GetObject32W(HANDLE32,INT32,LPVOID); HWND16 WINAPI GetOpenClipboardWindow16(void); HWND32 WINAPI GetOpenClipboardWindow32(void); #define GetOpenClipboardWindow WINELIB_NAME(GetOpenClipboardWindow) +/* FIXME: LPVOID should be LPOUTLINETEXTMETRIC{16,32A,32W} */ +UINT16 WINAPI GetOutlineTextMetrics16(HDC16,UINT16,LPVOID); +UINT32 WINAPI GetOutlineTextMetrics32A(HDC32,UINT32,LPVOID); +UINT32 WINAPI GetOutlineTextMetrics32W(HDC32,UINT32,LPVOID); +#define GetOutlineTextMetrics WINELIB_NAME_AW(GetOutlineTextMetrics) UINT16 WINAPI GetPaletteEntries16(HPALETTE16,UINT16,UINT16,LPPALETTEENTRY); UINT32 WINAPI GetPaletteEntries32(HPALETTE32,UINT32,UINT32,LPPALETTEENTRY); #define GetPaletteEntries WINELIB_NAME(GetPaletteEntries) @@ -7854,10 +7934,22 @@ UINT16 WINAPI GetPrivateProfileInt16(LPCSTR,LPCSTR,INT16,LPCSTR); UINT32 WINAPI GetPrivateProfileInt32A(LPCSTR,LPCSTR,INT32,LPCSTR); UINT32 WINAPI GetPrivateProfileInt32W(LPCWSTR,LPCWSTR,INT32,LPCWSTR); #define GetPrivateProfileInt WINELIB_NAME_AW(GetPrivateProfileInt) +INT16 WINAPI GetPrivateProfileSection16(LPCSTR,LPSTR,UINT16,LPCSTR); +INT32 WINAPI GetPrivateProfileSection32A(LPCSTR,LPSTR,DWORD,LPCSTR); +INT32 WINAPI GetPrivateProfileSection32W(LPCWSTR,LPWSTR,DWORD,LPCWSTR); +#define GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection) +WORD WINAPI GetPrivateProfileSectionNames16(LPSTR,UINT16,LPCSTR); +DWORD WINAPI GetPrivateProfileSectionNames32A(LPSTR,DWORD,LPCSTR); +DWORD WINAPI GetPrivateProfileSectionNames32W(LPWSTR,DWORD,LPCWSTR); +#define GetPrivateProfileSectionNames WINELIB_NAME_AW(GetPrivateProfileSectionNames) INT16 WINAPI GetPrivateProfileString16(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT16,LPCSTR); INT32 WINAPI GetPrivateProfileString32A(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT32,LPCSTR); INT32 WINAPI GetPrivateProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT32,LPCWSTR); #define GetPrivateProfileString WINELIB_NAME_AW(GetPrivateProfileString) +BOOL16 WINAPI GetPrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR); +BOOL32 WINAPI GetPrivateProfileStruct32A(LPCSTR,LPCSTR,LPVOID,UINT32,LPCSTR); +BOOL32 WINAPI GetPrivateProfileStruct32W(LPCWSTR,LPCWSTR,LPVOID,UINT32,LPCWSTR); +#define GetPrivateProfileStruct WINELIB_NAME_AW(GetPrivateProfileStruct) FARPROC16 WINAPI GetProcAddress16(HMODULE16,SEGPTR); FARPROC32 WINAPI GetProcAddress32(HMODULE32,LPCSTR); #define GetProcAddress WINELIB_NAME(GetProcAddress) @@ -7866,6 +7958,9 @@ UINT32 WINAPI GetProfileInt32A(LPCSTR,LPCSTR,INT32); UINT32 WINAPI GetProfileInt32W(LPCWSTR,LPCWSTR,INT32); #define GetProfileInt WINELIB_NAME_AW(GetProfileInt) INT16 WINAPI GetProfileString16(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT16); +INT32 WINAPI GetProfileSection32A(LPCSTR,LPSTR,DWORD); +INT32 WINAPI GetProfileSection32W(LPCWSTR,LPWSTR,DWORD); +#define GetProfileSection WINELIB_NAME_AW(GetProfileSection) INT32 WINAPI GetProfileString32A(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT32); INT32 WINAPI GetProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT32); #define GetProfileString WINELIB_NAME_AW(GetProfileString) @@ -8033,6 +8128,9 @@ BOOL32 WINAPI GetWindowPlacement32(HWND32,LPWINDOWPLACEMENT32); void WINAPI GetWindowRect16(HWND16,LPRECT16); void WINAPI GetWindowRect32(HWND32,LPRECT32); #define GetWindowRect WINELIB_NAME(GetWindowRect) +INT16 WINAPI GetWindowRgn16(HWND16,HRGN16); +INT32 WINAPI GetWindowRgn32(HWND32,HRGN32); +#define GetWindowRgn WINELIB_NAME(GetWindowRgn) UINT16 WINAPI GetWindowsDirectory16(LPSTR,UINT16); UINT32 WINAPI GetWindowsDirectory32A(LPSTR,UINT32); UINT32 WINAPI GetWindowsDirectory32W(LPWSTR,UINT32); @@ -8283,7 +8381,7 @@ HMENU32 WINAPI LoadMenuIndirect32A(LPCVOID); HMENU32 WINAPI LoadMenuIndirect32W(LPCVOID); #define LoadMenuIndirect WINELIB_NAME_AW(LoadMenuIndirect) HINSTANCE16 WINAPI LoadModule16(LPCSTR,LPVOID); -DWORD WINAPI LoadModule32(LPCSTR,LPVOID); +HINSTANCE32 WINAPI LoadModule32(LPCSTR,LPVOID); #define LoadModule WINELIB_NAME(LoadModule) HGLOBAL16 WINAPI LoadResource16(HINSTANCE16,HRSRC16); HGLOBAL32 WINAPI LoadResource32(HMODULE32,HRSRC32); @@ -8546,6 +8644,9 @@ UINT16 WINAPI RegisterClipboardFormat16(LPCSTR); UINT32 WINAPI RegisterClipboardFormat32A(LPCSTR); UINT32 WINAPI RegisterClipboardFormat32W(LPCWSTR); #define RegisterClipboardFormat WINELIB_NAME_AW(RegisterClipboardFormat) +HRESULT WINAPI RegisterDragDrop16(HWND16,LPVOID); +HRESULT WINAPI RegisterDragDrop32(HWND32,LPVOID); +#define RegisterDragDrop WINELIB_NAME(RegisterDragDrop) WORD WINAPI RegisterWindowMessage16(SEGPTR); WORD WINAPI RegisterWindowMessage32A(LPCSTR); WORD WINAPI RegisterWindowMessage32W(LPCWSTR); @@ -8782,6 +8883,7 @@ HWND32 WINAPI SetParent32(HWND32,HWND32); COLORREF WINAPI SetPixel16(HDC16,INT16,INT16,COLORREF); COLORREF WINAPI SetPixel32(HDC32,INT32,INT32,COLORREF); #define SetPixel WINELIB_NAME(SetPixel) +BOOL32 WINAPI SetPixelV32(HDC32,INT32,INT32,COLORREF); BOOL32 WINAPI SetPixelFormat(HDC32,int,PIXELFORMATDESCRIPTOR*); INT16 WINAPI SetPolyFillMode16(HDC16,INT16); INT32 WINAPI SetPolyFillMode32(HDC32,INT32); @@ -8901,6 +9003,9 @@ HHOOK WINAPI SetWindowsHookEx32W(INT32,HOOKPROC32,HINSTANCE32,DWORD); BOOL16 WINAPI SetWindowPos16(HWND16,HWND16,INT16,INT16,INT16,INT16,WORD); BOOL32 WINAPI SetWindowPos32(HWND32,HWND32,INT32,INT32,INT32,INT32,WORD); #define SetWindowPos WINELIB_NAME(SetWindowPos) +INT16 WINAPI SetWindowRgn16(HWND16,HRGN16,BOOL16); +INT32 WINAPI SetWindowRgn32(HWND32,HRGN32,BOOL32); +#define SetWindowRgn WINELIB_NAME(SetWindowRgn) void WINAPI SetWindowText16(HWND16,SEGPTR); void WINAPI SetWindowText32A(HWND32,LPCSTR); void WINAPI SetWindowText32W(HWND32,LPCWSTR); @@ -9057,10 +9162,18 @@ HWND32 WINAPI WindowFromDC32(HDC32); HWND16 WINAPI WindowFromPoint16(POINT16); HWND32 WINAPI WindowFromPoint32(POINT32); #define WindowFromPoint WINELIB_NAME(WindowFromPoint) +BOOL16 WINAPI WritePrivateProfileSection16(LPCSTR,LPCSTR,LPCSTR); +BOOL32 WINAPI WritePrivateProfileSection32A(LPCSTR,LPCSTR,LPCSTR); +BOOL32 WINAPI WritePrivateProfileSection32W(LPCWSTR,LPCWSTR,LPCWSTR); +#define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection) BOOL16 WINAPI WritePrivateProfileString16(LPCSTR,LPCSTR,LPCSTR,LPCSTR); BOOL32 WINAPI WritePrivateProfileString32A(LPCSTR,LPCSTR,LPCSTR,LPCSTR); BOOL32 WINAPI WritePrivateProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR); #define WritePrivateProfileString WINELIB_NAME_AW(WritePrivateProfileString) +BOOL16 WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR); +BOOL32 WINAPI WritePrivateProfileStruct32A(LPCSTR,LPCSTR,LPVOID,UINT32,LPCSTR); +BOOL32 WINAPI WritePrivateProfileStruct32W(LPCWSTR,LPCWSTR,LPVOID,UINT32,LPCWSTR); +#define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct) BOOL16 WINAPI WriteProfileString16(LPCSTR,LPCSTR,LPCSTR); BOOL32 WINAPI WriteProfileString32A(LPCSTR,LPCSTR,LPCSTR); BOOL32 WINAPI WriteProfileString32W(LPCWSTR,LPCWSTR,LPCWSTR); @@ -9154,9 +9267,11 @@ HPEN16 WINAPI GetSysColorPen16(INT16); HPEN32 WINAPI GetSysColorPen32(INT32); INT32 WINAPI LoadMessage32A(HMODULE32,UINT32,WORD,LPSTR,INT32); INT32 WINAPI LoadMessage32W(HMODULE32,UINT32,WORD,LPWSTR,INT32); +UINT32 WINAPI WIN16_GetTempDrive(BYTE); SEGPTR WINAPI WIN16_GlobalLock16(HGLOBAL16); SEGPTR WINAPI WIN16_LockResource16(HGLOBAL16); LONG WINAPI WIN16_hread(HFILE16,SEGPTR,LONG); +UINT16 WINAPI WIN16_lread(HFILE16,SEGPTR,UINT16); INT32 WINAPI lstrncmp32A(LPCSTR,LPCSTR,INT32); INT32 WINAPI lstrncmp32W(LPCWSTR,LPCWSTR,INT32); INT32 WINAPI lstrncmpi32A(LPCSTR,LPCSTR,INT32); diff --git a/include/winerror.h b/include/winerror.h index 12f1727df07..91db7950df3 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -22,6 +22,9 @@ extern int WIN32_LastError; */ #define ERROR_UNKNOWN 99999 +#define SEVERITY_SUCCESS 0 +#define SEVERITY_ERROR 1 + #define ERROR_SUCCESS 0 #define ERROR_FILE_NOT_FOUND 2 #define ERROR_PATH_NOT_FOUND 3 diff --git a/include/wintypes.h b/include/wintypes.h index b4804baad60..895676da174 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -135,6 +135,7 @@ typedef void* SEGPTR; DECLARE_HANDLE(HACCEL); DECLARE_HANDLE(HBITMAP); DECLARE_HANDLE(HBRUSH); +DECLARE_HANDLE(HCOLORSPACE); DECLARE_HANDLE(HCURSOR); DECLARE_HANDLE(HDC); DECLARE_HANDLE(HDROP); @@ -243,6 +244,7 @@ DECL_WINELIB_TYPE(HACCEL) DECL_WINELIB_TYPE(HANDLE) DECL_WINELIB_TYPE(HBITMAP) DECL_WINELIB_TYPE(HBRUSH) +DECL_WINELIB_TYPE(HCOLORSPACE) DECL_WINELIB_TYPE(HCURSOR) DECL_WINELIB_TYPE(HDC) DECL_WINELIB_TYPE(HDROP) diff --git a/include/x11drv.h b/include/x11drv.h index 0bb9b246ab1..5968388794e 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -98,7 +98,7 @@ extern BOOL32 X11DRV_Polygon( struct tagDC *dc, LPPOINT32 pt, INT32 count ); extern BOOL32 X11DRV_PolyPolygon( struct tagDC *dc, LPPOINT32 pt, LPINT32 counts, UINT32 polygons); extern BOOL32 X11DRV_PolyPolyline( struct tagDC *dc, LPPOINT32 pt, - LPINT32 counts, UINT32 polylines); + LPDWORD counts, DWORD polylines); extern HGDIOBJ32 X11DRV_SelectObject( struct tagDC *dc, HGDIOBJ32 handle ); diff --git a/loader/dos/Makefile.in b/loader/dos/Makefile.in index c605049b5ca..67b4c7a9a08 100644 --- a/loader/dos/Makefile.in +++ b/loader/dos/Makefile.in @@ -9,7 +9,9 @@ C_SRCS = \ module.c \ dosvm.c -all: $(MODULE).o dosmod +PROGRAMS = dosmod + +all: $(MODULE).o $(PROGRAMS) dosmod: dosmod.c $(CC) $(ALLCFLAGS) -o dosmod $< diff --git a/loader/dos/dosmod.c b/loader/dos/dosmod.c index b5ad24f0102..9807ecf580f 100644 --- a/loader/dos/dosmod.c +++ b/loader/dos/dosmod.c @@ -6,18 +6,26 @@ #ifdef linux -/* force dosmod at high addresses */ +/* apparently ELF images are usually loaded high anyway */ +#ifndef __ELF__ +/* if not, force dosmod at high addresses */ asm(".org 0x110000"); +#endif __ELF__ #include +#include #include #include #include #include +#include #include #include #include #include +#include +#include +#include /* FIXME: hack because libc vm86 may be the old syscall version */ static __inline__ int vm86plus( int func, struct vm86plus_struct *ptr ) @@ -50,16 +58,37 @@ int main(int argc,char**argv) void*img; struct vm86plus_struct VM86; int func,ret; + off_t fofs=0; + pid_t ppid=getppid(); /* fprintf(stderr,"main is at %08lx, file is %s, fd=%d\n",(unsigned long)&main,argv[0],mfd); */ if (mfd<0) return 1; /* Map in our DOS image at the start of the process address space */ - img=mmap(NULL,0x110000,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_FIXED|MAP_SHARED,mfd,0); + if (argv[1]) { + /* Ulrich Weigand suggested mapping in the DOS image directly from the Wine + address space */ + fofs=atol(argv[1]); + /* linux currently only allows mapping a process memory if it's being ptraced */ + /* Linus doesn't like it, so this probably won't work in the future */ + /* it doesn't even work for me right now */ + ptrace(PTRACE_ATTACH,ppid,0,0); + kill(ppid,SIGSTOP); + waitpid(ppid,NULL,0); + } + img=mmap(NULL,0x110000,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_FIXED|MAP_SHARED,mfd,fofs); + if (argv[1]) { + ptrace(PTRACE_DETACH,ppid,0,0); + kill(ppid,SIGCONT); + } if (img==(void*)-1) { fprintf(stderr,"DOS memory map failed, error=%s\n",strerror(errno)); + fprintf(stderr,"in attempt to map %s, offset %08lX, length 110000, to offset 0\n",argv[0],fofs); return 1; } /* fprintf(stderr,"Successfully mapped DOS memory, entering vm86 loop\n"); */ +/* report back to the main program that we're ready */ + ret=0; + write(1,&ret,sizeof(ret)); /* context exchange loop */ do { if (read(0,&func,sizeof(func))!=sizeof(func)) return 1; diff --git a/loader/dos/dosvm.c b/loader/dos/dosvm.c index 3818daa8c4b..ec2e91d8a2e 100644 --- a/loader/dos/dosvm.c +++ b/loader/dos/dosvm.c @@ -2,6 +2,8 @@ * DOS Virtual Machine * * Copyright 1998 Ove Kåven + * + * This code hasn't been completely cleaned up yet. */ #ifdef linux @@ -17,14 +19,16 @@ #include #include "windows.h" #include "winbase.h" +#include "winnt.h" #include "msdos.h" #include "miscemu.h" #include "debug.h" #include "module.h" +#include "task.h" #include "ldt.h" #include "dosexe.h" -void DOSVM_Dump( LPDOSTASK lpDosTask) +static void DOSVM_Dump( LPDOSTASK lpDosTask) { unsigned iofs; BYTE*inst; @@ -48,6 +52,7 @@ void DOSVM_Dump( LPDOSTASK lpDosTask) fprintf(stderr,"AX=%04lX CX=%04lX DX=%04lX BX=%04lX\n",REGS.eax,REGS.ebx,REGS.ecx,REGS.edx); fprintf(stderr,"SI=%04lX DI=%04lX SP=%04lX BP=%04lX\n",REGS.esi,REGS.edi,REGS.esp,REGS.ebp); fprintf(stderr,"CS=%04X DS=%04X ES=%04X SS=%04X\n",REGS.cs,REGS.ds,REGS.es,REGS.ss); + fprintf(stderr,"EIP=%04lX EFLAGS=%08lX\n",REGS.eip,REGS.eflags); iofs=((DWORD)REGS.cs<<4)+REGS.eip; #undef REGS @@ -59,8 +64,10 @@ void DOSVM_Dump( LPDOSTASK lpDosTask) exit(0); } -int DOSVM_Int(int vect, LPDOSTASK lpDosTask, PCONTEXT context ) +static int DOSVM_Int(int vect, LPDOSTASK lpDosTask, PCONTEXT context ) { + /* we should really map to if1632/wprocs.spec, but not all + interrupt handlers are adapted to support our VM yet */ switch (vect) { case 0x20: return -1; @@ -68,21 +75,30 @@ int DOSVM_Int(int vect, LPDOSTASK lpDosTask, PCONTEXT context ) if (AH_reg(context)==0x4c) return -1; DOS3Call(context); break; + case 0x1a: + INT_Int1aHandler(context); + break; + case 0x2f: + INT_Int2fHandler(context); + break; } return 0; } +#define CV CP(eax,Eax); CP(ecx,Ecx); CP(edx,Edx); CP(ebx,Ebx); \ + CP(esi,Esi); CP(edi,Edi); CP(esp,Esp); CP(ebp,Ebp); \ + CP(cs,SegCs); CP(ds,SegDs); CP(es,SegEs); \ + CP(ss,SegSs); CP(fs,SegFs); CP(gs,SegGs); \ + CP(eip,Eip); CP(eflags,EFlags) + int DOSVM_Process( LPDOSTASK lpDosTask ) { CONTEXT context; int ret=0; -#define REGS lpDosTask->VM86.regs - context.Eax=REGS.eax; context.Ecx=REGS.ecx; context.Edx=REGS.edx; context.Ebx=REGS.ebx; - context.Esi=REGS.esi; context.Edi=REGS.edi; context.Esp=REGS.esp; context.Ebp=REGS.ebp; - context.SegCs=REGS.cs; context.SegDs=REGS.ds; context.SegEs=REGS.es; - context.SegSs=REGS.ss; context.SegFs=REGS.fs; context.SegGs=REGS.gs; - context.Eip=REGS.eip; context.EFlags=REGS.eflags; +#define CP(x,y) context.y = lpDosTask->VM86.regs.x + CV; +#undef CP (void*)V86BASE(&context)=lpDosTask->img; switch (VM86_TYPE(lpDosTask->fn)) { @@ -106,13 +122,67 @@ int DOSVM_Process( LPDOSTASK lpDosTask ) } lpDosTask->fn=VM86_ENTER; - REGS.eax=context.Eax; REGS.ecx=context.Ecx; REGS.edx=context.Edx; REGS.ebx=context.Ebx; - REGS.esi=context.Esi; REGS.edi=context.Edi; REGS.esp=context.Esp; REGS.ebp=context.Ebp; - REGS.cs=context.SegCs; REGS.ds=context.SegDs; REGS.es=context.SegEs; - REGS.ss=context.SegSs; REGS.fs=context.SegFs; REGS.gs=context.SegGs; - REGS.eip=context.Eip; REGS.eflags=context.EFlags; -#undef REGS +#define CP(x,y) lpDosTask->VM86.regs.x = context.y + CV; +#undef CP return ret; } +int DOSVM_Enter( PCONTEXT context ) +{ + TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() ); + NE_MODULE *pModule = NE_GetPtr( pTask->hModule ); + LPDOSTASK lpDosTask; + int stat; + + GlobalUnlock16( GetCurrentTask() ); + if (!pModule) { + ERR(module,"No task is currently active!\n"); + return -1; + } + if (!pModule->lpDosTask) { + /* no VM86 (dosmod) task is currently running, start one */ + if ((lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL) + return 0; + lpDosTask->img=DOSMEM_MemoryBase(pModule->self); + lpDosTask->hModule=pModule->self; + stat=MZ_InitTask(lpDosTask); + if (stat<32) { + free(lpDosTask); + return -1; + } + pModule->lpDosTask = lpDosTask; + pModule->dos_image = lpDosTask->img; + /* Note: we're leaving it running after this, in case we need it again, + as this minimizes the overhead of starting it up every time... + it will be killed automatically when the current task terminates */ + } else lpDosTask=pModule->lpDosTask; + + if (context) { +#define CP(x,y) lpDosTask->VM86.regs.x = context->y + CV; +#undef CP + } + + /* main loop */ + while ((stat = MZ_RunModule(lpDosTask)) >= 0) + if (stat > 0 && DOSVM_Process(lpDosTask) < 0) + break; + + if (context) { +#define CP(x,y) context->y = lpDosTask->VM86.regs.x + CV; +#undef CP + } + return 0; +} + +#else /* !linux */ + +int DOSVM_Enter( PCONTEXT context ) +{ + ERR(module,"DOS realmode not supported on this architecture!\n"); + return -1; +} + #endif /* linux */ diff --git a/loader/dos/module.c b/loader/dos/module.c index 053c2c3b716..cce308f0fe4 100644 --- a/loader/dos/module.c +++ b/loader/dos/module.c @@ -2,6 +2,8 @@ * DOS (MZ) loader * * Copyright 1998 Ove Kåven + * + * This code hasn't been completely cleaned up yet. */ #ifdef linux @@ -15,16 +17,8 @@ #include #include #include -#ifdef MZ_USESYSV -#include -#include -#else #include -#endif #include -#ifdef MZ_USESYSV -#include /* FIXME: where else should I fetch the PAGE_SIZE define? */ -#endif #include "windows.h" #include "winbase.h" #include "module.h" @@ -35,15 +29,14 @@ #include "debug.h" #include "dosexe.h" +/* define this to try mapping through /proc/pid/mem instead of a temp file, + but Linus doesn't like mmapping /proc/pid/mem, so it doesn't work for me */ +#undef MZ_MAPSELF + #define BIOS_DATA_SEGMENT 0x40 #define BIOS_SEGMENT BIOSSEG /* BIOSSEG is defined to 0xf000 in sys/vm86.h */ #define STUB_SEGMENT BIOS_SEGMENT -#ifdef MZ_USESYSV -/* it might be that SYSV supports START_OFFSET 0 after all, haven't checked */ -#define START_OFFSET PAGE_SIZE -#else #define START_OFFSET 0 -#endif #define PSP_SIZE 0x10 #define SEG16(ptr,seg) ((LPVOID)((BYTE*)ptr+((DWORD)(seg)<<4))) @@ -80,7 +73,10 @@ static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, LPCSTR env ) psp->nextParagraph=0x9FFF; /* copy parameters */ if (cmd) { +#if 0 + /* command.com doesn't do this */ while (*cmd == ' ') cmd++; +#endif psp->cmdLine[0]=strlen(cmd); strcpy(psp->cmdLine+1,cmd); psp->cmdLine[psp->cmdLine[0]+1]='\r'; @@ -89,11 +85,11 @@ static void MZ_InitPSP( LPVOID lpPSP, LPCSTR cmdline, LPCSTR env ) /* FIXME: integrate the PDB stuff from Wine (loader/task.c) */ } -static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, LPDOSTASK lpDosTask ) +static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, + LPDOSTASK lpDosTask, NE_MODULE *pModule ) { IMAGE_DOS_HEADER mz_header; DWORD image_start,image_size,min_size,max_size,avail; - WORD psp_seg,load_seg; BYTE*psp_start,*load_start; int x; SEGPTR reloc; @@ -111,10 +107,10 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, LPDOSTASK lp /* allocate 1MB+64K shared memory */ lpDosTask->img_ofs=START_OFFSET; -#ifdef MZ_USESYSV - lpDosTask->key=ftok(".",'d'); /* FIXME: this is from my IPC intro doc */ - lpDosTask->shm_id=shmget(lpDosTask->key,0x110000-START_OFFSET,IPC_CREAT|SHM_R|SHM_W); - lpDosTask->img=shmat(lpDosTask->shm_id,NULL,0); +#ifdef MZ_MAPSELF + lpDosTask->img=VirtualAlloc(NULL,0x110000,MEM_COMMIT,PAGE_READWRITE); + /* make sure mmap accepts it */ + ((char*)lpDosTask->img)[0x10FFFF]=0; #else tmpnam(lpDosTask->mm_name); /* strcpy(lpDosTask->mm_name,"/tmp/mydosimage"); */ @@ -131,6 +127,7 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, LPDOSTASK lp return 0; } TRACE(module,"DOS VM86 image mapped at %08lx\n",(DWORD)lpDosTask->img); + pModule->dos_image=lpDosTask->img; /* initialize the memory */ MZ_InitSystem(lpDosTask->img); @@ -147,12 +144,12 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, LPDOSTASK lp return 0; } if (avail>max_size) avail=max_size; - psp_start=DOSMEM_GetBlock(lpDosTask->hModule,avail,&psp_seg); + psp_start=DOSMEM_GetBlock(lpDosTask->hModule,avail,&lpDosTask->psp_seg); if (!psp_start) { ERR(module, "error allocating DOS memory\n"); return 0; } - load_seg=psp_seg+PSP_SIZE; + lpDosTask->load_seg=lpDosTask->psp_seg+PSP_SIZE; load_start=psp_start+(PSP_SIZE<<4); MZ_InitPSP(psp_start, cmdline, env); @@ -169,26 +166,27 @@ static int MZ_LoadImage( HFILE16 hFile, LPCSTR cmdline, LPCSTR env, LPDOSTASK lp for (x=0; xload_seg; } /* initialize vm86 struct */ memset(&lpDosTask->VM86,0,sizeof(lpDosTask->VM86)); - lpDosTask->VM86.regs.cs=load_seg+mz_header.e_cs; + lpDosTask->VM86.regs.cs=lpDosTask->load_seg+mz_header.e_cs; lpDosTask->VM86.regs.eip=mz_header.e_ip; - lpDosTask->VM86.regs.ss=load_seg+mz_header.e_ss; + lpDosTask->VM86.regs.ss=lpDosTask->load_seg+mz_header.e_ss; lpDosTask->VM86.regs.esp=mz_header.e_sp; - lpDosTask->VM86.regs.ds=psp_seg; - lpDosTask->VM86.regs.es=psp_seg; + lpDosTask->VM86.regs.ds=lpDosTask->psp_seg; + lpDosTask->VM86.regs.es=lpDosTask->psp_seg; /* hmm, what else do we need? */ return 32; } -static int MZ_InitTask( LPDOSTASK lpDosTask ) +int MZ_InitTask( LPDOSTASK lpDosTask ) { int read_fd[2],write_fd[2]; pid_t child; + char *fname,*farg,arg[16],fproc[64]; /* create read pipe */ if (pipe(read_fd)<0) return 0; @@ -199,15 +197,36 @@ static int MZ_InitTask( LPDOSTASK lpDosTask ) lpDosTask->write_pipe=write_fd[1]; lpDosTask->fn=VM86_ENTER; lpDosTask->state=1; - TRACE(module,"Preparing to load DOS EXE support module: forking\n"); + /* if we have a mapping file, use it */ + fname=lpDosTask->mm_name; farg=NULL; + if (!fname[0]) { + /* otherwise, map our own memory image */ + sprintf(fproc,"/proc/%d/mem",getpid()); + sprintf(arg,"%ld",(unsigned long)lpDosTask->img); + fname=fproc; farg=arg; + } + + TRACE(module,"Preparing to load DOS VM support module: forking\n"); if ((child=fork())<0) { close(write_fd[0]); close(write_fd[1]); close(read_fd[0]); close(read_fd[1]); return 0; } if (child!=0) { /* parent process */ + int ret; + close(read_fd[1]); close(write_fd[0]); lpDosTask->task=child; + /* wait for child process to signal readiness */ + do { + if (read(lpDosTask->read_pipe,&ret,sizeof(ret))!=sizeof(ret)) { + if ((errno==EINTR)||(errno==EAGAIN)) continue; + /* failure */ + ERR(module,"dosmod has failed to initialize\n"); + return 0; + } + } while (0); + /* all systems are now go */ } else { /* child process */ close(read_fd[0]); close(write_fd[1]); @@ -215,9 +234,9 @@ static int MZ_InitTask( LPDOSTASK lpDosTask ) dup2(write_fd[0],0); /* stdin */ dup2(read_fd[1],1); /* stdout */ /* now load dosmod */ - execlp("dosmod",lpDosTask->mm_name,NULL); - execl("dosmod",lpDosTask->mm_name,NULL); - execl("loader/dos/dosmod",lpDosTask->mm_name,NULL); + execlp("dosmod",fname,farg,NULL); + execl("dosmod",fname,farg,NULL); + execl("loader/dos/dosmod",fname,farg,NULL); /* if failure, exit */ ERR(module,"Failed to spawn dosmod, error=%s\n",strerror(errno)); exit(1); @@ -225,8 +244,8 @@ static int MZ_InitTask( LPDOSTASK lpDosTask ) return 32; } -HINSTANCE16 MZ_LoadModule( LPCSTR name, LPCSTR cmdline, - LPCSTR env, UINT16 show_cmd ) +HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, + LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info ) { LPDOSTASK lpDosTask; HMODULE16 hModule; @@ -234,7 +253,6 @@ HINSTANCE16 MZ_LoadModule( LPCSTR name, LPCSTR cmdline, NE_MODULE *pModule; HFILE16 hFile; OFSTRUCT ofs; - PROCESS_INFORMATION info; int err; if ((lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL) @@ -252,29 +270,41 @@ HINSTANCE16 MZ_LoadModule( LPCSTR name, LPCSTR cmdline, pModule->lpDosTask = lpDosTask; lpDosTask->img=NULL; lpDosTask->mm_name[0]=0; lpDosTask->mm_fd=-1; - err = MZ_LoadImage( hFile, cmdline, env, lpDosTask ); + err = MZ_LoadImage( hFile, cmdline, env, lpDosTask, pModule ); _lclose16(hFile); + pModule->dos_image = lpDosTask->img; if (err<32) { - if (lpDosTask->img!=NULL) munmap(lpDosTask->img,0x110000-START_OFFSET); - if (lpDosTask->mm_fd>=0) close(lpDosTask->mm_fd); - if (lpDosTask->mm_name[0]!=0) unlink(lpDosTask->mm_name); + if (lpDosTask->mm_name[0]!=0) { + if (lpDosTask->img!=NULL) munmap(lpDosTask->img,0x110000-START_OFFSET); + if (lpDosTask->mm_fd>=0) close(lpDosTask->mm_fd); + unlink(lpDosTask->mm_name); + } else + if (lpDosTask->img!=NULL) VirtualFree(lpDosTask->img,0x110000,MEM_RELEASE); + return err; + } + err = MZ_InitTask( lpDosTask ); + if (lpDosTask->mm_name[0]!=0) { + /* we unlink the temp file here to avoid leaving a mess in /tmp + if/when Wine crashes; the mapping still remains open, though */ + unlink(lpDosTask->mm_name); + } + if (err<32) { + MZ_KillModule( lpDosTask ); + /* FIXME: cleanup hModule */ return err; } - MZ_InitTask( lpDosTask ); hInstance = NE_CreateInstance(pModule, NULL, (cmdline == NULL)); - PROCESS_Create( pModule, cmdline, env, hInstance, 0, show_cmd, &info ); - /* we don't need the handles for now */ - CloseHandle( info.hThread ); - CloseHandle( info.hProcess ); + PROCESS_Create( pModule, cmdline, env, hInstance, 0, startup, info ); return hInstance; } void MZ_KillModule( LPDOSTASK lpDosTask ) { - munmap(lpDosTask->img,0x110000-START_OFFSET); - close(lpDosTask->mm_fd); - unlink(lpDosTask->mm_name); + if (lpDosTask->mm_name[0]!=0) { + munmap(lpDosTask->img,0x110000-START_OFFSET); + close(lpDosTask->mm_fd); + } else VirtualFree(lpDosTask->img,0x110000,MEM_RELEASE); close(lpDosTask->read_pipe); close(lpDosTask->write_pipe); kill(lpDosTask->task,SIGTERM); @@ -310,4 +340,13 @@ int MZ_RunModule( LPDOSTASK lpDosTask ) return 0; } -#endif /* linux */ +#else /* !linux */ + +HINSTANCE16 MZ_CreateProcess( LPCSTR name, LPCSTR cmdline, LPCSTR env, + LPSTARTUPINFO32A startup, LPPROCESS_INFORMATION info ) +{ + WARN(module,"DOS executables not supported on this architecture\n"); + return (HMODULE16)11; /* invalid exe */ +} + +#endif diff --git a/loader/module.c b/loader/module.c index 21d566583c1..0804df33534 100644 --- a/loader/module.c +++ b/loader/module.c @@ -11,6 +11,7 @@ #include #include #include "windows.h" +#include "winerror.h" #include "class.h" #include "file.h" #include "global.h" @@ -284,16 +285,11 @@ HMODULE32 MODULE_FindModule32( /********************************************************************** - * MODULE_Load - * - * Implementation of LoadModule(). - * - * cmd_line must contain the whole command-line, including argv[0] (and - * without a preceding length byte). - * If cmd_line is NULL, the module is loaded as a library even if it is a .exe + * NE_CreateProcess */ -HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit, - LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd ) +static HINSTANCE16 NE_CreateProcess( LPCSTR name, LPCSTR cmd_line, LPCSTR env, + LPSTARTUPINFO32A startup, + LPPROCESS_INFORMATION info ) { HMODULE16 hModule; HINSTANCE16 hInstance, hPrevInstance; @@ -305,38 +301,24 @@ HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit, lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) ); if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule; pModule = (NE_MODULE *)GlobalLock16( hModule ); - hInstance = NE_CreateInstance( pModule, &hPrevInstance, - (cmd_line == NULL) ); + hInstance = NE_CreateInstance( pModule, &hPrevInstance, FALSE ); } else { - hInstance = NE_LoadModule( name, &hPrevInstance, implicit, - (cmd_line == NULL) ); - if ((hInstance == 21) && cmd_line) - return PE_LoadModule( name, cmd_line, env, show_cmd ); -#ifdef linux - if (hInstance == 11) - return MZ_LoadModule(name, cmd_line, env, show_cmd ); -#endif + hInstance = NE_LoadModule( name, &hPrevInstance, FALSE, FALSE ); + pModule = hInstance >= 32 ? NE_GetPtr( hInstance ) : NULL; } /* Create a task for this instance */ - if (hInstance < 32) return hInstance; - pModule = NE_GetPtr( hInstance ); - if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE)) + if (pModule && !(pModule->flags & NE_FFLAGS_LIBMODULE)) { PDB32 *pdb; - PROCESS_INFORMATION info; pModule->flags |= NE_FFLAGS_GUI; pdb = PROCESS_Create( pModule, cmd_line, env, hInstance, - hPrevInstance, show_cmd, &info ); - /* we don't need the handles for now */ - CloseHandle( info.hThread ); - CloseHandle( info.hProcess ); - if (pdb && (GetNumTasks() > 1)) Yield16(); + hPrevInstance, startup, info ); } return hInstance; @@ -349,77 +331,239 @@ HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit, HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock ) { LOADPARAMS *params; - LPSTR cmd_line, new_cmd_line; - UINT16 show_cmd = 0; - LPCVOID env = NULL; + LOADPARAMS32 params32; HINSTANCE16 hInstance; + LPSTR cmd_line; if (!paramBlock || (paramBlock == (LPVOID)-1)) return LoadLibrary16( name ); + /* Transfer arguments to 32-bit param-block */ params = (LOADPARAMS *)paramBlock; - cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ); - /* PowerPoint passes NULL as showCmd */ - if (params->showCmd) - show_cmd = *((UINT16 *)PTR_SEG_TO_LIN(params->showCmd)+1); + memset( ¶ms32, '\0', sizeof(params32) ); + cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ); if (!cmd_line) cmd_line = ""; else if (*cmd_line) cmd_line++; /* skip the length byte */ - if (!(new_cmd_line = HeapAlloc( GetProcessHeap(), 0, - strlen(cmd_line) + strlen(name) + 2 ))) + if (!(params32.lpCmdLine = HeapAlloc( GetProcessHeap(), 0, + strlen(cmd_line)+strlen(name)+2 ))) return 0; - strcpy( new_cmd_line, name ); - strcat( new_cmd_line, " " ); - strcat( new_cmd_line, cmd_line ); + strcpy( params32.lpCmdLine, name ); + strcat( params32.lpCmdLine, " " ); + strcat( params32.lpCmdLine, cmd_line ); - if (params->hEnvironment) env = GlobalLock16( params->hEnvironment ); - hInstance = MODULE_Load( name, FALSE, new_cmd_line, env, show_cmd ); + if (params->hEnvironment) + params32.lpEnvAddress = GlobalLock16( params->hEnvironment ); + if (params->showCmd) + params32.lpCmdShow = PTR_SEG_TO_LIN( params->showCmd ); + + /* Call LoadModule32 */ + hInstance = LoadModule32( name, ¶ms32 ); + + /* Clean up */ if (params->hEnvironment) GlobalUnlock16( params->hEnvironment ); - HeapFree( GetProcessHeap(), 0, new_cmd_line ); + HeapFree( GetProcessHeap(), 0, params32.lpCmdLine ); + return hInstance; } /********************************************************************** * LoadModule32 (KERNEL32.499) - * - * FIXME - * - * This should get implemented via CreateProcess -- MODULE_Load - * is resolutely 16-bit. */ -DWORD WINAPI LoadModule32( LPCSTR name, LPVOID paramBlock ) +HINSTANCE32 WINAPI LoadModule32( LPCSTR name, LPVOID paramBlock ) { LOADPARAMS32 *params = (LOADPARAMS32 *)paramBlock; -#if 0 - STARTUPINFO st; - PROCESSINFORMATION pi; - st.cb = sizeof(STARTUPINFO); - st.wShowWindow = p->lpCmdShow[2] ; WRONG + PROCESS_INFORMATION info; + STARTUPINFO32A startup; + HINSTANCE32 hInstance; + PDB32 *pdb; + TDB *tdb; - BOOL32 ret = CreateProcess32A( name, p->lpCmdLine, - NULL, NULL, FALSE, 0, p->lpEnvAddress, - NULL, &st, &pi); - if (!ret) { - /* handle errors appropriately */ - } - CloseHandle32(pi.hProcess); - CloseHandle32(pi.hThread); + memset( &startup, '\0', sizeof(startup) ); + startup.cb = sizeof(startup); + startup.dwFlags = STARTF_USESHOWWINDOW; + startup.wShowWindow = params->lpCmdShow? params->lpCmdShow[1] : 0; -#else - return MODULE_Load( name, FALSE, params->lpCmdLine, params->lpEnvAddress, - *((UINT16 *)params->lpCmdShow + 1) ); -#endif + if (!CreateProcess32A( name, params->lpCmdLine, + NULL, NULL, FALSE, 0, params->lpEnvAddress, + NULL, &startup, &info )) + return GetLastError(); /* guaranteed to be < 32 */ + + /* Get hInstance from process */ + pdb = PROCESS_IdToPDB( info.dwProcessId ); + tdb = pdb? (TDB *)GlobalLock16( pdb->task ) : NULL; + hInstance = tdb? tdb->hInstance : 0; + + /* Close off the handles */ + CloseHandle( info.hThread ); + CloseHandle( info.hProcess ); + + return hInstance; } +/********************************************************************** + * CreateProcess32A (KERNEL32.171) + */ +BOOL32 WINAPI CreateProcess32A( LPCSTR lpApplicationName, LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL32 bInheritHandles, DWORD dwCreationFlags, + LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, + LPSTARTUPINFO32A lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInfo ) +{ + HINSTANCE16 hInstance; + LPCSTR cmdline; + PDB32 *pdb; + char name[256]; + + /* Get name and command line */ + + if (!lpApplicationName && !lpCommandLine) + { + SetLastError( ERROR_FILE_NOT_FOUND ); + return FALSE; + } + + cmdline = lpCommandLine? lpCommandLine : lpApplicationName; + + if (lpApplicationName) + lstrcpyn32A(name, lpApplicationName, sizeof(name) - 4); + else + { + char *ptr = strchr(lpCommandLine, ' '); + int len = (ptr? ptr-lpCommandLine : strlen(lpCommandLine)) + 1; + if (len > sizeof(name) - 4) len = sizeof(name) - 4; + lstrcpyn32A(name, lpCommandLine, len); + } + + if (!strchr(name, '\\') && !strchr(name, '.')) + strcat(name, ".exe"); + + + /* Warn if unsupported features are used */ + + if (lpProcessAttributes) + FIXME(module, "(%s,...): lpProcessAttributes ignored\n", name); + if (lpThreadAttributes) + FIXME(module, "(%s,...): lpThreadAttributes ignored\n", name); + if (bInheritHandles) + FIXME(module, "(%s,...): bInheritHandles ignored\n", name); + if (dwCreationFlags & DEBUG_PROCESS) + FIXME(module, "(%s,...): DEBUG_PROCESS ignored\n", name); + if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS) + FIXME(module, "(%s,...): DEBUG_ONLY_THIS_PROCESS ignored\n", name); + if (dwCreationFlags & CREATE_SUSPENDED) + FIXME(module, "(%s,...): CREATE_SUSPENDED ignored\n", name); + if (dwCreationFlags & DETACHED_PROCESS) + FIXME(module, "(%s,...): DETACHED_PROCESS ignored\n", name); + if (dwCreationFlags & CREATE_NEW_CONSOLE) + FIXME(module, "(%s,...): CREATE_NEW_CONSOLE ignored\n", name); + if (dwCreationFlags & NORMAL_PRIORITY_CLASS) + FIXME(module, "(%s,...): NORMAL_PRIORITY_CLASS ignored\n", name); + if (dwCreationFlags & IDLE_PRIORITY_CLASS) + FIXME(module, "(%s,...): IDLE_PRIORITY_CLASS ignored\n", name); + if (dwCreationFlags & HIGH_PRIORITY_CLASS) + FIXME(module, "(%s,...): HIGH_PRIORITY_CLASS ignored\n", name); + if (dwCreationFlags & REALTIME_PRIORITY_CLASS) + FIXME(module, "(%s,...): REALTIME_PRIORITY_CLASS ignored\n", name); + if (dwCreationFlags & CREATE_NEW_PROCESS_GROUP) + FIXME(module, "(%s,...): CREATE_NEW_PROCESS_GROUP ignored\n", name); + if (dwCreationFlags & CREATE_UNICODE_ENVIRONMENT) + FIXME(module, "(%s,...): CREATE_UNICODE_ENVIRONMENT ignored\n", name); + if (dwCreationFlags & CREATE_SEPARATE_WOW_VDM) + FIXME(module, "(%s,...): CREATE_SEPARATE_WOW_VDM ignored\n", name); + if (dwCreationFlags & CREATE_SHARED_WOW_VDM) + FIXME(module, "(%s,...): CREATE_SHARED_WOW_VDM ignored\n", name); + if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE) + FIXME(module, "(%s,...): CREATE_DEFAULT_ERROR_MODE ignored\n", name); + if (dwCreationFlags & CREATE_NO_WINDOW) + FIXME(module, "(%s,...): CREATE_NO_WINDOW ignored\n", name); + if (dwCreationFlags & PROFILE_USER) + FIXME(module, "(%s,...): PROFILE_USER ignored\n", name); + if (dwCreationFlags & PROFILE_KERNEL) + FIXME(module, "(%s,...): PROFILE_KERNEL ignored\n", name); + if (dwCreationFlags & PROFILE_SERVER) + FIXME(module, "(%s,...): PROFILE_SERVER ignored\n", name); + if (lpCurrentDirectory) + FIXME(module, "(%s,...): lpCurrentDirectory %s ignored\n", + name, lpCurrentDirectory); + if (lpStartupInfo->lpDesktop) + FIXME(module, "(%s,...): lpStartupInfo->lpDesktop %s ignored\n", + name, lpStartupInfo->lpDesktop); + if (lpStartupInfo->lpTitle) + FIXME(module, "(%s,...): lpStartupInfo->lpTitle %s ignored\n", + name, lpStartupInfo->lpTitle); + if (lpStartupInfo->dwFlags & STARTF_USECOUNTCHARS) + FIXME(module, "(%s,...): STARTF_USECOUNTCHARS (%ld,%ld) ignored\n", + name, lpStartupInfo->dwXCountChars, lpStartupInfo->dwYCountChars); + if (lpStartupInfo->dwFlags & STARTF_USEFILLATTRIBUTE) + FIXME(module, "(%s,...): STARTF_USEFILLATTRIBUTE %lx ignored\n", + name, lpStartupInfo->dwFillAttribute); + if (lpStartupInfo->dwFlags & STARTF_RUNFULLSCREEN) + FIXME(module, "(%s,...): STARTF_RUNFULLSCREEN ignored\n", name); + if (lpStartupInfo->dwFlags & STARTF_FORCEONFEEDBACK) + FIXME(module, "(%s,...): STARTF_FORCEONFEEDBACK ignored\n", name); + if (lpStartupInfo->dwFlags & STARTF_FORCEOFFFEEDBACK) + FIXME(module, "(%s,...): STARTF_FORCEOFFFEEDBACK ignored\n", name); + if (lpStartupInfo->dwFlags & STARTF_USEHOTKEY) + FIXME(module, "(%s,...): STARTF_USEHOTKEY ignored\n", name); + + + /* Try NE (or winelib) module */ + hInstance = NE_CreateProcess( name, cmdline, lpEnvironment, + lpStartupInfo, lpProcessInfo ); + + /* Try PE module */ + if (hInstance == 21) + hInstance = PE_CreateProcess( name, cmdline, lpEnvironment, + lpStartupInfo, lpProcessInfo ); + + /* Try DOS module */ +#ifdef linux + if (hInstance == 11) + hInstance = MZ_CreateProcess( name, cmdline, lpEnvironment, + lpStartupInfo, lpProcessInfo ); +#endif + + if (hInstance < 32) + { + SetLastError( hInstance ); + return FALSE; + } + + /* Get hTask from process and start the task */ + pdb = PROCESS_IdToPDB( lpProcessInfo->dwProcessId ); + if (pdb) TASK_StartTask( pdb->task ); + + return TRUE; +} + +/********************************************************************** + * CreateProcess32W (KERNEL32.172) + */ +BOOL32 WINAPI CreateProcess32W( LPCWSTR lpApplicationName, LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL32 bInheritHandles, DWORD dwCreationFlags, + LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, + LPSTARTUPINFO32W lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInfo ) +{ + FIXME(win32, "(%s,%s,...): stub\n", debugstr_w(lpApplicationName), + debugstr_w(lpCommandLine)); + + /* make from lcc uses system as fallback if CreateProcess returns + FALSE, so return false */ + return FALSE; +} /*********************************************************************** * GetModuleHandle (KERNEL32.237) */ HMODULE32 WINAPI GetModuleHandle32A(LPCSTR module) { - - TRACE(win32, "%s\n", module ? module : "NULL"); if (module == NULL) return PROCESS_Current()->exe_modref->module; else @@ -582,10 +726,21 @@ HINSTANCE32 WINAPI WinExec32( LPCSTR lpCmdLine, UINT32 nCmdShow ) char *p, filename[256]; static int use_load_module = 1; int spacelimit = 0, exhausted = 0; + LOADPARAMS32 params; + UINT16 paramCmdShow[2]; if (!lpCmdLine) return 2; /* File not found */ + /* Set up LOADPARAMS32 buffer for LoadModule32 */ + + memset( ¶ms, '\0', sizeof(params) ); + params.lpCmdLine = (LPSTR)lpCmdLine; + params.lpCmdShow = paramCmdShow; + params.lpCmdShow[0] = 2; + params.lpCmdShow[1] = nCmdShow; + + /* Keep trying to load a file by trying different filenames; e.g., for the cmdline "abcd efg hij", try "abcd" with args "efg hij", then "abcd efg" with arg "hij", and finally "abcd efg hij" with @@ -625,7 +780,7 @@ HINSTANCE32 WINAPI WinExec32( LPCSTR lpCmdLine, UINT32 nCmdShow ) { /* Winelib: Use LoadModule() only for the program itself */ if (__winelib) use_load_module = 0; - handle = MODULE_Load( filename, FALSE, lpCmdLine, NULL, nCmdShow ); + handle = LoadModule32( filename, ¶ms ); if (handle == 2) /* file not found */ { /* Check that the original file name did not have a suffix */ @@ -635,8 +790,7 @@ HINSTANCE32 WINAPI WinExec32( LPCSTR lpCmdLine, UINT32 nCmdShow ) { p = filename + strlen(filename); strcpy( p, ".exe" ); - handle = MODULE_Load( filename, FALSE, lpCmdLine, - NULL, nCmdShow ); + handle = LoadModule32( filename, ¶ms ); *p = '\0'; /* Remove extension */ } } diff --git a/loader/ne/module.c b/loader/ne/module.c index c085678d794..fb3b16839db 100644 --- a/loader/ne/module.c +++ b/loader/ne/module.c @@ -19,6 +19,7 @@ #include "process.h" #include "toolhelp.h" #include "snoop.h" +#include "stackframe.h" #include "debug.h" FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16) = NULL; @@ -744,6 +745,8 @@ HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance, { HINSTANCE16 prev; pModule = NE_GetPtr( hModule ); + if ( pModule->module32 ) return (HINSTANCE16)21; + hInstance = NE_CreateInstance( pModule, &prev, lib_only ); if (hInstance != prev) /* not a library */ NE_LoadSegment( pModule, pModule->dgroup ); @@ -1115,3 +1118,55 @@ BOOL16 WINAPI ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule ) lpme->wNext = hModule; return ModuleNext( lpme ); } + +/*************************************************************************** + * MapHModuleLS (KERNEL32.520) + */ +HMODULE16 WINAPI MapHModuleLS(HMODULE32 hmod) { + NE_MODULE *pModule; + + if (!hmod) + return ((TDB*)GlobalLock16(GetCurrentTask()))->hInstance; + if (!HIWORD(hmod)) + return hmod; /* we already have a 16 bit module handle */ + pModule = (NE_MODULE*)GlobalLock16(hFirstModule); + while (pModule) { + if (pModule->module32 == hmod) + return pModule->self; + pModule = (NE_MODULE*)GlobalLock16(pModule->next); + } + return 0; +} + +/*************************************************************************** + * MapHModuleSL (KERNEL32.521) + */ +HMODULE32 WINAPI MapHModuleSL(HMODULE16 hmod) { + NE_MODULE *pModule; + + if (!hmod) { + TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask()); + + hmod = pTask->hInstance; + } + pModule = (NE_MODULE*)GlobalLock16(hmod); + if ( (pModule->magic!=IMAGE_OS2_SIGNATURE) || + !(pModule->flags & NE_FFLAGS_WIN32) + ) + return 0; + return pModule->module32; +} + +/*************************************************************************** + * MapHInstLS (KERNEL32.516) + */ +REGS_ENTRYPOINT(MapHInstLS) { + EAX_reg(context) = MapHModuleLS(EAX_reg(context)); +} + +/*************************************************************************** + * MapHInstLS (KERNEL32.518) + */ +REGS_ENTRYPOINT(MapHInstSL) { + EAX_reg(context) = MapHModuleSL(EAX_reg(context)); +} diff --git a/loader/ne/resource.c b/loader/ne/resource.c index c5d3fcec9cb..90fb4160468 100644 --- a/loader/ne/resource.c +++ b/loader/ne/resource.c @@ -374,7 +374,7 @@ HGLOBAL16 WINAPI DirectResAlloc( HINSTANCE16 hInstance, WORD wType, */ INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) { - HFILE32 fd; + HFILE16 fd; NE_MODULE *pModule = NE_GetPtr( hModule ); if (!pModule || !pModule->res_table || !hRsrc) return -1; @@ -383,11 +383,11 @@ INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */ - if ((fd = _lopen32( NE_MODULE_NAME(pModule), OF_READ )) != -1) + if ((fd = _lopen16( NE_MODULE_NAME(pModule), OF_READ )) != -1) { WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table); NE_NAMEINFO *pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); - _llseek32( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET ); + _llseek16( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET ); } return fd; } diff --git a/loader/pe_image.c b/loader/pe_image.c index 76dc87eb633..8ef9b7394e9 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -827,8 +827,9 @@ HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, PDB32 *process, * FIXME: this function should use PE_LoadLibraryEx32A, but currently can't * due to the PROCESS_Create stuff. */ -HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line, - LPCSTR env, UINT16 show_cmd ) +HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line, + LPCSTR env, LPSTARTUPINFO32A startup, + LPPROCESS_INFORMATION info ) { HMODULE16 hModule16; HMODULE32 hModule32; @@ -836,8 +837,8 @@ HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line, NE_MODULE *pModule; HFILE32 hFile; OFSTRUCT ofs; - THDB *thdb = THREAD_Current(); PDB32 *process; + TDB *pTask; WINE_MODREF *wm; if ((hFile = OpenFile32( name, &ofs, OF_READ )) == HFILE_ERROR32) @@ -850,21 +851,13 @@ HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line, pModule->module32 = hModule32 = PE_LoadImage( hFile ); if (hModule32 < 32) return 21; - hInstance = NE_CreateInstance( pModule, NULL, (cmd_line == NULL) ); - if (cmd_line && - !(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL)) - { - PROCESS_INFORMATION info; - PDB32 *pdb = PROCESS_Create( pModule, cmd_line, env, - hInstance, 0, show_cmd, &info ); - TDB *pTask = (TDB *)GlobalLock16( pdb->task ); - thdb = pTask->thdb; - /* we don't need the handles for now */ - CloseHandle( info.hThread ); - CloseHandle( info.hProcess ); - } + if (PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL) + return 11; - process = thdb->process; + hInstance = NE_CreateInstance( pModule, NULL, FALSE ); + process = PROCESS_Create( pModule, cmd_line, env, + hInstance, 0, startup, info ); + pTask = (TDB *)GlobalLock16( process->task ); wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm)); wm->type = MODULE32_PE; @@ -878,8 +871,10 @@ HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line, return 0; } pModule->module32 = wm->module; + /* FIXME: Yuck. Is there no other good place to do that? */ - PE_InitTls( thdb ); + PE_InitTls( pTask->thdb ); + return hInstance; } @@ -916,7 +911,7 @@ static void PE_InitDLL(WINE_MODREF *wm, DWORD type,LPVOID lpReserved) if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) && (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint) ) { - FARPROC32 entry = (FARPROC32)RVA_PTR( wm->module, + DWORD (CALLBACK *entry)(HMODULE32,DWORD,LPVOID) = (void*)RVA_PTR( wm->module, OptionalHeader.AddressOfEntryPoint ); TRACE(relay, "CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n", entry, wm->module, type, lpReserved ); diff --git a/loader/resource.c b/loader/resource.c index bff00b9d9c1..798b8a517ef 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -66,7 +66,7 @@ HANDLE32 WINAPI FindResourceEx32A( HMODULE32 hModule, LPCSTR name, LPCSTR type, */ HRSRC32 WINAPI FindResourceEx32W( HMODULE32 hModule, LPCWSTR name, LPCWSTR type, WORD lang ) -{ +{ HRSRC32 ret; WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule); HRSRC32 hrsrc; @@ -83,7 +83,10 @@ HRSRC32 WINAPI FindResourceEx32W( HMODULE32 hModule, LPCWSTR name, if (wm) { switch (wm->type) { case MODULE32_PE: - return PE_FindResourceEx32W(wm,name,type,lang); + ret = PE_FindResourceEx32W(wm,name,type,lang); + if ( ret==0 ) + ERR(resource,"%s not found!\n",debugres_w (name)); + return ret; default: ERR(module,"unknown module type %d\n",wm->type); break; @@ -229,6 +232,7 @@ HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName) { HRSRC32 hRsrc; HACCEL32 hRetval; + DWORD size; if (HIWORD(lpTableName)) TRACE(accel, "%p '%s'\n", @@ -244,6 +248,13 @@ HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName) } else { hRetval = LoadResource32( instance, hRsrc ); + size = SizeofResource32( instance, hRsrc ); + if(size>=sizeof(ACCEL32)) + { + LPACCEL32 accel_table = (LPACCEL32) hRetval; + /* mark last element as such - sometimes it is not marked in image */ + accel_table[size/sizeof(ACCEL32)-1].fVirt |= 0x80; + } } TRACE(accel, "returning HACCEL 0x%x\n", hRsrc); diff --git a/loader/signal.c b/loader/signal.c index 0023c6570ee..c6267219d89 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -34,9 +34,6 @@ #include "sig_context.h" #include "winsock.h" -/* Global variable to save %fs register while in 16-bit code */ -WORD CALLTO16_Current_fs; - /* Linux sigaction function */ #if defined(linux) && defined(__i386__) diff --git a/loader/task.c b/loader/task.c index 7d1814db41d..099333e30ac 100644 --- a/loader/task.c +++ b/loader/task.c @@ -6,6 +6,7 @@ #include #include +#include #include "windows.h" #include "user.h" @@ -55,6 +56,9 @@ static UINT16 nTaskCount = 0; static void TASK_YieldToSystem(TDB*); +extern BOOL32 THREAD_InitDone; + + /*********************************************************************** * TASK_InstallTHHook */ @@ -78,7 +82,6 @@ HTASK16 TASK_GetNextTask( HTASK16 hTask ) return (hFirstTask != hTask) ? hFirstTask : 0; } - /*********************************************************************** * TASK_LinkTask */ @@ -222,8 +225,7 @@ static BOOL32 TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk ) */ static void TASK_CallToStart(void) { - int exit_code = 1; - TDB *pTask = (TDB *)GlobalLock16( hCurrentTask ); + TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() ); NE_MODULE *pModule = NE_GetPtr( pTask->hModule ); SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); @@ -237,7 +239,11 @@ static void TASK_CallToStart(void) { /* FIXME: all this is an ugly hack */ - FARPROC32 entry = (FARPROC32)RVA_PTR( PROCESS_Current()->exe_modref->module, OptionalHeader.AddressOfEntryPoint ); + LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE) + RVA_PTR(pModule->module32, OptionalHeader.AddressOfEntryPoint); + DWORD size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve; + DWORD id; + THDB *thdb; pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc; if (pModule->heap_size) @@ -246,22 +252,27 @@ static void TASK_CallToStart(void) InitApp( pTask->hModule ); PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, (LPVOID)-1 ); TRACE(relay, "(entryproc=%p)\n", entry ); - exit_code = entry(); - TASK_KillCurrentTask( exit_code ); - } -#ifdef linux - else if (pModule->lpDosTask) - { - int stat; - while ((stat = MZ_RunModule(pModule->lpDosTask)) >= 0) - if (stat > 0 && DOSVM_Process(pModule->lpDosTask) < 0) - break; +#if 1 + ExitProcess( entry(NULL) ); +#else + CreateThread( NULL, size, entry, NULL, 0, &id ); + thdb = THREAD_ID_TO_THDB( id ); - MZ_KillModule(pModule->lpDosTask); - TASK_KillCurrentTask( 0 ); - } + while ( thdb->exit_code == 0x103 ) + { + WaitEvent( 0 ); + QUEUE_Signal( pTask->hSelf ); + } + + ExitProcess( thdb->exit_code ); #endif + } + else if (pModule->dos_image) + { + DOSVM_Enter( NULL ); + ExitProcess( 0 ); + } else { /* Registers at initialization must be: @@ -295,13 +306,17 @@ static void TASK_CallToStart(void) Callbacks->CallRegisterShortProc( &context, 0 ); /* This should never return */ ERR( task, "Main program returned! (should never happen)\n" ); - TASK_KillCurrentTask( 1 ); + ExitProcess( 1 ); } } /*********************************************************************** * TASK_Create + * + * NOTE: This routine might be called by a Win32 thread. We don't have + * any real problems with that, since we operated merely on a private + * TDB structure that is not yet linked into the task list. */ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance, UINT16 cmdShow) @@ -339,7 +354,7 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, pTask->hInstance = hInstance; pTask->hPrevInstance = hPrevInstance; pTask->hModule = pModule->self; - pTask->hParent = hCurrentTask; + pTask->hParent = GetCurrentTask(); pTask->magic = TDB_MAGIC; pTask->nCmdShow = cmdShow; pTask->thdb = thdb; @@ -439,9 +454,6 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, if (!THREAD_Current()->cur_stack) THREAD_Current()->cur_stack = pTask->thdb->cur_stack; - /* Add the task to the linked list */ - - TASK_LinkTask( hTask ); TRACE(task, "module='%s' cmdline='%s' task=%04x\n", name, cmd_line, hTask ); @@ -449,6 +461,35 @@ HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, return hTask; } +/*********************************************************************** + * TASK_StartTask + * + * NOTE: This routine might be called by a Win32 thread. Thus, we need + * to be careful to protect global data structures. We do this + * by entering the Win16Lock while linking the task into the + * global task list. + */ +void TASK_StartTask( HTASK16 hTask ) +{ + /* Add the task to the linked list */ + + SYSLEVEL_EnterWin16Lock(); + TASK_LinkTask( hTask ); + SYSLEVEL_LeaveWin16Lock(); + + TRACE(task, "linked task %04x\n", hTask ); + + /* Get the task up and running. If we ourselves are a 16-bit task, + we simply Yield(). If we are 32-bit however, we need to signal + the main process somehow (NOT YET IMPLEMENTED!) */ + + if ( GetCurrentTask() ) + if ( THREAD_IsWin16( THREAD_Current() ) ) + Yield16(); + else + FIXME(task, "Don't know how to start 16-bit task from 32-bit thread. Move the mouse!\n"); +} + /*********************************************************************** * TASK_DeleteTask @@ -498,9 +539,25 @@ static void TASK_DeleteTask( HTASK16 hTask ) */ void TASK_KillCurrentTask( INT16 exitCode ) { - TDB* pTask = (TDB*) GlobalLock16( hCurrentTask ); + TDB* pTask = (TDB*) GlobalLock16( GetCurrentTask() ); + NE_MODULE* pModule = NE_GetPtr( pTask->hModule ); if (!pTask) USER_ExitWindows(); /* No current task yet */ + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return; + } + + /* Enter the Win16Lock to protect global data structures + NOTE: We never explicitly leave it again. This shouldn't matter + though, as it will be released in TASK_Reschedule and this + task won't ever get scheduled again ... */ + + SYSLEVEL_EnterWin16Lock(); + + assert(hCurrentTask == GetCurrentTask()); + TRACE(task, "Killing task %04x\n", hCurrentTask ); /* Delete active sockets */ @@ -508,6 +565,12 @@ void TASK_KillCurrentTask( INT16 exitCode ) if( pTask->pwsi ) WINSOCK_DeleteTaskWSI( pTask, pTask->pwsi ); +#ifdef MZ_SUPPORTED + /* Kill DOS VM task */ + if ( pModule->lpDosTask ) + MZ_KillModule( pModule->lpDosTask ); +#endif + /* Perform USER cleanup */ if (pTask->userhandler) @@ -567,9 +630,15 @@ void TASK_Reschedule(void) HTASK16 hTask = 0; STACK16FRAME *newframe16; - SYSLEVEL_ReleaseWin16Lock(); + /* NOTE: As we are entered from 16-bit code, we hold the Win16Lock. + We hang onto it thoughout most of this routine, so that accesses + to global variables (most notably the task list) are protected. */ + assert(hCurrentTask == GetCurrentTask()); + + TRACE(task, "entered with hTask %04x (pid %d)\n", hCurrentTask, getpid()); #ifdef CONFIG_IPC + /* FIXME: What about the Win16Lock ??? */ dde_reschedule(); #endif /* First check if there's a task to kill */ @@ -616,13 +685,19 @@ void TASK_Reschedule(void) /* No task found, wait for some events to come in */ + /* NOTE: We release the Win16Lock while waiting for events. This is to enable + Win32 threads to thunk down to 16-bit temporarily. Since Win16 + tasks won't execute and Win32 threads are not allowed to enter + TASK_Reschedule anyway, there should be no re-entrancy problem ... */ + + SYSLEVEL_ReleaseWin16Lock(); EVENT_WaitNetEvent( TRUE, TRUE ); + SYSLEVEL_RestoreWin16Lock(); } if (hTask == hCurrentTask) { TRACE(task, "returning to the current task(%04x)\n", hTask ); - SYSLEVEL_RestoreWin16Lock(); return; /* Nothing to do */ } pNewTask = (TDB *)GlobalLock16( hTask ); @@ -655,6 +730,12 @@ void TASK_Reschedule(void) /* Switch to the new stack */ + /* NOTE: We need to release/restore the Win16Lock, as the task + switched to might be at another recursion level than + the old task ... */ + + SYSLEVEL_ReleaseWin16Lock(); + hCurrentTask = hTask; SET_CUR_THREAD( pNewTask->thdb ); pNewTask->ss_sp = pNewTask->thdb->cur_stack; @@ -673,6 +754,12 @@ void TASK_YieldToSystem(TDB* pTask) { MESSAGEQUEUE* pQ; + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return; + } + Callbacks->CallTaskRescheduleProc(); if( pTask ) @@ -702,7 +789,7 @@ void WINAPI InitTask( CONTEXT *context ) LONG stacklow, stackhi; if (context) EAX_reg(context) = 0; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; if (!(pModule = NE_GetPtr( pTask->hModule ))) return; /* This is a hack to install task USER signal handler before @@ -770,8 +857,15 @@ BOOL16 WINAPI WaitEvent( HTASK16 hTask ) { TDB *pTask; - if (!hTask) hTask = hCurrentTask; + if (!hTask) hTask = GetCurrentTask(); pTask = (TDB *)GlobalLock16( hTask ); + + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return TRUE; + } + if (pTask->nEvents > 0) { pTask->nEvents--; @@ -793,8 +887,16 @@ void WINAPI PostEvent( HTASK16 hTask ) { TDB *pTask; - if (!hTask) hTask = hCurrentTask; + if (!hTask) hTask = GetCurrentTask(); if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; + + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + memset(0, 0, 4096); + return; + } + pTask->nEvents++; } @@ -807,7 +909,7 @@ void WINAPI SetPriority( HTASK16 hTask, INT16 delta ) TDB *pTask; INT16 newpriority; - if (!hTask) hTask = hCurrentTask; + if (!hTask) hTask = GetCurrentTask(); if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; newpriority = pTask->priority + delta; if (newpriority < -32) newpriority = -32; @@ -825,7 +927,7 @@ void WINAPI SetPriority( HTASK16 hTask, INT16 delta ) */ HTASK16 WINAPI LockCurrentTask( BOOL16 bLock ) { - if (bLock) hLockedTask = hCurrentTask; + if (bLock) hLockedTask = GetCurrentTask(); else hLockedTask = 0; return hLockedTask; } @@ -845,9 +947,14 @@ HTASK16 WINAPI IsTaskLocked(void) */ void WINAPI OldYield(void) { - TDB *pCurTask; + TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); + + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return; + } - pCurTask = (TDB *)GlobalLock16( hCurrentTask ); if (pCurTask) pCurTask->nEvents++; /* Make sure we get back here */ TASK_YieldToSystem(pCurTask); if (pCurTask) pCurTask->nEvents--; @@ -859,7 +966,14 @@ void WINAPI OldYield(void) */ void WINAPI DirectedYield( HTASK16 hTask ) { - TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask ); + TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); + + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return; + } + pCurTask->hYieldTo = hTask; OldYield(); } @@ -870,8 +984,15 @@ void WINAPI DirectedYield( HTASK16 hTask ) */ void WINAPI UserYield(void) { - TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask ); + TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue ); + + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return; + } + /* Handle sent messages */ while (queue && (queue->wakeBits & QS_SENDMESSAGE)) QUEUE_ReceiveMessage( queue ); @@ -889,7 +1010,14 @@ void WINAPI UserYield(void) */ void WINAPI Yield16(void) { - TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask ); + TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); + + if ( !THREAD_IsWin16( THREAD_Current() ) ) + { + FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel); + return; + } + if (pCurTask) pCurTask->hYieldTo = 0; if (pCurTask && pCurTask->hQueue) UserYield(); else OldYield(); @@ -905,7 +1033,7 @@ FARPROC16 WINAPI MakeProcInstance16( FARPROC16 func, HANDLE16 hInstance ) SEGPTR thunkaddr; if (!hInstance) hInstance = CURRENT_DS; - thunkaddr = TASK_AllocThunk( hCurrentTask ); + thunkaddr = TASK_AllocThunk( GetCurrentTask() ); if (!thunkaddr) return (FARPROC16)0; thunk = PTR_SEG_TO_LIN( thunkaddr ); lfunc = PTR_SEG_TO_LIN( func ); @@ -935,7 +1063,7 @@ FARPROC16 WINAPI MakeProcInstance16( FARPROC16 func, HANDLE16 hInstance ) void WINAPI FreeProcInstance16( FARPROC16 func ) { TRACE(task, "(%08lx)\n", (DWORD)func ); - TASK_FreeThunk( hCurrentTask, (SEGPTR)func ); + TASK_FreeThunk( GetCurrentTask(), (SEGPTR)func ); } @@ -977,7 +1105,7 @@ HQUEUE16 WINAPI SetTaskQueue( HTASK16 hTask, HQUEUE16 hQueue ) HQUEUE16 hPrev; TDB *pTask; - if (!hTask) hTask = hCurrentTask; + if (!hTask) hTask = GetCurrentTask(); if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; hPrev = pTask->hQueue; @@ -996,7 +1124,7 @@ HQUEUE16 WINAPI GetTaskQueue( HTASK16 hTask ) { TDB *pTask; - if (!hTask) hTask = hCurrentTask; + if (!hTask) hTask = GetCurrentTask(); if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; return pTask->hQueue; } @@ -1012,7 +1140,7 @@ void WINAPI SwitchStackTo( WORD seg, WORD ptr, WORD top ) INSTANCEDATA *pData; UINT16 copySize; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return; TRACE(task, "old=%04x:%04x new=%04x:%04x\n", SELECTOROF( pTask->thdb->cur_stack ), @@ -1056,7 +1184,7 @@ void WINAPI SwitchStackBack( CONTEXT *context ) STACK16FRAME *oldFrame, *newFrame; INSTANCEDATA *pData; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(pTask->thdb->cur_stack)))) return; if (!pData->old_ss_sp) @@ -1116,14 +1244,14 @@ void WINAPI GetTaskQueueES( CONTEXT *context ) */ HTASK16 WINAPI GetCurrentTask(void) { - return hCurrentTask; + return THREAD_InitDone? PROCESS_Current()->task : 0; } DWORD WINAPI WIN16_GetCurrentTask(void) { /* This is the version used by relay code; the first task is */ /* returned in the high word of the result */ - return MAKELONG( hCurrentTask, hFirstTask ); + return MAKELONG( GetCurrentTask(), hFirstTask ); } @@ -1134,7 +1262,7 @@ HANDLE16 WINAPI GetCurrentPDB(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; return pTask->hPDB; } @@ -1159,7 +1287,7 @@ WORD WINAPI GetExeVersion(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; return pTask->version; } @@ -1172,7 +1300,7 @@ UINT16 WINAPI SetErrorMode16( UINT16 mode ) TDB *pTask; UINT16 oldMode; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; oldMode = pTask->error_mode; pTask->error_mode = mode; pTask->thdb->process->error_mode = mode; @@ -1196,7 +1324,7 @@ SEGPTR WINAPI GetDOSEnvironment(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; return PTR_SEG_OFF_TO_SEGPTR( pTask->pdb.environment, 0 ); } @@ -1220,7 +1348,7 @@ HINSTANCE16 WINAPI GetTaskDS(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; return pTask->hInstance; } @@ -1248,7 +1376,7 @@ FARPROC16 WINAPI SetTaskSignalProc( HTASK16 hTask, FARPROC16 proc ) TDB *pTask; FARPROC16 oldProc; - if (!hTask) hTask = hCurrentTask; + if (!hTask) hTask = GetCurrentTask(); if (!(pTask = (TDB *)GlobalLock16( hTask ))) return NULL; oldProc = (FARPROC16)pTask->userhandler; pTask->userhandler = (USERSIGNALPROC)proc; @@ -1271,7 +1399,7 @@ WORD WINAPI SetSigHandler( FARPROC16 newhandler, FARPROC16* oldhandler, { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; if (oldmode) *oldmode = pTask->signal_flags; pTask->signal_flags = newmode; if (oldhandler) *oldhandler = pTask->sighandler; @@ -1288,7 +1416,7 @@ VOID WINAPI GlobalNotify( FARPROC16 proc ) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; + if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; pTask->discardhandler = proc; } diff --git a/misc/Makefile.in b/misc/Makefile.in index 420d9e237ec..c1d31707a54 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -25,7 +25,6 @@ C_SRCS = \ printdrv.c \ registry.c \ shell.c \ - shellord.c \ sound.c \ spy.c \ stress.c \ diff --git a/misc/commdlg.c b/misc/commdlg.c index db21377f688..007f4735ea5 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -73,7 +73,7 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) if (lpofn->Flags & OFN_WINE32) { if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) { - if (!(template = LockResource32( lpofn->hInstance ))) + if (!(template = LockResource32( MapHModuleSL(lpofn->hInstance )))) { CommDlgLastError = CDERR_LOADRESFAILURE; return FALSE; @@ -81,13 +81,14 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) } else if (lpofn->Flags & OFN_ENABLETEMPLATE) { - if (!(hResInfo = FindResource32A(lpofn->hInstance, + if (!(hResInfo = FindResource32A(MapHModuleSL(lpofn->hInstance), PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOG32A))) { CommDlgLastError = CDERR_FINDRESFAILURE; return FALSE; } - if (!(hDlgTmpl = LoadResource32( lpofn->hInstance, hResInfo )) || + if (!(hDlgTmpl = LoadResource32( MapHModuleSL(lpofn->hInstance), + hResInfo )) || !(template = LockResource32( hDlgTmpl ))) { CommDlgLastError = CDERR_LOADRESFAILURE; @@ -198,7 +199,7 @@ BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn) if (lpofn->Flags & OFN_WINE32) { if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) { - if (!(template = LockResource32( lpofn->hInstance ))) + if (!(template = LockResource32( MapHModuleSL(lpofn->hInstance )))) { CommDlgLastError = CDERR_LOADRESFAILURE; return FALSE; @@ -207,14 +208,15 @@ BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn) else if (lpofn->Flags & OFN_ENABLETEMPLATE) { HANDLE32 hResInfo; - if (!(hResInfo = FindResource32A(lpofn->hInstance, + if (!(hResInfo = FindResource32A(MapHModuleSL(lpofn->hInstance), PTR_SEG_TO_LIN(lpofn->lpTemplateName), RT_DIALOG32A))) { CommDlgLastError = CDERR_FINDRESFAILURE; return FALSE; } - if (!(hDlgTmpl = LoadResource32(lpofn->hInstance,hResInfo)) || + if (!(hDlgTmpl = LoadResource32(MapHModuleSL(lpofn->hInstance), + hResInfo)) || !(template = LockResource32(hDlgTmpl))) { CommDlgLastError = CDERR_LOADRESFAILURE; @@ -3646,8 +3648,7 @@ static BOOL32 Commdlg_GetFileName32A( BOOL16 (CALLBACK *dofunction)(SEGPTR x), memset(ofn16,'\0',sizeof(*ofn16)); ofn16->lStructSize = sizeof(*ofn16); ofn16->hwndOwner = ofn->hwndOwner; - /* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */ - ofn16->hInstance = 0; + ofn16->hInstance = MapHModuleLS(ofn->hInstance); if (ofn->lpstrFilter) { LPSTR s,x; @@ -3736,8 +3737,7 @@ static BOOL32 Commdlg_GetFileName32W( BOOL16 (CALLBACK *dofunction)(SEGPTR x), memset(ofn16,'\0',sizeof(*ofn16)); ofn16->lStructSize = sizeof(*ofn16); ofn16->hwndOwner = ofn->hwndOwner; - /* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */ - ofn16->hInstance = 0; + ofn16->hInstance = MapHModuleLS(ofn->hInstance); if (ofn->lpstrFilter) { LPWSTR s; LPSTR x,y; @@ -3881,7 +3881,7 @@ BOOL32 WINAPI ChooseColor32A(LPCHOOSECOLOR32A lpChCol ) memset(lpcc16,'\0',sizeof(*lpcc16)); lpcc16->lStructSize=sizeof(*lpcc16); lpcc16->hwndOwner=lpChCol->hwndOwner; - lpcc16->hInstance=0; /* FIXME:MODULE_HANDLEtoHMODULE16(lpChCol->hInstance)*/ + lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance); lpcc16->rgbResult=lpChCol->rgbResult; memcpy(ccref,lpChCol->lpCustColors,64); lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref); @@ -3915,7 +3915,7 @@ BOOL32 WINAPI ChooseColor32W(LPCHOOSECOLOR32W lpChCol ) memset(lpcc16,'\0',sizeof(*lpcc16)); lpcc16->lStructSize=sizeof(*lpcc16); lpcc16->hwndOwner=lpChCol->hwndOwner; - lpcc16->hInstance=0; /*FIXME:MODULE_HANDLEtoHMODULE16(lpChCol->hInstance)*/ + lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance); lpcc16->rgbResult=lpChCol->rgbResult; memcpy(ccref,lpChCol->lpCustColors,64); lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref); diff --git a/misc/imagelist.c b/misc/imagelist.c index 4c3125d066b..8cafd4abe64 100644 --- a/misc/imagelist.c +++ b/misc/imagelist.c @@ -556,7 +556,7 @@ ImageList_Create (INT32 cx, INT32 cy, UINT32 flags, himl->clrBk = CLR_NONE; /* initialize overlay mask indices */ - for (nCount = 0; nCount <= MAX_OVERLAYIMAGE; nCount++) + for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++) himl->nOvlIdx[nCount] = -1; hdc = CreateCompatibleDC32 (0); @@ -1691,7 +1691,7 @@ ImageList_Remove (HIMAGELIST himl, INT32 i) himl->cMaxImage = himl->cInitial + himl->cGrow; himl->cCurImage = 0; - for (nCount = 0; nCount <= MAX_OVERLAYIMAGE; nCount++) + for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++) himl->nOvlIdx[nCount] = -1; DeleteObject32 (himl->hbmImage); @@ -1921,10 +1921,10 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT32 i, HICON32 hIcon) if (hdcImage) DeleteDC32 (hdcImage); -// FIXME (imagelist, "deleting hbmColor!\n"); - DeleteObject32 (ii.hbmColor); -// FIXME (imagelist, "deleted hbmColor!\n"); - DeleteObject32 (ii.hbmMask); + if (ii.hbmColor) + DeleteObject32 (ii.hbmColor); + if (ii.hbmMask) + DeleteObject32 (ii.hbmMask); return (nIndex); } diff --git a/misc/lstr.c b/misc/lstr.c index 02550496ed9..b2b4ae03dd1 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -668,6 +668,7 @@ DWORD WINAPI FormatMessage32A( if (nSize && talloced +#include +#include +#include #include "windows.h" #include "winerror.h" @@ -425,6 +428,31 @@ UINT16 WINAPI WNetGetUser(LPSTR lpLocalName, LPSTR lpUserName, DWORD *lpSize) return WN_NO_NETWORK; } +/************************************************************************** + * WNetGetUser [MPR.86] + * FIXME: we should not return ourselves, but the owner of the drive lpLocalName + */ +DWORD WINAPI WNetGetUser32A(LPCSTR lpLocalName, LPSTR lpUserName, DWORD *lpSize) +{ + struct passwd *pwd = getpwuid(getuid()); + + FIXME(wnet, "(%s, %p, %p), mostly stub\n", lpLocalName, lpUserName, lpSize); + if (pwd) { + if (strlen(pwd->pw_name)+1>*lpSize) { + *lpSize = strlen(pwd->pw_name)+1; + SetLastError(ERROR_MORE_DATA); + return ERROR_MORE_DATA; + } + strcpy(lpUserName,pwd->pw_name); + if (lpSize) + *lpSize = strlen(pwd->pw_name)+1; + return WN_SUCCESS; + } + /* FIXME: wrong return value */ + SetLastError(ERROR_NO_NETWORK); + return ERROR_NO_NETWORK; +} + /************************************************************************** * WNetGetError [USER.519] */ diff --git a/misc/registry.c b/misc/registry.c index 6f7ff914b7f..b2d1de4eded 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -99,7 +99,9 @@ static struct openhandle { } *openhandles=NULL; static int nrofopenhandles=0; /* Starts after 1 because 0,1 are reserved for Win16 */ -static int currenthandle=1; +/* Note: Should always be even, as Win95 ADVAPI32.DLL reserves odd + HKEYs for remote registry access */ +static int currenthandle=2; /* @@ -1743,7 +1745,8 @@ DWORD WINAPI RegOpenKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, DWORD dwReserved, if (!lpszSubKey || !*lpszSubKey) { /* Either NULL or pointer to empty string, so return a new handle to the original hkey */ - add_handle(++currenthandle,lpNextKey,samDesired); + currenthandle += 2; + add_handle(currenthandle,lpNextKey,samDesired); *retkey=currenthandle; return ERROR_SUCCESS; } @@ -1776,7 +1779,8 @@ DWORD WINAPI RegOpenKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, DWORD dwReserved, lpNextKey = lpxkey; } - add_handle(++currenthandle,lpxkey,samDesired); + currenthandle += 2; + add_handle(currenthandle,lpxkey,samDesired); *retkey = currenthandle; TRACE(reg," Returning %x\n", currenthandle); FREE_KEY_PATH; @@ -1909,7 +1913,8 @@ DWORD WINAPI RegCreateKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, return ERROR_INVALID_PARAMETER; if (!lpszSubKey || !*lpszSubKey) { - add_handle(++currenthandle,lpNextKey,samDesired); + currenthandle += 2; + add_handle(currenthandle,lpNextKey,samDesired); *retkey=currenthandle; TRACE(reg, "Returning %x\n", currenthandle); lpNextKey->flags|=REG_OPTION_TAINTED; @@ -1938,7 +1943,8 @@ DWORD WINAPI RegCreateKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, lpNextKey = lpxkey; } if (lpxkey) { - add_handle(++currenthandle,lpxkey,samDesired); + currenthandle += 2; + add_handle(currenthandle,lpxkey,samDesired); lpxkey->flags |= REG_OPTION_TAINTED; *retkey = currenthandle; TRACE(reg, "Returning %x\n", currenthandle); @@ -1977,7 +1983,8 @@ DWORD WINAPI RegCreateKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, lpNextKey = *lplpPrevKey; i++; } - add_handle(++currenthandle,lpNextKey,samDesired); + currenthandle += 2; + add_handle(currenthandle,lpNextKey,samDesired); /*FIXME: flag handling correct? */ lpNextKey->flags= fdwOptions |REG_OPTION_TAINTED; diff --git a/misc/shell.c b/misc/shell.c index 1b8ebbf00e9..6cdeec80b3d 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -2,9 +2,6 @@ * Shell Library Functions * * 1998 Marcus Meissner - * 1998 Juergen Schmied (jsch) - * currently work in progress on SH* and SHELL32_DllGetClassObject functions - * */ #include #include @@ -31,156 +28,6 @@ #include "imagelist.h" #include "commctrl.h" -/* FIXME should be moved to a header file. IsEqualGUID -is declared but not exported in compobj.c !!!*/ -#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) - -static const char * const SHELL_People[] = -{ - "Bob Amstadt", - "Dag Asheim", - "Martin Ayotte", - "Karl Backström", - "Peter Bajusz", - "Marcel Baur", - "Georg Beyerle", - "Ross Biro", - "Martin Boehme", - "Uwe Bonnes", - "Erik Bos", - "Fons Botman", - "John Brezak", - "Andrew Bulhak", - "John Burton", - "Niels de Carpentier", - "Gordon Chaffee", - "Jimen Ching", - "Pascal Cuoq", - "David A. Cuthbert", - "Huw D. M. Davies", - "Roman Dolejsi", - "Frans van Dorsselaer", - "Chris Faherty", - "Carsten Fallesen", - "Paul Falstad", - "David Faure", - "Claus Fischer", - "Olaf Flebbe", - "Chad Fraleigh", - "Matthew Francis", - "Peter Galbavy", - "Ramon Garcia", - "Matthew Ghio", - "Jody Goldberg", - "Hans de Graaff", - "Charles M. Hannum", - "Adrian Harvey", - "John Harvey", - "Bill Hawes", - "Cameron Heide", - "Jochen Hoenicke", - "Onno Hovers", - "Jeffrey Hsu", - "Miguel de Icaza", - "Jukka Iivonen", - "Lee Jaekil", - "Alexandre Julliard", - "Bang Jun-Young", - "Pavel Kankovsky", - "Jochen Karrer", - "Andreas Kirschbaum", - "Rein Klazes", - "Albrecht Kleine", - "Eric Kohl", - "Jon Konrath", - "Alex Korobka", - "Greg Kreider", - "Anand Kumria", - "Ove Kåven", - "Scott A. Laird", - "David Lee Lambert", - "Andrew Lewycky", - "Per Lindström", - "Martin von Loewis", - "Michiel van Loon", - "Kenneth MacDonald", - "Peter MacDonald", - "William Magro", - "Juergen Marquardt", - "Ricardo Massaro", - "Marcus Meissner", - "Graham Menhennitt", - "David Metcalfe", - "Bruce Milner", - "Steffen Moeller", - "Andreas Mohr", - "James Moody", - "Philippe De Muyter", - "Itai Nahshon", - "Kristian Nielsen", - "Henrik Olsen", - "Michael Patra", - "Dimitrie O. Paun", - "Jim Peterson", - "Robert Pouliot", - "Keith Reynolds", - "Slaven Rezic", - "John Richardson", - "Rick Richardson", - "Doug Ridgway", - "Bernhard Rosenkraenzer", - "Johannes Ruscheinski", - "Thomas Sandford", - "Constantine Sapuntzakis", - "Pablo Saratxaga", - "Daniel Schepler", - "Peter Schlaile", - "Ulrich Schmid", - "Bernd Schmidt", - "Juergen Schmied", - "Ingo Schneider", - "Victor Schneider", - "Yngvi Sigurjonsson", - "Stephen Simmons", - "Rick Sladkey", - "William Smith", - "Dominik Strasser", - "Vadim Strizhevsky", - "Bertho Stultiens", - "Erik Svendsen", - "Tristan Tarrant", - "Andrew Taylor", - "Duncan C Thomson", - "Goran Thyni", - "Jimmy Tirtawangsa", - "Jon Tombs", - "Linus Torvalds", - "Gregory Trubetskoy", - "Petri Tuomola", - "Michael Veksler", - "Sven Verdoolaege", - "Ronan Waide", - "Eric Warnke", - "Manfred Weichel", - "Ulrich Weigand", - "Morten Welinder", - "Len White", - "Lawson Whitney", - "Jan Willamowius", - "Carl Williams", - "Karl Guenter Wuensch", - "Eric Youngdale", - "James Youngman", - "Nikita V. Youshchenko", - "Mikolaj Zalewski", - "John Zero", - "Luiz Otavio L. Zorzella", - NULL -}; - - /* .ICO file ICONDIR definitions */ #pragma pack(1) @@ -301,7 +148,7 @@ BOOL16 WINAPI DragQueryPoint(HDROP16 hDrop, POINT16 *p) * * Utility for code sharing between FindExecutable and ShellExecute */ -static HINSTANCE32 SHELL_FindExecutable( LPCSTR lpFile, +HINSTANCE32 SHELL_FindExecutable( LPCSTR lpFile, LPCSTR lpOperation, LPSTR lpResult) { char *extension = NULL; /* pointer to file extension */ @@ -485,18 +332,6 @@ HINSTANCE16 WINAPI ShellExecute16( HWND16 hWnd, LPCSTR lpOperation, return retval; } - -/************************************************************************* - * ShellExecute32A (SHELL32.245) - */ -HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation, - LPCSTR lpFile, LPCSTR lpParameters, - LPCSTR lpDirectory, INT32 iShowCmd ) -{ TRACE(shell,"\n"); - return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters, - lpDirectory, iShowCmd ); -} - /************************************************************************* * FindExecutable16 (SHELL.21) */ @@ -505,190 +340,6 @@ HINSTANCE16 WINAPI FindExecutable16( LPCSTR lpFile, LPCSTR lpDirectory, { return (HINSTANCE16)FindExecutable32A( lpFile, lpDirectory, lpResult ); } -/************************************************************************* - * FindExecutable32A (SHELL32.184) - */ -HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory, - LPSTR lpResult ) -{ HINSTANCE32 retval=31; /* default - 'No association was found' */ - char old_dir[1024]; - - TRACE(shell, "File %s, Dir %s\n", - (lpFile != NULL?lpFile:"-"), - (lpDirectory != NULL?lpDirectory:"-")); - - lpResult[0]='\0'; /* Start off with an empty return string */ - - /* trap NULL parameters on entry */ - if (( lpFile == NULL ) || ( lpResult == NULL )) - { /* FIXME - should throw a warning, perhaps! */ - return 2; /* File not found. Close enough, I guess. */ - } - - if (lpDirectory) - { GetCurrentDirectory32A( sizeof(old_dir), old_dir ); - SetCurrentDirectory32A( lpDirectory ); - } - - retval = SHELL_FindExecutable( lpFile, "open", lpResult ); - - TRACE(shell, "returning %s\n", lpResult); - if (lpDirectory) - SetCurrentDirectory32A( old_dir ); - return retval; -} - -typedef struct -{ LPCSTR szApp; - LPCSTR szOtherStuff; - HICON32 hIcon; -} ABOUT_INFO; - -#define IDC_STATIC_TEXT 100 -#define IDC_LISTBOX 99 -#define IDC_WINE_TEXT 98 - -#define DROP_FIELD_TOP (-15) -#define DROP_FIELD_HEIGHT 15 - -extern HICON32 hIconTitleFont; - -static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect ) -{ HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT); - if( hWndCtl ) - { GetWindowRect32( hWndCtl, lprect ); - MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 ); - lprect->bottom = (lprect->top += DROP_FIELD_TOP); - return TRUE; - } - return FALSE; -} - -/************************************************************************* - * AboutDlgProc32 (not an exported API function) - */ -LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam, - LPARAM lParam ) -{ HWND32 hWndCtl; - char Template[512], AppTitle[512]; - - TRACE(shell,"\n"); - - switch(msg) - { case WM_INITDIALOG: - { ABOUT_INFO *info = (ABOUT_INFO *)lParam; - if (info) - { const char* const *pstr = SHELL_People; - SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0); - GetWindowText32A( hWnd, Template, sizeof(Template) ); - sprintf( AppTitle, Template, info->szApp ); - SetWindowText32A( hWnd, AppTitle ); - SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), - info->szOtherStuff ); - hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX); - SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 ); - SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 ); - while (*pstr) - { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr ); - pstr++; - } - SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 ); - } - } - return 1; - - case WM_PAINT: - { RECT32 rect; - PAINTSTRUCT32 ps; - HDC32 hDC = BeginPaint32( hWnd, &ps ); - - if( __get_dropline( hWnd, &rect ) ) - GRAPH_DrawLines( hDC, (LPPOINT32)&rect, 1, GetStockObject32( BLACK_PEN ) ); - EndPaint32( hWnd, &ps ); - } - break; - - case WM_LBTRACKPOINT: - hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX); - if( (INT16)GetKeyState16( VK_CONTROL ) < 0 ) - { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) ) - { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 ); - if( idx != -1 ) - { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 ); - HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 ); - char* pstr = (char*)GlobalLock16( hMemObj ); - - if( pstr ) - { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) ); - SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr ); - SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 ); - UpdateWindow32( hWndCtl ); - if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) ) - SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr ); - } - if( hMemObj ) - GlobalFree16( hMemObj ); - } - } - } - break; - - case WM_QUERYDROPOBJECT: - if( wParam == 0 ) - { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); - if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA ) - { RECT32 rect; - if( __get_dropline( hWnd, &rect ) ) - { POINT32 pt = { lpDragInfo->pt.x, lpDragInfo->pt.y }; - rect.bottom += DROP_FIELD_HEIGHT; - if( PtInRect32( &rect, pt ) ) - { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 ); - return TRUE; - } - } - } - } - break; - - case WM_DROPOBJECT: - if( wParam == hWnd ) - { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); - if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList ) - { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) ); - if( pstr ) - { static char __appendix_str[] = " with"; - - hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT ); - SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template ); - if( !lstrncmp32A( Template, "WINE", 4 ) ) - SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template ); - else - { char* pch = Template + strlen(Template) - strlen(__appendix_str); - *pch = '\0'; - SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, - (WPARAM32)-1, (LPARAM)Template ); - } - - lstrcpy32A( Template, pstr ); - lstrcat32A( Template, __appendix_str ); - SetWindowText32A( hWndCtl, Template ); - SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 ); - return TRUE; - } - } - } - break; - - case WM_COMMAND: - if (wParam == IDOK) - { EndDialog32(hWnd, TRUE); - return TRUE; - } - break; - } - return 0; -} - /************************************************************************* * AboutDlgProc16 (SHELL.33) @@ -707,69 +358,6 @@ BOOL16 WINAPI ShellAbout16( HWND16 hWnd, LPCSTR szApp, LPCSTR szOtherStuff, { return ShellAbout32A( hWnd, szApp, szOtherStuff, hIcon ); } -/************************************************************************* - * ShellAbout32A (SHELL32.243) - */ -BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff, - HICON32 hIcon ) -{ ABOUT_INFO info; - TRACE(shell,"\n"); - info.szApp = szApp; - info.szOtherStuff = szOtherStuff; - info.hIcon = hIcon; - if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); - return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ), - SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ), - hWnd, AboutDlgProc32, (LPARAM)&info ); -} - - -/************************************************************************* - * ShellAbout32W (SHELL32.244) - */ -BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, - HICON32 hIcon ) -{ BOOL32 ret; - ABOUT_INFO info; - - TRACE(shell,"\n"); - - info.szApp = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp ); - info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff ); - info.hIcon = hIcon; - if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); - ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ), - SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ), - hWnd, AboutDlgProc32, (LPARAM)&info ); - HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp ); - HeapFree( GetProcessHeap(), 0, (LPSTR)info.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 ) -{ TRACE(shell,"\n"); - 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 ) -{ TRACE(shell,"\n"); - return FALSE; -} - /************************************************************************* * SHELL_GetResourceTable */ @@ -1186,40 +774,6 @@ HICON16 WINAPI ExtractIcon16( HINSTANCE16 hInstance, LPCSTR lpszExeFileName, } -/************************************************************************* - * ExtractIcon32A (SHELL32.133) - */ -HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName, - UINT32 nIconIndex ) -{ HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1); - TRACE(shell,"\n"); - if( handle ) - { - HICON16* ptr = (HICON16*)GlobalLock16(handle); - HICON16 hIcon = *ptr; - - GlobalFree16(handle); - return hIcon; - } - return 0; -} - -/************************************************************************* - * ExtractIcon32W (SHELL32.180) - */ -HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName, - UINT32 nIconIndex ) -{ LPSTR exefn; - HICON32 ret; - TRACE(shell,"\n"); - - exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName); - ret = ExtractIcon32A(hInstance,exefn,nIconIndex); - - HeapFree(GetProcessHeap(),0,exefn); - return ret; -} - /************************************************************************* * ExtractAssociatedIcon [SHELL.36] @@ -1430,652 +984,3 @@ BOOL32 WINAPI RegisterShellHook(HWND16 hWnd, UINT16 uAction) } return FALSE; } - -/************************************************************************* - * SHGetFileInfoA [SHELL32.218] - * - * FIXME - * - */ -HIMAGELIST ShellSmallIconList = 0; -HIMAGELIST ShellBigIconList = 0; - -DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes, - SHFILEINFO32A *psfi, UINT32 sizeofpsfi, - UINT32 flags ) -{ CHAR szTemp[MAX_PATH]; - DWORD ret=0; - - TRACE(shell,"(%s,0x%x,%p,0x%x,0x%x)\n", - path,dwFileAttributes,psfi,sizeofpsfi,flags); - - /* translate the pidl to a path*/ - if (flags & SHGFI_PIDL) - { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp); - TRACE(shell,"pidl=%p is %s\n",path,szTemp); - } - - if (flags & SHGFI_ATTRIBUTES) - { FIXME(shell,"file attributes, stub\n"); - psfi->dwAttributes=0; - ret=TRUE; - } - - if (flags & SHGFI_DISPLAYNAME) - { if (flags & SHGFI_PIDL) - { strcpy(psfi->szDisplayName,szTemp); - } - else - { strcpy(psfi->szDisplayName,path); - TRACE(shell,"displayname=%s\n", szTemp); - } - ret=TRUE; - } - - if (flags & SHGFI_TYPENAME) - { FIXME(shell,"get the file type, stub\n"); - strcpy(psfi->szTypeName,""); - ret=TRUE; - } - - if (flags & SHGFI_ICONLOCATION) - { FIXME(shell,"location of icon, stub\n"); - strcpy(psfi->szDisplayName,""); - ret=TRUE; - } - - if (flags & SHGFI_EXETYPE) - FIXME(shell,"type of executable, stub\n"); - - if (flags & SHGFI_LINKOVERLAY) - FIXME(shell,"set icon to link, stub\n"); - - if (flags & SHGFI_OPENICON) - FIXME(shell,"set to open icon, stub\n"); - - if (flags & SHGFI_SELECTED) - FIXME(shell,"set icon to selected, stub\n"); - - if (flags & SHGFI_SHELLICONSIZE) - FIXME(shell,"set icon to shell size, stub\n"); - - if (flags & SHGFI_USEFILEATTRIBUTES) - FIXME(shell,"use the dwFileAttributes, stub\n"); - - if (flags & SHGFI_ICON) - { FIXME(shell,"icon handle\n"); - if (flags & SHGFI_SMALLICON) - { TRACE(shell,"set to small icon\n"); - psfi->hIcon=ImageList_GetIcon(ShellSmallIconList,0,ILD_NORMAL); - ret = (DWORD) ShellSmallIconList; - } - else - { TRACE(shell,"set to big icon\n"); - psfi->hIcon=ImageList_GetIcon(ShellBigIconList,0,ILD_NORMAL); - ret = (DWORD) ShellBigIconList; - } - } - - if (flags & SHGFI_SYSICONINDEX) - { FIXME(shell,"get the SYSICONINDEX\n"); - psfi->iIcon=1; - if (flags & SHGFI_SMALLICON) - { TRACE(shell,"set to small icon\n"); - ret = (DWORD) ShellSmallIconList; - } - else - { TRACE(shell,"set to big icon\n"); - ret = (DWORD) ShellBigIconList; - } - } - - - return ret; -} - -/************************************************************************* - * SHAppBarMessage32 [SHELL32.207] - */ -UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data) -{ FIXME(shell,"(0x%08lx,%p): stub\n", msg, data); -#if 0 - switch (msg) - { case ABM_ACTIVATE: - case ABM_GETAUTOHIDEBAR: - case ABM_GETSTATE: - case ABM_GETTASKBARPOS: - case ABM_NEW: - case ABM_QUERYPOS: - case ABM_REMOVE: - case ABM_SETAUTOHIDEBAR: - case ABM_SETPOS: - case ABM_WINDOWPOSCHANGED: - ; - } -#endif - return 0; -} - -/************************************************************************* - * CommandLineToArgvW [SHELL32.7] - */ -LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs) -{ LPWSTR *argv,s,t; - int i; - TRACE(shell,"\n"); - - /* to get writeable copy */ - cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline); - s=cmdline;i=0; - while (*s) - { /* space */ - if (*s==0x0020) - { i++; - s++; - while (*s && *s==0x0020) - s++; - continue; - } - s++; - } - argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) ); - s=t=cmdline; - i=0; - while (*s) - { if (*s==0x0020) - { *s=0; - argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t ); - *s=0x0020; - while (*s && *s==0x0020) - s++; - if (*s) - t=s+1; - else - t=s; - continue; - } - s++; - } - if (*t) - argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t ); - HeapFree( GetProcessHeap(), 0, cmdline ); - argv[i]=NULL; - *numargs=i; - return argv; -} - -/************************************************************************* - * Control_RunDLL [SHELL32.12] - * - * Wild speculation in the following! - * - * http://premium.microsoft.com/msdn/library/techart/msdn193.htm - */ - -void WINAPI Control_RunDLL (HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4) -{ FIXME(shell, "(%08x, %p, \"%s\", %08lx)\n", - hwnd, code ? code : "(null)", cmd ? cmd : "(null)", arg4); -} - -/************************************************************************* - * FreeIconList - */ -void WINAPI FreeIconList( DWORD dw ) -{ FIXME(shell, "(%lx): stub\n",dw); -} - -/************************************************************************* - * SHELL32_DllGetClassObject [SHELL32.128] - * - * [Standart OLE/COM Interface Method] - * This Function retrives the pointer to a specified interface (iid) of - * a given class (rclsid). - * With this pointer it's possible to call the IClassFactory_CreateInstance - * method to get a instance of the requested Class. - * This function does NOT instantiate the Class!!! - * - * RETURNS - * HRESULT - * - */ -DWORD WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID *ppv) -{ HRESULT hres = E_OUTOFMEMORY; - LPCLASSFACTORY lpclf; - - char xclsid[50],xiid[50]; - WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); - WINE_StringFromCLSID((LPCLSID)iid,xiid); - TRACE(shell,"\n\tCLSID:\t%s,\n\tIID:\t%s\n",xclsid,xiid); - - *ppv = NULL; - if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)|| - IsEqualCLSID(rclsid, &CLSID_ShellLink)) - { if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)) /*debug*/ - TRACE(shell,"requested CLSID_ShellDesktop\n"); - if(IsEqualCLSID(rclsid, &CLSID_ShellLink)) /*debug*/ - TRACE(shell,"requested CLSID_ShellLink\n"); - - lpclf = IClassFactory_Constructor(); - if(lpclf) - { hres = lpclf->lpvtbl->fnQueryInterface(lpclf,iid, ppv); - lpclf->lpvtbl->fnRelease(lpclf); - } - } - else - { WARN(shell, "clsid(%s) not in buildin SHELL32\n",xclsid); - hres = CLASS_E_CLASSNOTAVAILABLE; - } - TRACE(shell,"RETURN pointer to interface: %p\n",ppv); - return hres; -} - -/************************************************************************* - * SHGetDesktopFolder [SHELL32.216] - * - * SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with - * CLSID_ShellDesktop - * CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf); - * - * RETURNS - * the interface to the shell desktop folder. - * - * FIXME - * the pdesktopfolder has to be released at the end (at dll unloading???) - */ -LPSHELLFOLDER pdesktopfolder=NULL; - -DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) -{ HRESULT hres = E_OUTOFMEMORY; - LPCLASSFACTORY lpclf; - TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder); - - if (pdesktopfolder) - { hres = NOERROR; - } - else - { lpclf = IClassFactory_Constructor(); - /* fixme: the buildin IClassFactory_Constructor is at the moment only - for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/ - if(lpclf) - { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder); - lpclf->lpvtbl->fnRelease(lpclf); - } - } - - if (pdesktopfolder) - { *shellfolder = pdesktopfolder; - pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder); - } - else - { *shellfolder=NULL; - } - - TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder); - return hres; -} - -/************************************************************************* - * 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(LPMALLOC32 *lpmal) -{ TRACE(shell,"(%p)\n", lpmal); - return CoGetMalloc32(0,lpmal); -} - -/************************************************************************* - * SHGetSpecialFolderLocation [SHELL32.223] - * gets the folder locations from the registry and creates a pidl - * creates missing reg keys and directorys - * - * PARAMS - * hwndOwner [I] - * nFolder [I] CSIDL_xxxxx - * ppidl [O] PIDL of a special folder - * - * RETURNS - * HResult - * - * FIXME - * - look for "User Shell Folder" first - * - */ -HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl) -{ LPSHELLFOLDER shellfolder; - DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res; - CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH]; - LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0]; - HKEY key; - - enum - { FT_UNKNOWN= 0x00000000, - FT_DIR= 0x00000001, - FT_DESKTOP= 0x00000002 - } tFolder; - - TRACE(shell,"(%04x,%d,%p)\n", hwndOwner,nFolder,ppidl); - - strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); - - res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp); - if (res) - { ERR(shell,"Could not create key %s %08lx \n",buffer,res); - return E_OUTOFMEMORY; - } - - tFolder=FT_DIR; - switch (nFolder) - { case CSIDL_BITBUCKET: - strcpy (buffer,"xxx"); /*not in the registry*/ - TRACE (shell,"looking for Recycler\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_CONTROLS: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE (shell,"looking for Control\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_DESKTOP: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE (shell,"looking for Desktop\n"); - tFolder=FT_DESKTOP; - break; - case CSIDL_DESKTOPDIRECTORY: - strcpy (buffer,"Desktop"); - break; - case CSIDL_DRIVES: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE (shell,"looking for Drives\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_FONTS: - strcpy (buffer,"Fonts"); - break; - case CSIDL_NETHOOD: - strcpy (buffer,"NetHood"); - break; - case CSIDL_NETWORK: - strcpy (buffer,"xxx"); /*virtual folder*/ - TRACE (shell,"looking for Network\n"); - tFolder=FT_UNKNOWN; - break; - case CSIDL_PERSONAL: - strcpy (buffer,"Personal"); - break; - case CSIDL_FAVORITES: - strcpy (buffer,"Favorites"); - break; - case CSIDL_PRINTERS: - strcpy (buffer,"PrintHood"); - break; - case CSIDL_PROGRAMS: - strcpy (buffer,"Programs"); - break; - case CSIDL_RECENT: - strcpy (buffer,"Recent"); - break; - case CSIDL_SENDTO: - strcpy (buffer,"SendTo"); - break; - case CSIDL_STARTMENU: - strcpy (buffer,"Start Menu"); - break; - case CSIDL_STARTUP: - strcpy (buffer,"Startup"); - break; - case CSIDL_TEMPLATES: - strcpy (buffer,"Templates"); - break; - default: - ERR (shell,"unknown CSIDL\n"); - tFolder=FT_UNKNOWN; - break; - } - - TRACE(shell,"Key=%s\n",buffer); - - type=REG_SZ; - - switch (tFolder) - { case FT_DIR: - /* Directory: get the value from the registry, if its not there - create it and the directory*/ - if (RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen)) - { GetWindowsDirectory32A(npath,MAX_PATH); - PathAddBackslash(npath); - switch (nFolder) - { case CSIDL_DESKTOPDIRECTORY: - strcat (npath,"Desktop"); - break; - case CSIDL_FONTS: - strcat (npath,"Fonts"); - break; - case CSIDL_NETHOOD: - strcat (npath,"NetHood"); - break; - case CSIDL_PERSONAL: - strcpy (npath,"C:\\Personal"); - break; - case CSIDL_FAVORITES: - strcat (npath,"Favorites"); - break; - case CSIDL_PRINTERS: - strcat (npath,"PrintHood"); - break; - case CSIDL_PROGRAMS: - strcat (npath,"Start Menu"); - CreateDirectory32A(npath,NULL); - strcat (npath,"\\Programs"); - break; - case CSIDL_RECENT: - strcat (npath,"Recent"); - break; - case CSIDL_SENDTO: - strcat (npath,"SendTo"); - break; - case CSIDL_STARTMENU: - strcat (npath,"Start Menu"); - break; - case CSIDL_STARTUP: - strcat (npath,"Start Menu"); - CreateDirectory32A(npath,NULL); - strcat (npath,"\\Startup"); - break; - case CSIDL_TEMPLATES: - strcat (npath,"Templates"); - break; - default: - RegCloseKey(key); - return E_OUTOFMEMORY; - } - if (RegSetValueEx32A(key,buffer,0,REG_SZ,npath,sizeof(npath)+1)) - { ERR(shell,"could not create value %s\n",buffer); - RegCloseKey(key); - return E_OUTOFMEMORY; - } - TRACE(shell,"value %s=%s created\n",buffer,npath); - CreateDirectory32A(npath,NULL); - } - break; - case FT_DESKTOP: - strcpy (tpath,"Desktop"); - break; - default: - RegCloseKey(key); - return E_OUTOFMEMORY; - break; - } - - RegCloseKey(key); - - TRACE(shell,"Value=%s\n",tpath); - LocalToWideChar32(lpszDisplayName, tpath, 256); - - if (SHGetDesktopFolder(&shellfolder)==S_OK) - { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL); - shellfolder->lpvtbl->fnRelease(shellfolder); - } - - TRACE(shell, "-- (new pidl %p)\n",*ppidl); - return NOERROR; -} - -/************************************************************************* - * SHGetPathFromIDList32A [SHELL32.261][NT 4.0: SHELL32.220] - * - * PARAMETERS - * pidl, [IN] pidl - * pszPath [OUT] path - * - * RETURNS - * path from a passed PIDL. - * - * NOTES - * exported by name - * - * FIXME - * fnGetDisplayNameOf can return different types of OLEString - */ -DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath) -{ STRRET lpName; - LPSHELLFOLDER shellfolder; - CHAR buffer[MAX_PATH],tpath[MAX_PATH]; - DWORD type,tpathlen=MAX_PATH,dwdisp; - HKEY key; - - TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath); - - if (!pidl) - { strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\"); - - if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp)) - { return E_OUTOFMEMORY; - } - type=REG_SZ; - strcpy (buffer,"Desktop"); /*registry name*/ - if ( RegQueryValueEx32A(key,buffer,NULL,&type,tpath,&tpathlen)) - { GetWindowsDirectory32A(tpath,MAX_PATH); - PathAddBackslash(tpath); - strcat (tpath,"Desktop"); /*folder name*/ - RegSetValueEx32A(key,buffer,0,REG_SZ,tpath,tpathlen); - CreateDirectory32A(tpath,NULL); - } - RegCloseKey(key); - strcpy(pszPath,tpath); - } - else - { if (SHGetDesktopFolder(&shellfolder)==S_OK) - { shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName); - shellfolder->lpvtbl->fnRelease(shellfolder); - } - /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/ - strcpy(pszPath,lpName.u.cStr); - /* fixme free the olestring*/ - } - TRACE(shell,"-- (%s)\n",pszPath); - return NOERROR; -} -/************************************************************************* - * SHGetPathFromIDList32W [SHELL32.262] - */ -DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath) -{ FIXME (shell,"(pidl=%p %s):stub.\n", pidl, debugstr_w(pszPath)); - return 0; -} - -/************************************************************************* - * SHGetPathFromIDList [SHELL32.221][NT 4.0: SHELL32.219] - */ -BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath) -{ TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath); - return SHGetPathFromIDList32A(pidl,pszPath); -} - -/************************************************************************* - * SHHelpShortcuts_RunDLL [SHELL32.224] - * - */ -DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4) -{ FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n", - dwArg1, dwArg2, dwArg3, dwArg4); - - return 0; -} - -/************************************************************************* - * SHLoadInProc [SHELL32.225] - * - */ - -DWORD WINAPI SHLoadInProc (DWORD dwArg1) -{ FIXME (shell, "(%lx) empty stub!\n", dwArg1); - return 0; -} - -/************************************************************************* - * SHBrowseForFolderA [SHELL32.209] - * - */ -LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi) -{ FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle); - return NULL; -} - -/************************************************************************* - * SHELL32 LibMain - * - * FIXME - * at the moment the icons are extracted from shell32.dll - */ -HINSTANCE32 shell32_hInstance; - -BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ HICON32 htmpIcon; - UINT32 iiconindex; - UINT32 index; - CHAR szShellPath[MAX_PATH]; - - TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved); - - shell32_hInstance = hinstDLL; - - GetWindowsDirectory32A(szShellPath,MAX_PATH); - PathAddBackslash(szShellPath); - strcat(szShellPath,"system\\shell32.dll"); - - if (fdwReason==DLL_PROCESS_ATTACH) - { if ( ! ShellSmallIconList ) - { if ( (ShellSmallIconList = ImageList_Create(16,16,ILC_COLOR,64,16)) ) - { for (index=0;index < 40; index++) - { if ( ( htmpIcon = ExtractIcon32A(hinstDLL, szShellPath, index)) ) - { iiconindex = ImageList_AddIcon (ShellSmallIconList, htmpIcon); - } - else - { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n"); - break; - } - } - } - } - if ( ! ShellBigIconList ) - { if ( (ShellBigIconList = ImageList_Create(32,32,ILC_COLOR,64,16)) ) - { for (index=0;index < 40; index++) - { if ( (htmpIcon = ExtractIcon32A( hinstDLL, szShellPath, index)) ) - { iiconindex = ImageList_AddIcon (ShellBigIconList, htmpIcon); - } - else - { ERR(shell,"could not initialize iconlist (is shell32.dll in the system directory?)\n"); - break; - } - } - } - } - } - return TRUE; -} diff --git a/msdos/dosmem.c b/msdos/dosmem.c index d0bfddd5a8a..1affb0a84ba 100644 --- a/msdos/dosmem.c +++ b/msdos/dosmem.c @@ -15,7 +15,6 @@ #include "miscemu.h" #include "module.h" #include "task.h" -#include "dosexe.h" #include "debug.h" HANDLE16 DOSMEM_BiosSeg; /* BIOS data segment at 0x40:0 */ @@ -112,13 +111,14 @@ static dosmem_info* info_block = NULL; * * Gets the DOS memory base. */ -static char *DOSMEM_MemoryBase(HMODULE16 hModule) +char *DOSMEM_MemoryBase(HMODULE16 hModule) { TDB *pTask = hModule ? NULL : (TDB *)GlobalLock16( GetCurrentTask() ); NE_MODULE *pModule = (hModule || pTask) ? NE_GetPtr( hModule ? hModule : pTask->hModule ) : NULL; - if (pModule && pModule->lpDosTask) - return pModule->lpDosTask->img; + GlobalUnlock16( GetCurrentTask() ); + if (pModule && pModule->dos_image) + return pModule->dos_image; else return DOSMEM_dosmem; } @@ -431,7 +431,6 @@ LPVOID DOSMEM_ResizeBlock(HMODULE16 hModule, void* ptr, UINT32 size, UINT16* pse UINT32 DOSMEM_Available(HMODULE16 hModule) { UINT32 blocksize, available = 0; - char *block = NULL; dosmem_entry *dm; dm = root_block; diff --git a/msdos/int20.c b/msdos/int20.c index e53813a72f0..f6be7adf1ed 100644 --- a/msdos/int20.c +++ b/msdos/int20.c @@ -15,5 +15,5 @@ */ void WINAPI INT_Int20Handler( CONTEXT *context ) { - TASK_KillCurrentTask( 0 ); + ExitProcess( 0 ); } diff --git a/msdos/int21.c b/msdos/int21.c index 6bb650eda4f..a4e95f1c80a 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -32,14 +32,6 @@ #endif -#define DOS_TO_HANDLE(handle) (((handle)==0) ? GetStdHandle(STD_INPUT_HANDLE) : \ - ((handle)==1) ? GetStdHandle(STD_OUTPUT_HANDLE) : \ - ((handle)==2) ? GetStdHandle(STD_ERROR_HANDLE) : \ - (handle)-5) -#define HANDLE_TO_DOS(handle) ({ WORD hnd=handle; \ - ((hnd==HFILE_ERROR16) ? HFILE_ERROR16 : \ - hnd+5); }) - #define DOS_GET_DRIVE(reg) ((reg) ? (reg) - 1 : DRIVE_GetCurrentDrive()) /* Define the drive parameter block, as used by int21/1F @@ -228,7 +220,7 @@ static void ioctlGetDeviceInfo( CONTEXT *context ) RESET_CFLAG(context); /* DOS device ? */ - if ((file = FILE_GetFile( DOS_TO_HANDLE(BX_reg(context)) ))) + if ((file = FILE_GetFile( HFILE16_TO_HFILE32(BX_reg(context)) ))) { const DOS_DEVICE *dev = DOSFS_GetDevice( file->unix_name ); FILE_ReleaseFile( file ); @@ -364,16 +356,16 @@ char *INT21_DriveName(int drive) } static BOOL32 INT21_CreateFile( CONTEXT *context ) { - AX_reg(context) = HANDLE_TO_DOS(_lcreat16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context), - DX_reg(context) ), CX_reg(context) )); + AX_reg(context) = _lcreat16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context), + DX_reg(context) ), CX_reg(context) ); return (AX_reg(context) == (WORD)HFILE_ERROR16); } static void OpenExistingFile( CONTEXT *context ) { - AX_reg(context) = HANDLE_TO_DOS(_lopen16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)), - AL_reg(context) )); + AX_reg(context) = _lopen16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)), + AL_reg(context) ); if (AX_reg(context) == (WORD)HFILE_ERROR16) { AX_reg(context) = DOS_ExtendedError; @@ -442,7 +434,7 @@ static void OpenExistingFile( CONTEXT *context ) } Error (0,0,0); - AX_reg(context) = HANDLE_TO_DOS(handle); + AX_reg(context) = handle; RESET_CFLAG(context); } #endif @@ -450,7 +442,7 @@ static void OpenExistingFile( CONTEXT *context ) static void CloseFile( CONTEXT *context ) { - if ((AX_reg(context) = _lclose16( DOS_TO_HANDLE(BX_reg(context)) )) != 0) + if ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0) { AX_reg(context) = DOS_ExtendedError; SET_CFLAG(context); @@ -666,7 +658,7 @@ static BOOL32 INT21_CreateTempFile( CONTEXT *context ) sprintf( p, "wine%04x.%03d", (int)getpid(), counter ); counter = (counter + 1) % 1000; - if ((AX_reg(context) = HANDLE_TO_DOS(_lcreat_uniq( name, 0 ))) != (WORD)HFILE_ERROR16) + if ((AX_reg(context) = HFILE32_TO_HFILE16(_lcreat_uniq( name, 0 ))) != (WORD)HFILE_ERROR16) { TRACE(int21, "created %s\n", name ); return TRUE; @@ -844,7 +836,7 @@ static void fLock( CONTEXT * context ) BX_reg(context), MAKELONG(DX_reg(context),CX_reg(context)), MAKELONG(DI_reg(context),SI_reg(context))) ; - if (!LockFile(DOS_TO_HANDLE(BX_reg(context)), + if (!LockFile(HFILE16_TO_HFILE32(BX_reg(context)), MAKELONG(DX_reg(context),CX_reg(context)), 0, MAKELONG(DI_reg(context),SI_reg(context)), 0)) { AX_reg(context) = DOS_ExtendedError; @@ -857,7 +849,7 @@ static void fLock( CONTEXT * context ) BX_reg(context), MAKELONG(DX_reg(context),CX_reg(context)), MAKELONG(DI_reg(context),SI_reg(context))) ; - if (!UnlockFile(DOS_TO_HANDLE(BX_reg(context)), + if (!UnlockFile(HFILE16_TO_HFILE32(BX_reg(context)), MAKELONG(DX_reg(context),CX_reg(context)), 0, MAKELONG(DI_reg(context),SI_reg(context)), 0)) { AX_reg(context) = DOS_ExtendedError; @@ -902,6 +894,20 @@ INT21_networkfunc (CONTEXT *context) } } +static WORD INT21_GetCurrentPSP() +{ +#ifdef MZ_SUPPORTED + TDB *pTask = hModule ? NULL : (TDB *)GlobalLock16( GetCurrentTask() ); + NE_MODULE *pModule = (hModule || pTask) ? NE_GetPtr( hModule ? hModule : pTask->hModule ) : NULL; + + GlobalUnlock16( GetCurrentTask() ); + if (pModule->lpDosTask) + return pModule->lpDosTask->psp_seg; + else +#endif + return GetCurrentPDB(); +} + SEGPTR INT21_GetListOfLists() { @@ -1001,16 +1007,13 @@ void WINAPI DOS3Call( CONTEXT *context ) { case 0x00: /* TERMINATE PROGRAM */ TRACE(int21,"TERMINATE PROGRAM\n"); - TASK_KillCurrentTask( 0 ); + ExitProcess( 0 ); break; case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */ - case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */ case 0x03: /* READ CHARACTER FROM STDAUX */ case 0x04: /* WRITE CHARACTER TO STDAUX */ case 0x05: /* WRITE CHARACTER TO PRINTER */ - case 0x06: /* DIRECT CONSOLE IN/OUTPUT */ - case 0x0a: /* BUFFERED INPUT */ case 0x0b: /* GET STDIN STATUS */ case 0x0f: /* OPEN FILE USING FCB */ case 0x10: /* CLOSE FILE USING FCB */ @@ -1025,21 +1028,23 @@ void WINAPI DOS3Call( CONTEXT *context ) case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */ case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */ case 0x29: /* PARSE FILENAME INTO FCB */ - case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER - "SWITCHAR" - SET SWITCH CHARACTER - "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */ case 0x54: /* GET VERIFY FLAG */ INT_BARF( context, 0x21 ); break; + case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */ + case 0x06: /* DIRECT CONSOLE IN/OUTPUT */ + _lwrite16( 1, &DL_reg(context), 1); + break; + case 0x07: /* DIRECT CHARACTER INPUT WITHOUT ECHO */ TRACE(int21,"DIRECT CHARACTER INPUT WITHOUT ECHO\n"); - _lread16( DOS_TO_HANDLE(0), &AL_reg(context), 1); + _lread16( 0, &AL_reg(context), 1); break; case 0x08: /* CHARACTER INPUT WITHOUT ECHO */ TRACE(int21,"CHARACTER INPUT WITHOUT ECHO\n"); - _lread16( DOS_TO_HANDLE(0), &AL_reg(context), 1); + _lread16( 0, &AL_reg(context), 1); break; case 0x09: /* WRITE STRING TO STANDARD OUTPUT */ @@ -1048,10 +1053,26 @@ void WINAPI DOS3Call( CONTEXT *context ) { LPSTR data = CTX_SEG_OFF_TO_LIN(context,DS_reg(context),DX_reg(context)); LONG length = strchr(data,'$')-data; - _hwrite16( DOS_TO_HANDLE(1), data, length); + _hwrite16( 1, data, length); } break; + case 0x0a: /* BUFFERED INPUT */ + { + char *buffer = ((char *)CTX_SEG_OFF_TO_LIN(context, DS_reg(context), + DX_reg(context) )); + int res; + + TRACE(int21,"BUFFERED INPUT\n"); + if (buffer[1]) + TRACE(int21,"Handle old chars in buffer!\n"); + res=_lread16( 0, buffer+2,buffer[0]); + buffer[1]=res; + if(buffer[res+1] == '\n') + buffer[res+1] = '\r'; + break; + } + case 0x2e: /* SET VERIFY FLAG */ TRACE(int21,"SET VERIFY FLAG ignored\n"); /* we cannot change the behaviour anyway, so just ignore it */ @@ -1241,6 +1262,28 @@ void WINAPI DOS3Call( CONTEXT *context ) if (!INT21_GetFreeDiskSpace(context)) AX_reg(context) = 0xffff; break; + case 0x37: + { + unsigned char switchchar='/'; + switch (AL_reg(context)) + { + case 0x00: /* "SWITCHAR" - GET SWITCH CHARACTER */ + TRACE(int21,"SWITCHAR - GET SWITCH CHARACTER\n"); + AL_reg(context) = 0x00; /* success*/ + DL_reg(context) = switchchar; + break; + case 0x01: /*"SWITCHAR" - SET SWITCH CHARACTER*/ + TRACE(int21,"SWITCHAR - SET SWITCH CHARACTER\n"); + switchchar = DL_reg(context); + AL_reg(context) = 0x00; /* success*/ + break; + default: /*"AVAILDEV" - SPECIFY \DEV\ PREFIX USE*/ + INT_BARF( context, 0x21 ); + break; + } + break; + } + case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ TRACE(int21,"GET COUNTRY-SPECIFIC INFORMATION for country 0x%02x\n", AL_reg(context)); @@ -1271,8 +1314,8 @@ void WINAPI DOS3Call( CONTEXT *context ) case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */ TRACE(int21,"CREAT flag 0x%02x %s\n",CX_reg(context), (LPCSTR)CTX_SEG_OFF_TO_LIN(context, DS_reg(context), DX_reg(context))); - AX_reg(context) = HANDLE_TO_DOS(_lcreat16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context), - DX_reg(context) ), CX_reg(context) )); + AX_reg(context) = _lcreat16( CTX_SEG_OFF_TO_LIN(context, DS_reg(context), + DX_reg(context) ), CX_reg(context) ); bSetDOSExtendedError = (AX_reg(context) == (WORD)HFILE_ERROR16); break; @@ -1289,14 +1332,14 @@ void WINAPI DOS3Call( CONTEXT *context ) DOS_ExtendedError = 0x06; bSetDOSExtendedError = TRUE; } else - bSetDOSExtendedError = ((AX_reg(context) = _lclose16( DOS_TO_HANDLE(BX_reg(context)) )) != 0); + bSetDOSExtendedError = ((AX_reg(context) = _lclose16( BX_reg(context) )) != 0); break; case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */ TRACE(int21,"READ from %d to %04lX:%04X for %d byte\n",BX_reg(context), DS_reg(context),DX_reg(context),CX_reg(context) ); { - LONG result = _hread16( DOS_TO_HANDLE(BX_reg(context)), + LONG result = _hread16( BX_reg(context), CTX_SEG_OFF_TO_LIN(context, DS_reg(context), DX_reg(context) ), CX_reg(context) ); @@ -1309,7 +1352,7 @@ void WINAPI DOS3Call( CONTEXT *context ) TRACE(int21,"WRITE from %04lX:%04X to handle %d for %d byte\n", DS_reg(context),DX_reg(context),BX_reg(context),CX_reg(context) ); { - LONG result = _hwrite16( DOS_TO_HANDLE(BX_reg(context)), + LONG result = _hwrite16( BX_reg(context), CTX_SEG_OFF_TO_LIN(context, DS_reg(context), DX_reg(context) ), CX_reg(context) ); @@ -1331,7 +1374,7 @@ void WINAPI DOS3Call( CONTEXT *context ) (AL_reg(context)==0)?"start of file":(AL_reg(context)==1)? "current file position":"end of file"); { - LONG status = _llseek16( DOS_TO_HANDLE(BX_reg(context)), + LONG status = _llseek16( BX_reg(context), MAKELONG(DX_reg(context),CX_reg(context)), AL_reg(context) ); if (status == -1) bSetDOSExtendedError = TRUE; @@ -1381,7 +1424,7 @@ void WINAPI DOS3Call( CONTEXT *context ) break; case 0x02:{ FILE_OBJECT *file; - file = FILE_GetFile(DOS_TO_HANDLE(BX_reg(context))); + file = FILE_GetFile(HFILE16_TO_HFILE32(BX_reg(context))); if (!strcasecmp(file->unix_name, "SCSIMGR$")) ASPI_DOS_HandleInt(context); FILE_ReleaseFile( file ); @@ -1493,13 +1536,13 @@ void WINAPI DOS3Call( CONTEXT *context ) case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */ TRACE(int21,"DUP - DUPLICATE FILE HANDLE %d\n",BX_reg(context)); - bSetDOSExtendedError = ((AX_reg(context) = HANDLE_TO_DOS(FILE_Dup(DOS_TO_HANDLE(BX_reg(context))))) == (WORD)HFILE_ERROR16); + bSetDOSExtendedError = ((AX_reg(context) = HFILE32_TO_HFILE16(FILE_Dup(HFILE16_TO_HFILE32(BX_reg(context))))) == (WORD)HFILE_ERROR16); break; case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ TRACE(int21,"FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n", BX_reg(context),CX_reg(context)); - bSetDOSExtendedError = (FILE_Dup2( DOS_TO_HANDLE(BX_reg(context)), DOS_TO_HANDLE(CX_reg(context)) ) == HFILE_ERROR32); + bSetDOSExtendedError = (FILE_Dup2( HFILE16_TO_HFILE32(BX_reg(context)), HFILE16_TO_HFILE32(CX_reg(context)) ) == HFILE_ERROR32); break; case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ @@ -1557,7 +1600,7 @@ void WINAPI DOS3Call( CONTEXT *context ) case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */ TRACE(int21,"EXIT with return code %d\n",AL_reg(context)); - TASK_KillCurrentTask( AL_reg(context) ); + ExitProcess( AL_reg(context) ); break; case 0x4d: /* GET RETURN CODE */ @@ -1586,13 +1629,13 @@ void WINAPI DOS3Call( CONTEXT *context ) TRACE(int21,"GET CURRENT PROCESS ID (GET PSP ADDRESS)\n"); /* FIXME: should we return the original DOS PSP upon */ /* Windows startup ? */ - BX_reg(context) = GetCurrentPDB(); + BX_reg(context) = INT21_GetCurrentPSP(); break; case 0x62: /* GET PSP ADDRESS */ TRACE(int21,"GET CURRENT PSP ADDRESS\n"); /* FIXME: should we return the original DOS PSP upon */ /* Windows startup ? */ - BX_reg(context) = GetCurrentPDB(); + BX_reg(context) = INT21_GetCurrentPSP(); break; case 0x52: /* "SYSVARS" - GET LIST OF LISTS */ @@ -1670,7 +1713,7 @@ void WINAPI DOS3Call( CONTEXT *context ) TRACE(int21,"CREATE NEW FILE 0x%02x for %s\n", CX_reg(context), (LPCSTR)CTX_SEG_OFF_TO_LIN(context, DS_reg(context), DX_reg(context))); bSetDOSExtendedError = ((AX_reg(context) = - HANDLE_TO_DOS(_lcreat_uniq( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)), 0 ))) + HFILE32_TO_HFILE16(_lcreat_uniq( CTX_SEG_OFF_TO_LIN(context, DS_reg(context),DX_reg(context)), 0 ))) == (WORD)HFILE_ERROR16); break; @@ -1789,7 +1832,7 @@ void WINAPI DOS3Call( CONTEXT *context ) case 0x68: /* "FFLUSH" - COMMIT FILE */ case 0x6a: /* COMMIT FILE */ TRACE(int21,"FFLUSH/COMMIT handle %d\n",BX_reg(context)); - bSetDOSExtendedError = (!FlushFileBuffers( DOS_TO_HANDLE(BX_reg(context)) )); + bSetDOSExtendedError = (!FlushFileBuffers( HFILE16_TO_HFILE32(BX_reg(context)) )); break; case 0x69: /* DISK SERIAL NUMBER */ diff --git a/msdos/vxd.c b/msdos/vxd.c index 3f08ac8e307..caac7a33daf 100644 --- a/msdos/vxd.c +++ b/msdos/vxd.c @@ -806,7 +806,7 @@ void VXD_Win32s( CONTEXT *context ) LARGE_INTEGER *size = (LARGE_INTEGER *)AppToWine(stack[3]); DWORD protect = stack[4]; DWORD flags2 = stack[5]; - HFILE32 hFile = stack[6]; + HFILE32 hFile = HFILE16_TO_HFILE32(stack[6]); DWORD psp = stack[7]; HANDLE32 result = INVALID_HANDLE_VALUE32; diff --git a/multimedia/dsound.c b/multimedia/dsound.c index d3adc762ce8..654206fe361 100644 --- a/multimedia/dsound.c +++ b/multimedia/dsound.c @@ -242,6 +242,7 @@ static DWORD WINAPI IDirectSoundBuffer_Release(LPDIRECTSOUNDBUFFER this) { this->dsound->nrofbuffers--; this->dsound->lpvtbl->fnRelease(this->dsound); } + HeapFree(GetProcessHeap(),0,this->buffer); HeapFree(GetProcessHeap(),0,this); return 0; } @@ -784,7 +785,7 @@ DSOUND_MixInBuffer(IDirectSoundBuffer *dsb) { /* unsigned char *xbuf = (unsigned char*)(dsb->buffer); */ char *xbuf = dsb->buffer; if (dsb->wfx.nChannels == 1) { - printf("Mixing 8-bit stereo into 16!!\n"); + WARN(dsound,"Mixing 8-bit stereo into 16!!\n"); for (j=0;jplaypos=(dsb->playpos+1)%buflen; if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) { diff --git a/multimedia/mmio.c b/multimedia/mmio.c index f6bdc77026f..8443ca14b7e 100644 --- a/multimedia/mmio.c +++ b/multimedia/mmio.c @@ -32,7 +32,7 @@ static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lP case MMIOM_OPEN: { /* Parameters: * lParam1 = szFileName parameter from mmioOpen - * lParam2 = unused + * lParam2 = reserved (we use it for 16-bitness) * Returns: zero on success, error code on error * NOTE: lDiskOffset automatically set to zero */ @@ -46,8 +46,11 @@ static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lP } /* if filename NULL, assume open file handle in adwInfo[0] */ - if (!szFileName) + if (!szFileName) { + if (lParam2) lpmmioinfo->adwInfo[0] = + HFILE16_TO_HFILE32(lpmmioinfo->adwInfo[0]); return 0; + } lpmmioinfo->adwInfo[0] = (DWORD) OpenFile32(szFileName, &ofs, lpmmioinfo->dwFlags); @@ -110,7 +113,7 @@ static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lP LONG cch = (LONG) lParam2; LONG count; - count = _hwrite16((HFILE32)lpmmioinfo->adwInfo[0], pch, cch); + count = _hwrite32((HFILE32)lpmmioinfo->adwInfo[0], pch, cch); if (count != -1) lpmmioinfo->lDiskOffset += count; @@ -159,37 +162,97 @@ static LRESULT mmioDosIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lP * mmioMemIOProc [internal] */ static LRESULT mmioMemIOProc(LPMMIOINFO16 lpmmioinfo, UINT16 uMessage, LPARAM lParam1, LPARAM lParam2) { - FIXME(mmio,"(%p,0x%04x,0x%08lx,0x%08lx), stub!\n",lpmmioinfo,uMessage,lParam1,lParam2); + TRACE(mmio,"(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo,uMessage,lParam1,lParam2); + switch (uMessage) { + + case MMIOM_OPEN: { + /* Parameters: + * lParam1 = filename (must be NULL) + * lParam2 = reserved (we use it for 16-bitness) + * Returns: zero on success, error code on error + * NOTE: lDiskOffset automatically set to zero + */ + + if (!(lpmmioinfo->dwFlags & MMIO_CREATE)) + lpmmioinfo->pchEndRead = lpmmioinfo->pchEndWrite; + + return 0; + } + + case MMIOM_CLOSE: { + /* Parameters: + * lParam1 = wFlags parameter from mmioClose + * lParam2 = unused + * Returns: zero on success, error code on error + */ + + return 0; + + } + + case MMIOM_READ: { + /* Parameters: + * lParam1 = huge pointer to read buffer + * lParam2 = number of bytes to read + * Returns: number of bytes read, 0 for EOF, -1 for error (error code + * in wErrorRet) + * NOTE: lDiskOffset should be updated + */ + + HPSTR pch = (HPSTR) lParam1; + LONG cch = (LONG) lParam2; + + FIXME(mmio,"MMIOM_READ on memory files should not occur, buffer may be lost!\n"); + return 0; + } + + case MMIOM_WRITE: + case MMIOM_WRITEFLUSH: { + /* no internal buffering, so WRITEFLUSH handled same as WRITE */ + + /* Parameters: + * lParam1 = huge pointer to write buffer + * lParam2 = number of bytes to write + * Returns: number of bytes written, -1 for error (error code in + * wErrorRet) + * NOTE: lDiskOffset should be updated + */ + + HPSTR pch = (HPSTR) lParam1; + LONG cch = (LONG) lParam2; + + FIXME(mmio,"MMIOM_WRITE on memory files should not occur, buffer may be lost!\n"); + return 0; + } + + case MMIOM_SEEK: { + /* Parameters: + * lParam1 = new position + * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END) + * Returns: new file postion, -1 on error + * NOTE: lDiskOffset should be updated + */ + + LONG Offset = (LONG) lParam1; + LONG Whence = (LONG) lParam2; + + FIXME(mmio,"MMIOM_SEEK on memory files should not occur, buffer may be lost!\n"); + return -1; + } + + default: + FIXME(mmio, "unexpected message %u\n", uMessage); + return 0; + } + return 0; } /************************************************************************** - * mmioOpenW [WINMM.123] + * MMIO_Open [internal] */ -HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo, - DWORD dwOpenFlags) -{ - LPSTR szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName); - HMMIO32 ret = mmioOpen16(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags); - - HeapFree(GetProcessHeap(),0,szFn); - return ret; -} - -/************************************************************************** - * mmioOpenA [WINMM.122] - */ -HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo, - DWORD dwOpenFlags) -{ - return mmioOpen16(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags); -} - -/************************************************************************** - * mmioOpen [MMSYSTEM.1210] - */ -HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, - DWORD dwOpenFlags) +static HMMIO16 MMIO_Open(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, + DWORD dwOpenFlags, int use16) { LPMMIOINFO16 lpmminfo; HMMIO16 hmmio; @@ -207,7 +270,7 @@ HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, if (!lpmmioinfo || (lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL)) { - lpmminfo->fccIOProc = mmioFOURCC('D', 'O', 'S', ' '); + lpmminfo->fccIOProc = FOURCC_DOS; lpmminfo->pIOProc = (LPMMIOPROC16) mmioDosIOProc; } /* if just the four character code is present, look up IO proc */ @@ -230,13 +293,20 @@ HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, lpmmioinfo->wErrorRet = result; return 0; } + } else + if (lpmminfo->fccIOProc == FOURCC_MEM) { + if ((result = mmioSetBuffer(hmmio, lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer, 0))) { + if (lpmmioinfo) + lpmmioinfo->wErrorRet = result; + return 0; + } } lpmminfo->dwFlags = dwOpenFlags; lpmminfo->hmmio = hmmio; /* call IO proc to actually open file */ - result = (UINT16) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) 0); + result = (UINT16) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) use16); GlobalUnlock16(hmmio); @@ -248,6 +318,37 @@ HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, return hmmio; } +/************************************************************************** + * mmioOpenW [WINMM.123] + */ +HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo, + DWORD dwOpenFlags) +{ + LPSTR szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName); + HMMIO32 ret = MMIO_Open(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,FALSE); + + HeapFree(GetProcessHeap(),0,szFn); + return ret; +} + +/************************************************************************** + * mmioOpenA [WINMM.122] + */ +HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo, + DWORD dwOpenFlags) +{ + return MMIO_Open(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,FALSE); +} + +/************************************************************************** + * mmioOpen [MMSYSTEM.1210] + */ +HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo, + DWORD dwOpenFlags) +{ + return MMIO_Open(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags,TRUE); +} + /************************************************************************** * mmioClose [WINMM.114] @@ -304,7 +405,7 @@ LONG WINAPI mmioRead32(HMMIO32 hmmio, HPSTR pch, LONG cch) if (lpmminfo->pchNext != lpmminfo->pchEndRead) { count = lpmminfo->pchEndRead - lpmminfo->pchNext; - if (count > cch) count = cch; + if (count > cch || count < 0) count = cch; memcpy(pch, lpmminfo->pchNext, count); lpmminfo->pchNext += count; pch += count; @@ -312,15 +413,19 @@ LONG WINAPI mmioRead32(HMMIO32 hmmio, HPSTR pch, LONG cch) } else count = 0; - if (cch) { + if (cch&&(lpmminfo->fccIOProc!=FOURCC_MEM)) { if (lpmminfo->cchBuffer) { mmioFlush32(hmmio, MMIO_EMPTYBUF); while (cch) { - LONG size = mmioSendMessage(hmmio, MMIOM_READ, + LONG size; + lpmminfo->lBufOffset = lpmminfo->lDiskOffset; + lpmminfo->pchNext = lpmminfo->pchBuffer; + lpmminfo->pchEndRead = lpmminfo->pchBuffer; + size = mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) lpmminfo->pchBuffer, (LPARAM) lpmminfo->cchBuffer); - lpmminfo->pchNext = lpmminfo->pchBuffer; + if (size<=0) break; lpmminfo->pchEndRead = lpmminfo->pchBuffer + size; if (size > cch) size = cch; memcpy(pch, lpmminfo->pchNext, size); @@ -331,6 +436,7 @@ LONG WINAPI mmioRead32(HMMIO32 hmmio, HPSTR pch, LONG cch) } } else { count += mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) pch, (LPARAM) cch); + if (count>0) lpmminfo->lBufOffset += count; } } @@ -366,12 +472,18 @@ LONG WINAPI mmioWrite32(HMMIO32 hmmio, HPCSTR pch, LONG cch) while (cch) { if (lpmminfo->pchNext != lpmminfo->pchEndWrite) { count = lpmminfo->pchEndWrite - lpmminfo->pchNext; - if (count > cch) count = cch; + if (count > cch || count < 0) count = cch; memcpy(lpmminfo->pchNext, pch, count); lpmminfo->pchNext += count; pch += count; cch -= count; lpmminfo->dwFlags |= MMIO_DIRTY; + } else + if (lpmminfo->fccIOProc==FOURCC_MEM) { + if (lpmminfo->adwInfo[0]) { + /* from where would we get the memory handle? */ + FIXME(mmio, "memory file expansion not implemented!\n"); + } else break; } if (lpmminfo->pchNext == lpmminfo->pchEndWrite @@ -379,6 +491,7 @@ LONG WINAPI mmioWrite32(HMMIO32 hmmio, HPCSTR pch, LONG cch) } } else { count = mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) pch, (LPARAM) cch); + lpmminfo->lBufOffset = lpmminfo->lDiskOffset; } GlobalUnlock16(hmmio); @@ -404,14 +517,28 @@ LONG WINAPI mmioSeek32(HMMIO32 hmmio, LONG lOffset, INT32 iOrigin) TRACE(mmio, "(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin); - if (mmioFlush32(hmmio, MMIO_EMPTYBUF)) - return -1; - lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio); if (lpmminfo == NULL) - return 0; + return -1; + + offset = (iOrigin==SEEK_SET)?(lOffset - lpmminfo->lBufOffset): + (iOrigin==SEEK_CUR)?(lOffset + + (lpmminfo->pchNext - lpmminfo->pchBuffer)):-1; + + if ((lpmminfo->cchBuffer<0)|| + ((offset>=0)&&(offset<=(lpmminfo->pchEndRead-lpmminfo->pchBuffer)))) { + lpmminfo->pchNext = lpmminfo->pchBuffer + offset; + GlobalUnlock16(hmmio); + return lpmminfo->lBufOffset + offset; + } + + if ((lpmminfo->fccIOProc==FOURCC_MEM)||mmioFlush32(hmmio, MMIO_EMPTYBUF)) { + GlobalUnlock16(hmmio); + return -1; + } offset = mmioSendMessage(hmmio, MMIOM_SEEK, (LPARAM) lOffset, (LPARAM) iOrigin); + lpmminfo->lBufOffset = lpmminfo->lDiskOffset; GlobalUnlock16(hmmio); return offset; @@ -554,24 +681,30 @@ UINT32 WINAPI mmioFlush32(HMMIO32 hmmio, UINT32 uFlags) lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio); if (lpmminfo == NULL) return 0; + if ((!lpmminfo->cchBuffer)||(lpmminfo->fccIOProc==FOURCC_MEM)) { + GlobalUnlock16(hmmio); + return 0; + } /* not quite sure what to do here, but I'll guess */ - if (lpmminfo->dwFlags&MMIO_DIRTY) { - if (lpmminfo->pchNext != (lpmminfo->pchBuffer + lpmminfo->lBufOffset)) { - if (lpmminfo->dwFlags&MMIO_READWRITE) - mmioSendMessage(hmmio, MMIOM_SEEK, - (LPARAM) (lpmminfo->pchBuffer - lpmminfo->pchEndRead) + lpmminfo->lBufOffset, - (LPARAM) SEEK_CUR ); - mmioSendMessage(hmmio, MMIOM_WRITE, - (LPARAM) lpmminfo->pchBuffer + lpmminfo->lBufOffset, - (LPARAM) (lpmminfo->pchNext - lpmminfo->pchBuffer) - lpmminfo->lBufOffset ); - } - lpmminfo->lBufOffset = lpmminfo->pchNext - lpmminfo->pchBuffer; + if (lpmminfo->dwFlags & MMIO_DIRTY) { + mmioSendMessage(hmmio, MMIOM_SEEK, + (LPARAM) lpmminfo->lBufOffset, + (LPARAM) SEEK_SET); + mmioSendMessage(hmmio, MMIOM_WRITE, + (LPARAM) lpmminfo->pchBuffer, + (LPARAM) (lpmminfo->pchNext - lpmminfo->pchBuffer) ); lpmminfo->dwFlags &= ~MMIO_DIRTY; } if (uFlags & MMIO_EMPTYBUF) { + /* seems Windows doesn't do any seeking here, hopefully this + won't matter, otherwise a slight rewrite is necessary */ + mmioSendMessage(hmmio, MMIOM_SEEK, + (LPARAM) (lpmminfo->lBufOffset + + (lpmminfo->pchNext - lpmminfo->pchBuffer)), + (LPARAM) SEEK_SET); lpmminfo->pchNext = lpmminfo->pchBuffer; lpmminfo->pchEndRead = lpmminfo->pchBuffer; - lpmminfo->lBufOffset = 0; + lpmminfo->lBufOffset = lpmminfo->lDiskOffset; } GlobalUnlock16(hmmio); @@ -595,15 +728,26 @@ UINT32 WINAPI mmioAdvance32(HMMIO32 hmmio,MMIOINFO32*lpmmioinfo,UINT32 uFlags) TRACE(mmio, "mmioAdvance\n"); lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio); if (lpmminfo == NULL) return 0; + if (!lpmminfo->cchBuffer) { + GlobalUnlock16(hmmio); + return MMIOERR_UNBUFFERED; + } + lpmminfo->pchNext = lpmmioinfo->pchNext; + if (mmioFlush32(hmmio, MMIO_EMPTYBUF)) { + GlobalUnlock16(hmmio); + return MMIOERR_CANNOTWRITE; + } if (uFlags == MMIO_READ) lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer + mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) lpmmioinfo->pchBuffer, (LPARAM) lpmmioinfo->cchBuffer); +#if 0 /* mmioFlush32 already did the writing */ if (uFlags == MMIO_WRITE) mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) lpmmioinfo->pchBuffer, (LPARAM) lpmmioinfo->cchBuffer); +#endif lpmmioinfo->pchNext = lpmmioinfo->pchBuffer; GlobalUnlock16(hmmio); return 0; @@ -618,15 +762,26 @@ UINT16 WINAPI mmioAdvance16(HMMIO16 hmmio,MMIOINFO16*lpmmioinfo,UINT16 uFlags) TRACE(mmio, "mmioAdvance\n"); lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio); if (lpmminfo == NULL) return 0; + if (!lpmminfo->cchBuffer) { + GlobalUnlock16(hmmio); + return MMIOERR_UNBUFFERED; + } + lpmminfo->pchNext = lpmmioinfo->pchNext; + if (mmioFlush32(hmmio, MMIO_EMPTYBUF)) { + GlobalUnlock16(hmmio); + return MMIOERR_CANNOTWRITE; + } if (uFlags == MMIO_READ) lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer + mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) lpmmioinfo->pchBuffer, (LPARAM) lpmmioinfo->cchBuffer); +#if 0 /* mmioFlush32 already did the writing */ if (uFlags == MMIO_WRITE) mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) lpmmioinfo->pchBuffer, (LPARAM) lpmmioinfo->cchBuffer); +#endif lpmmioinfo->pchNext = lpmmioinfo->pchBuffer; GlobalUnlock16(hmmio); return 0; @@ -786,10 +941,17 @@ UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck, while (TRUE) { LONG ix; - ix = mmioRead32(hmmio, (LPSTR)lpck, sizeof(MMCKINFO)); - TRACE(mmio, "after _lread32 ix = %ld req = %d, errno = %d\n",ix,sizeof(MMCKINFO),errno); - if (ix < sizeof(MMCKINFO)) { - + ix = mmioRead32(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)); + TRACE(mmio, "after _lread32 ix = %ld req = %d, errno = %d\n",ix,3 * sizeof(DWORD),errno); + if (ix < sizeof(DWORD)) { + mmioSeek32(hmmio, dwOldPos, SEEK_SET); + WARN(mmio, "return ChunkNotFound\n"); + return MMIOERR_CHUNKNOTFOUND; + } + lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); + if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) + lpck->dwDataOffset += sizeof(DWORD); + if (ix < lpck->dwDataOffset - dwOldPos) { mmioSeek32(hmmio, dwOldPos, SEEK_SET); WARN(mmio, "return ChunkNotFound\n"); return MMIOERR_CHUNKNOTFOUND; @@ -799,9 +961,7 @@ UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck, if (dwfcc == lpck->ckid) break; - dwOldPos += lpck->cksize + 2 * sizeof(DWORD); - if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) - dwOldPos += sizeof(DWORD); + dwOldPos = lpck->dwDataOffset + lpck->cksize; mmioSeek32(hmmio, dwOldPos, SEEK_SET); } } @@ -811,10 +971,10 @@ UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck, WARN(mmio, "return ChunkNotFound 2nd\n"); return MMIOERR_CHUNKNOTFOUND; } + lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); + if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) + lpck->dwDataOffset += sizeof(DWORD); } - lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); - if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) - lpck->dwDataOffset += sizeof(DWORD); mmioSeek32(hmmio, lpck->dwDataOffset, SEEK_SET); TRACE(mmio, "lpck->ckid=%08lX lpck->cksize=%ld !\n", @@ -833,7 +993,8 @@ UINT32 WINAPI mmioAscend32(HMMIO32 hmmio, MMCKINFO * lpck, UINT32 uFlags) hmmio, lpck, uFlags); if (lpck->dwFlags&MMIO_DIRTY) { DWORD dwOldPos, dwNewSize, dwSizePos; - + + TRACE(mmio, "chunk is marked MMIO_DIRTY, correcting chunk size\n"); dwOldPos = mmioSeek32(hmmio, 0, SEEK_CUR); TRACE(mmio, "dwOldPos=%ld\n", dwOldPos); dwNewSize = dwOldPos - lpck->dwDataOffset; @@ -882,6 +1043,8 @@ UINT16 WINAPI mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags) else if (uFlags == MMIO_CREATERIFF) lpck->ckid = FOURCC_RIFF; + TRACE(mmio, "ckid=%08lX\n", lpck->ckid); + lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD); if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) lpck->dwDataOffset += sizeof(DWORD); diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c index 458a5be133f..40d44244c3d 100644 --- a/multimedia/mmsystem.c +++ b/multimedia/mmsystem.c @@ -162,13 +162,17 @@ BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags) TRACE(mmsys, "Stop !\n"); return FALSE; } - hmmio = mmioOpen16((LPSTR)lpszSoundName, NULL, - MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); - if (uFlags & SND_MEMORY) { - FIXME(mmsys, "SND_MEMORY flag not implemented!\n"); - return FALSE; - } + MMIOINFO16 mminfo; + memset(&mminfo, 0, sizeof(mminfo)); + mminfo.fccIOProc = FOURCC_MEM; + mminfo.pchBuffer = (LPSTR)lpszSoundName; + mminfo.cchBuffer = -1; + TRACE(mmsys, "Memory sound %p\n",lpszSoundName); + hmmio = mmioOpen16(NULL, &mminfo, MMIO_READ); + } else + hmmio = mmioOpen16((LPSTR)lpszSoundName, NULL, + MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE); if (hmmio == 0) { @@ -233,7 +237,7 @@ BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags) { WAVEHDR waveHdr; HGLOBAL16 hData; - INT32 count, bufsize; + INT32 count, bufsize, left = mmckInfo.cksize; bufsize = 64000; hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize); @@ -246,10 +250,12 @@ BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags) dwRet = wodMessage(0,WODM_PREPARE,0,(DWORD)&waveHdr,sizeof(WAVEHDR)); if (dwRet == MMSYSERR_NOERROR) { - while( TRUE ) + while( left ) { + if (bufsize > left) bufsize = left; count = mmioRead32(hmmio,waveHdr.lpData,bufsize); if (count < 1) break; + left -= count; waveHdr.dwBufferLength = count; /* waveHdr.dwBytesRecorded = count; */ /* FIXME: doesn't expect async ops */ diff --git a/objects/bitmap.c b/objects/bitmap.c index a3df02bc92c..2480f273555 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -394,6 +394,22 @@ LONG WINAPI GetBitmapBits32( tbuf += pad; } break; + + case 32: + for (h=0;hbitmap.bmWidth;w++) + { + long pixel = XGetPixel(image,w,h); + + *tbuf++ = pixel & 0xff; + *tbuf++ = (pixel>> 8) & 0xff; + *tbuf++ = (pixel>>16) & 0xff; + *tbuf++ = (pixel>>24) & 0xff; + } + tbuf += pad; + } + break; default: FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel); } @@ -524,6 +540,20 @@ LONG WINAPI SetBitmapBits32( sbuf += pad; } break; + case 32: + for (h=0;hbitmap.bmWidth;w++) + { + XPutPixel(image,w,h,(sbuf[3]<<24)+(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]); + sbuf += 4; + } + sbuf += pad; + } + break; + default: + FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel); + } descr.bmp = bmp; @@ -684,7 +714,7 @@ HBITMAP32 WINAPI CopyBitmap32 (HBITMAP32 hnd) * FIXME: implementation still lacks nearly all features, see LR_* * defines in windows.h */ -HANDLE32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx, +HICON32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx, INT32 desiredy, UINT32 flags ) { switch (type) @@ -699,7 +729,6 @@ HANDLE32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx, return 0; } - /********************************************************************** * LoadBitmap16 (USER.175) * diff --git a/objects/color.c b/objects/color.c index 6487adb6bbc..65fdcccb1a6 100644 --- a/objects/color.c +++ b/objects/color.c @@ -816,9 +816,11 @@ COLORREF COLOR_ToLogical(int pixel) { XColor color; +#if 0 /* truecolor visual */ if (screenDepth >= 24) return pixel; +#endif /* check for hicolor visuals first */ diff --git a/objects/dc.c b/objects/dc.c index 20243c3b5ce..1899d4879fd 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -1497,3 +1497,24 @@ WORD WINAPI SetHookFlags(HDC16 hDC, WORD flags) return 0; } +/*********************************************************************** + * SetICMMode (GDI32.318) + */ +INT32 WINAPI SetICMMode(HDC32 hdc, INT32 iEnableICM) +{ +/*FIXME Asuming that ICM is always off, and cannot be turned on */ + if (iEnableICM == ICM_OFF) return ICM_OFF; + if (iEnableICM == ICM_ON) return 0; + if (iEnableICM == ICM_QUERY) return ICM_OFF; + return 0; +} + + +/*********************************************************************** + * GetColorSpace (GDI32.165) + */ +HCOLORSPACE32 WINAPI GetColorSpace(HDC32 hdc) +{ +/*FIXME Need to to whatever GetColorSpace actually does */ + return 0; +} diff --git a/objects/font.c b/objects/font.c index 91434d37d51..95575b4e25b 100644 --- a/objects/font.c +++ b/objects/font.c @@ -927,9 +927,9 @@ BOOL32 WINAPI GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics ) * Success: Non-zero or size of required buffer * Failure: 0 */ -INT16 WINAPI GetOutlineTextMetrics( +UINT16 WINAPI GetOutlineTextMetrics16( HDC16 hdc, /* [in] Handle of device context */ - INT16 cbData, /* [in] Size of metric data array */ + UINT16 cbData, /* [in] Size of metric data array */ void *lpOTM) /* [out] Address of metric data array */ { FIXME(font, "(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM); @@ -1036,7 +1036,7 @@ DWORD WINAPI SetMapperFlags32( HDC32 hDC, DWORD dwFlag ) /*********************************************************************** * GetAspectRatioFilterEx16 (GDI.486) */ -BOOL16 GetAspectRatioFilterEx16( HDC16 hdc, LPVOID pAspectRatio ) +BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio ) { FIXME(font, "(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio); @@ -1290,8 +1290,8 @@ DWORD WINAPI GetFontData32(HDC32 hdc, DWORD table, DWORD offset, * GetCharacterPlacement32A [GDI32.160] */ DWORD WINAPI -GetCharacterPlacement32A(HDC32 hdc, LPCSTR lpString, UINT32 uCount, - INT32 nMaxExtent, GCP_RESULTS32A lpResults, +GetCharacterPlacement32A(HDC32 hdc, LPCSTR lpString, INT32 uCount, + INT32 nMaxExtent, GCP_RESULTS32A *lpResults, DWORD dwFlags) { /* return value 0 is correct for most cases anyway */ @@ -1303,12 +1303,11 @@ GetCharacterPlacement32A(HDC32 hdc, LPCSTR lpString, UINT32 uCount, * GetCharacterPlacement32W [GDI32.161] */ DWORD WINAPI -GetCharacterPlacement32W(HDC32 hdc, LPCWSTR lpString, UINT32 uCount, - INT32 nMaxExtent, GCP_RESULTS32W lpResults, +GetCharacterPlacement32W(HDC32 hdc, LPCWSTR lpString, INT32 uCount, + INT32 nMaxExtent, GCP_RESULTS32W *lpResults, DWORD dwFlags) { /* return value 0 is correct for most cases anyway */ FIXME(font,":stub!\n"); return 0; } - diff --git a/ole/Makefile.in b/ole/Makefile.in index bbe7198a8ee..134f4fc3b36 100644 --- a/ole/Makefile.in +++ b/ole/Makefile.in @@ -8,7 +8,6 @@ MODULE = ole C_SRCS = \ compobj.c \ ifs.c \ - folders.c \ moniker.c \ ole2.c \ ole2disp.c \ diff --git a/ole/folders.c b/ole/folders.c deleted file mode 100644 index 3ddde1108b5..00000000000 --- a/ole/folders.c +++ /dev/null @@ -1,2215 +0,0 @@ -/* - * Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL) - * - * Copyright 1997 Marcus Meissner - * Copyright 1998 Juergen Schmied - * - * !!! currently work in progress on all classes !!! - * - */ - -#include -#include -#include -#include "ole.h" -#include "ole2.h" -#include "debug.h" -#include "compobj.h" -#include "interfaces.h" -#include "shlobj.h" -#include "winerror.h" -#include "winnls.h" -#include "winproc.h" - -/* FIXME should be moved to a header file. IsEqualGUID -is declared but not exported in compobj.c !!!*/ -#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) -#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) -#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) -/*************************************************************************** - * GetNextElement (internal function) - * - * gets a part of a string till the first backslash - * - * PARAMETERS - * pszNext [IN] string to get the element from - * pszOut [IN] pointer to buffer whitch receives string - * dwOut [IN] length of pszOut - * - * RETURNS - * LPSTR pointer to first, not yet parsed char - */ -LPSTR GetNextElement(LPSTR pszNext,LPSTR pszOut,DWORD dwOut) -{ LPSTR pszTail = pszNext; - DWORD dwCopy; - TRACE(shell,"(%s %p 0x%08lx)\n",debugstr_a(pszNext),pszOut,dwOut); - - if(!pszNext || !*pszNext) - return NULL; - - while(*pszTail && (*pszTail != '\\')) - { pszTail++; - } - dwCopy=((LPBYTE)pszTail-(LPBYTE)pszNext)/sizeof(CHAR)+1; - lstrcpyn32A(pszOut, pszNext, (dwOutref = 1; - lpclf->lpvtbl = &clfvt; - TRACE(shell,"(%p)->()\n",lpclf); - return lpclf; -} -/************************************************************************** - * IClassFactory::QueryInterface - */ -static HRESULT WINAPI IClassFactory_QueryInterface( - LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj) -{ char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ - { *ppvObj = this; - } - else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/ - { *ppvObj = (IClassFactory*)this; - } - - if(*ppvObj) - { (*(LPCLASSFACTORY*)ppvObj)->lpvtbl->fnAddRef(this); - TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE(shell,"-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} -/****************************************************************************** - * IClassFactory_AddRef - */ -static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); - return ++(this->ref); -} -/****************************************************************************** - * IClassFactory_Release - */ -static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); - if (!--(this->ref)) - { TRACE(shell,"-- destroying IClassFactory(%p)\n",this); - HeapFree(GetProcessHeap(),0,this); - return 0; - } - return this->ref; -} -/****************************************************************************** - * IClassFactory_CreateInstance - */ -static HRESULT WINAPI IClassFactory_CreateInstance( - LPCLASSFACTORY this, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject) -{ IUnknown *pObj = NULL; - HRESULT hres; - char xriid[50]; - - WINE_StringFromCLSID((LPCLSID)riid,xriid); - TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown,xriid,ppObject); - - *ppObject = NULL; - - if(pUnknown) - { return(CLASS_E_NOAGGREGATION); - } - - if (IsEqualIID(riid, &IID_IShellFolder)) - { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL); - } - else if (IsEqualIID(riid, &IID_IShellView)) - { pObj = (IUnknown *)IShellView_Constructor(); - } - else if (IsEqualIID(riid, &IID_IShellLink)) - { pObj = (IUnknown *)IShellLink_Constructor(); - } - else - { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid); - return(E_NOINTERFACE); - } - - if (!pObj) - { return(E_OUTOFMEMORY); - } - - hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject); - pObj->lpvtbl->fnRelease(pObj); - TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject); - - return hres; -} -/****************************************************************************** - * IClassFactory_LockServer - */ -static HRESULT WINAPI IClassFactory_LockServer(LPCLASSFACTORY this, BOOL32 fLock) -{ TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock); - return E_NOTIMPL; -} - -/************************************************************************** - * IEnumIDList Implementation - */ -static HRESULT WINAPI IEnumIDList_QueryInterface(LPENUMIDLIST,REFIID,LPVOID*); -static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST); -static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST); -static HRESULT WINAPI IEnumIDList_Next(LPENUMIDLIST,ULONG,LPITEMIDLIST*,ULONG*); -static HRESULT WINAPI IEnumIDList_Skip(LPENUMIDLIST,ULONG); -static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST); -static HRESULT WINAPI IEnumIDList_Clone(LPENUMIDLIST,LPENUMIDLIST*); -static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST,LPCSTR, DWORD); -static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST,LPITEMIDLIST); -static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST); -/************************************************************************** - * IEnumIDList_VTable - */ -static IEnumIDList_VTable eidlvt = -{ IEnumIDList_QueryInterface, - IEnumIDList_AddRef, - IEnumIDList_Release, - IEnumIDList_Next, - IEnumIDList_Skip, - IEnumIDList_Reset, - IEnumIDList_Clone, - IEnumIDList_CreateEnumList, - IEnumIDList_AddToEnumList, - IEnumIDList_DeleteList -}; - -/************************************************************************** - * IEnumIDList_Constructor - */ - -LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult) -{ LPENUMIDLIST lpeidl; - - lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList)); - lpeidl->ref = 1; - lpeidl->lpvtbl = &eidlvt; - lpeidl->mpFirst=NULL; - lpeidl->mpLast=NULL; - lpeidl->mpCurrent=NULL; - - TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,debugstr_a(lpszPath),dwFlags,pResult); - - lpeidl->mpPidlMgr=PidlMgr_Constructor(); - if (!lpeidl->mpPidlMgr) - { if (pResult) - { *pResult=E_OUTOFMEMORY; - HeapFree(GetProcessHeap(),0,lpeidl); - return NULL; - } - } - - if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags)) - { if(pResult) - { *pResult = E_OUTOFMEMORY; - HeapFree(GetProcessHeap(),0,lpeidl->mpPidlMgr); - HeapFree(GetProcessHeap(),0,lpeidl); - return NULL; - } - } - - TRACE(shell,"-- (%p)->()\n",lpeidl); - return lpeidl; -} - -/************************************************************************** - * EnumIDList::QueryInterface - */ -static HRESULT WINAPI IEnumIDList_QueryInterface( - LPENUMIDLIST this, REFIID riid, LPVOID *ppvObj) -{ char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ - { *ppvObj = this; - } - else if(IsEqualIID(riid, &IID_IEnumIDList)) /*IEnumIDList*/ - { *ppvObj = (IEnumIDList*)this; - } - - if(*ppvObj) - { (*(LPENUMIDLIST*)ppvObj)->lpvtbl->fnAddRef(this); - TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE(shell,"-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/****************************************************************************** - * IEnumIDList_AddRef - */ -static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this) -{ TRACE(shell,"(%p)->()\n",this); - return ++(this->ref); -} -/****************************************************************************** - * IEnumIDList_Release - */ -static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this) -{ TRACE(shell,"(%p)->()\n",this); - if (!--(this->ref)) - { TRACE(shell," destroying IEnumIDList(%p)\n",this); - HeapFree(GetProcessHeap(),0,this); - return 0; - } - return this->ref; -} - -/************************************************************************** - * IEnumIDList_Next - */ - -static HRESULT WINAPI IEnumIDList_Next( - LPENUMIDLIST this,ULONG celt,LPITEMIDLIST * rgelt,ULONG *pceltFetched) -{ ULONG i; - HRESULT hr = S_OK; - LPITEMIDLIST temp; - - TRACE(shell,"(%p)->(%ld,%p, %p)\n",this,celt,rgelt,pceltFetched); - - /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's - subsystems actually use it (and so may a third party browser) - */ - if(pceltFetched) - *pceltFetched = 0; - - *rgelt=0; - - if(celt > 1 && !pceltFetched) - { return E_INVALIDARG; - } - - for(i = 0; i < celt; i++) - { if(!(this->mpCurrent)) - { hr = S_FALSE; - break; - } - temp = ILClone(this->mpCurrent->pidl); - rgelt[i] = temp; - this->mpCurrent = this->mpCurrent->pNext; - } - if(pceltFetched) - { *pceltFetched = i; - } - - return hr; -} - -/************************************************************************** -* IEnumIDList_Skip -*/ -static HRESULT WINAPI IEnumIDList_Skip( - LPENUMIDLIST this,ULONG celt) -{ DWORD dwIndex; - HRESULT hr = S_OK; - - TRACE(shell,"(%p)->(%lu)\n",this,celt); - - for(dwIndex = 0; dwIndex < celt; dwIndex++) - { if(!this->mpCurrent) - { hr = S_FALSE; - break; - } - this->mpCurrent = this->mpCurrent->pNext; - } - return hr; -} -/************************************************************************** -* IEnumIDList_Reset -*/ -static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST this) -{ TRACE(shell,"(%p)\n",this); - this->mpCurrent = this->mpFirst; - return S_OK; -} -/************************************************************************** -* IEnumIDList_Clone -*/ -static HRESULT WINAPI IEnumIDList_Clone( - LPENUMIDLIST this,LPENUMIDLIST * ppenum) -{ TRACE(shell,"(%p)->() to (%p)->() E_NOTIMPL\n",this,ppenum); - return E_NOTIMPL; -} -/************************************************************************** - * EnumIDList_CreateEnumList() - * fixme: devices not handled - * fixme: add wildcards to path - */ -static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST this, LPCSTR lpszPath, DWORD dwFlags) -{ LPITEMIDLIST pidl=NULL; - WIN32_FIND_DATA32A stffile; - HANDLE32 hFile; - DWORD dwDrivemap; - CHAR szDriveName[4]; - CHAR szPath[MAX_PATH]; - - TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags); - - if (lpszPath && lpszPath[0]!='\0') - { strcpy(szPath, lpszPath); - PathAddBackslash(szPath); - strcat(szPath,"*.*"); - } - - /*enumerate the folders*/ - if(dwFlags & SHCONTF_FOLDERS) - { /* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood... - so we need to fake an enumeration of those.*/ - if(!lpszPath) - { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (special) items\n",this); - //create the pidl for this item - pidl = this->mpPidlMgr->lpvtbl->fnCreateMyComputer(this->mpPidlMgr); - if(pidl) - { if(!IEnumIDList_AddToEnumList(this, pidl)) - return FALSE; - } - } - else if (lpszPath[0]=='\0') /* enumerate the drives*/ - { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",this); - dwDrivemap = GetLogicalDrives(); - strcpy (szDriveName,"A:\\"); - while (szDriveName[0]<='Z') - { if(dwDrivemap & 0x00000001L) - { pidl = this->mpPidlMgr->lpvtbl->fnCreateDrive(this->mpPidlMgr,szDriveName ); - if(pidl) - { if(!IEnumIDList_AddToEnumList(this, pidl)) - return FALSE; - } - } - szDriveName[0]++; - dwDrivemap = dwDrivemap >> 1; - } - } - - else - { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",this,debugstr_a(szPath)); - hFile = FindFirstFile32A(szPath,&stffile); - if ( hFile != INVALID_HANDLE_VALUE32 ) - { do - { if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, "..")) - { pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName); - if(pidl) - { if(!IEnumIDList_AddToEnumList(this, pidl)) - { return FALSE; - } - } - else - { return FALSE; - } - } - } while( FindNextFile32A(hFile,&stffile)); - FindClose32 (hFile); - } - } - } - //enumerate the non-folder items (values) - if(dwFlags & SHCONTF_NONFOLDERS) - { if(lpszPath) - { TRACE (shell,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",this,debugstr_a(szPath)); - hFile = FindFirstFile32A(szPath,&stffile); - if ( hFile != INVALID_HANDLE_VALUE32 ) - { do - { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { pidl = this->mpPidlMgr->lpvtbl->fnCreateValue(this->mpPidlMgr, stffile.cFileName); - if(pidl) - { if(!IEnumIDList_AddToEnumList(this, pidl)) - { return FALSE; - } - } - else - { return FALSE; - } - } - } while( FindNextFile32A(hFile,&stffile)); - FindClose32 (hFile); - } - } - } - return TRUE; -} - -/************************************************************************** - * EnumIDList_AddToEnumList() - */ -static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST this,LPITEMIDLIST pidl) -{ LPENUMLIST pNew; - - TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); - pNew = (LPENUMLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ENUMLIST)); - if(pNew) - { //set the next pointer - pNew->pNext = NULL; - pNew->pidl = pidl; - - //is this the first item in the list? - if(!this->mpFirst) - { this->mpFirst = pNew; - this->mpCurrent = pNew; - } - - if(this->mpLast) - { //add the new item to the end of the list - this->mpLast->pNext = pNew; - } - - //update the last item pointer - this->mpLast = pNew; - TRACE(shell,"-- (%p)->(first=%p, last=%p)\n",this,this->mpFirst,this->mpLast); - return TRUE; - } - return FALSE; -} -/************************************************************************** -* EnumIDList_DeleteList() -*/ -static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST this) -{ LPENUMLIST pDelete; - - TRACE(shell,"(%p)->()\n",this); - - while(this->mpFirst) - { pDelete = this->mpFirst; - this->mpFirst = pDelete->pNext; - SHFree(pDelete->pidl); - SHFree(pDelete); - } - this->mpFirst = this->mpLast = this->mpCurrent = NULL; - return TRUE; -} -/*********************************************************************** -* IShellView implementation -*/ -static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID riid, LPVOID *ppvObj); -static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ; -static ULONG WINAPI IShellView_Release(LPSHELLVIEW); - - // *** IOleWindow methods *** -static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd); -static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode); - - // *** IShellView methods *** -static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg); -static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable); -static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState); -static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW); -static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd); -static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW); -static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs); -static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam); -static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW); -static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags); -static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv); - -static struct IShellView_VTable svvt = -{ IShellView_QueryInterface, - IShellView_AddRef, - IShellView_Release, - IShellView_GetWindow, - IShellView_ContextSensitiveHelp, - IShellView_TranslateAccelerator, - IShellView_EnableModeless, - IShellView_UIActivate, - IShellView_Refresh, - IShellView_CreateViewWindow, - IShellView_DestroyViewWindow, - IShellView_GetCurrentInfo, - IShellView_AddPropertySheetPages, - IShellView_SaveViewState, - IShellView_SelectItem, - IShellView_GetItemObject -}; -/************************************************************************** -* IShellView_Constructor -*/ -LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl) -{ LPSHELLVIEW sv; - sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView)); - sv->ref=1; - sv->lpvtbl=&svvt; - - sv->mpidl = ILClone(pidl); - - sv->pSFParent = pFolder; - if(sv->pSFParent) - sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent); - - TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl); - return sv; -} -/************************************************************************** -* ShellView_WndProc -*/ -LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam) -{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA); - LPCREATESTRUCT32A lpcs; - - FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam); - - switch (uMessage) - { case WM_NCCREATE: - { TRACE(shell,"WM_NCCREATE\n"); - lpcs = (LPCREATESTRUCT32A)lParam; - pThis = (LPSHELLVIEW)(lpcs->lpCreateParams); - SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis); - - //set the window handle - pThis->hWnd = hWnd; - } - break; - - case WM_SIZE: - TRACE(shell,"WM_SIZE\n"); - return FALSE; - - case WM_CREATE: - TRACE(shell,"WM_CREATE\n"); - return FALSE; - - case WM_SETFOCUS: - TRACE(shell,"WM_SETFOCUS\n"); - return FALSE; - - case WM_KILLFOCUS: - TRACE(shell,"WM_KILLFOCUS\n"); - return FALSE; - - case WM_ACTIVATE: - TRACE(shell,"WM_ACTIVATE\n"); - return FALSE; - - case WM_COMMAND: - TRACE(shell,"WM_COMMAND\n"); - return FALSE; - - case WM_INITMENUPOPUP: - TRACE(shell,"WM_INITMENUPOPUP\n"); - return FALSE; - - case WM_NOTIFY: - TRACE(shell,"WM_NOTIFY\n"); - return FALSE; - -/* case WM_SETTINGCHANGE: - return FALSE;*/ - } - - return DefWindowProc32A (hWnd, uMessage, wParam, lParam); -} - - -/************************************************************************** -* IShellView::QueryInterface -*/ -static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj) -{ char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ - { *ppvObj = this; - } - else if(IsEqualIID(riid, &IID_IShellView)) /*IShellView*/ - { *ppvObj = (IShellView*)this; - } - - if(*ppvObj) - { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this); - TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE(shell,"-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} -/************************************************************************** -* IShellView::AddRef -*/ -static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); - return ++(this->ref); -} -/************************************************************************** -* IShellView::Release -*/ -static ULONG WINAPI IShellView_Release(LPSHELLVIEW this) -{ TRACE(shell,"(%p)->()\n",this); - if (!--(this->ref)) - { TRACE(shell," destroying IEnumIDList(%p)\n",this); - - if(this->pSFParent) - this->pSFParent->lpvtbl->fnRelease(this->pSFParent); - - HeapFree(GetProcessHeap(),0,this); - return 0; - } - return this->ref; -} -/************************************************************************** -* IShellView::GetWindow -*/ -static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd) -{ TRACE(shell,"(%p) stub\n",this); - *phWnd = this->hWnd; - - return S_OK; -} -static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode) -{ FIXME(shell,"(%p) stub\n",this); - return E_NOTIMPL; -} -static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg) -{ FIXME(shell,"(%p)->(%p) stub\n",this,lpmsg); - return E_NOTIMPL; -} -static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable) -{ FIXME(shell,"(%p) stub\n",this); - return E_NOTIMPL; -} -static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState) -{ FIXME(shell,"(%p) stub\n",this); - return E_NOTIMPL; -} -static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this) -{ FIXME(shell,"(%p) stub\n",this); - return S_OK; -} -static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView, - LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd) -{ WNDCLASS32A wc; - *phWnd = 0; - - TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd); - -//if our window class has not been registered, then do so - if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc)) - { ZeroMemory(&wc, sizeof(wc)); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC32) ShellView_WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = shell32_hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursor32A (0, IDC_ARROW32A); - wc.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = SV_CLASS_NAME; - - if(!RegisterClass32A(&wc)) - return E_FAIL; - } - //set up the member variables - this->pShellBrowser = psb; - this->FolderSettings = *lpfs; - - //get our parent window - this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent)); - - *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, - prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top, - this->hWndParent, 0, shell32_hInstance, (LPVOID)this); - - if(!*phWnd) - return E_FAIL; - - this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser); - - return S_OK; -} - -static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this) -{ FIXME(shell,"(%p) stub\n",this); - - this->pShellBrowser->lpvtbl->fnRelease(this->pShellBrowser); - - return S_OK; -} -static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs) -{ FIXME(shell,"(%p)->(%p)stub\n",this, lpfs); - - *lpfs = this->FolderSettings; - return S_OK; -} -static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam) -{ FIXME(shell,"(%p) stub\n",this); - return E_NOTIMPL; -} -static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this) -{ FIXME(shell,"(%p) stub\n",this); - return S_OK; -} -static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags) -{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags); - return E_NOTIMPL; -} -static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut) -{ char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - - FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut); - - *ppvOut = NULL; - return E_NOTIMPL; -} - -/*********************************************************************** -* IShellFolder implementation -*/ -static HRESULT WINAPI IShellFolder_QueryInterface(LPSHELLFOLDER,REFIID,LPVOID*); -static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER); -static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER); -static HRESULT WINAPI IShellFolder_Initialize(LPSHELLFOLDER,LPCITEMIDLIST); -static HRESULT WINAPI IShellFolder_ParseDisplayName(LPSHELLFOLDER,HWND32,LPBC,LPOLESTR32,DWORD*,LPITEMIDLIST*,DWORD*); -static HRESULT WINAPI IShellFolder_EnumObjects(LPSHELLFOLDER,HWND32,DWORD,LPENUMIDLIST*); -static HRESULT WINAPI IShellFolder_BindToObject(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*); -static HRESULT WINAPI IShellFolder_BindToStorage(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*); -static HRESULT WINAPI IShellFolder_CompareIDs(LPSHELLFOLDER,LPARAM,LPCITEMIDLIST,LPCITEMIDLIST); -static HRESULT WINAPI IShellFolder_CreateViewObject(LPSHELLFOLDER,HWND32,REFIID,LPVOID*); -static HRESULT WINAPI IShellFolder_GetAttributesOf(LPSHELLFOLDER,UINT32,LPCITEMIDLIST*,DWORD*); -static HRESULT WINAPI IShellFolder_GetUIObjectOf(LPSHELLFOLDER,HWND32,UINT32,LPCITEMIDLIST*,REFIID,UINT32*,LPVOID*); -static HRESULT WINAPI IShellFolder_GetDisplayNameOf(LPSHELLFOLDER,LPCITEMIDLIST,DWORD,LPSTRRET); -static HRESULT WINAPI IShellFolder_SetNameOf(LPSHELLFOLDER,HWND32,LPCITEMIDLIST,LPCOLESTR32,DWORD,LPITEMIDLIST*); -/*********************************************************************** -* -* IShellFolder_VTable -*/ -static struct IShellFolder_VTable sfvt = -{ IShellFolder_QueryInterface, - IShellFolder_AddRef, - IShellFolder_Release, - IShellFolder_ParseDisplayName, - IShellFolder_EnumObjects, - IShellFolder_BindToObject, - IShellFolder_BindToStorage, - IShellFolder_CompareIDs, - IShellFolder_CreateViewObject, - IShellFolder_GetAttributesOf, - IShellFolder_GetUIObjectOf, - IShellFolder_GetDisplayNameOf, - IShellFolder_SetNameOf - /* IShellFolder_Initialize*/ -}; -/************************************************************************** -* IShellFolder_Constructor -*/ - -LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER pParent,LPITEMIDLIST pidl) -{ LPSHELLFOLDER sf; - DWORD dwSize=0; - sf=(LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder)); - sf->ref=1; - sf->lpvtbl=&sfvt; - sf->mlpszFolder=NULL; - sf->mpSFParent=pParent; - - TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl); - - /* create own pidl-manager*/ - sf->pPidlMgr = PidlMgr_Constructor(); - if (! sf->pPidlMgr ) - { HeapFree(GetProcessHeap(),0,sf); - ERR (shell,"-- Could not initialize PidMGR\n"); - return NULL; - } - - /* keep a copy of the pidl in the instance*/ - sf->mpidl = ILClone(pidl); - sf->mpidlNSRoot = NULL; - - if(sf->mpidl) /* do we have a pidl?*/ - { dwSize = 0; - if(sf->mpSFParent->mlpszFolder) - { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1; - } - dwSize += sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr,sf->mpidl,NULL,0); - sf->mlpszFolder = SHAlloc(dwSize); - if(sf->mlpszFolder) - { *(sf->mlpszFolder)=0x00; - if(sf->mpSFParent->mlpszFolder) - { strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder); - PathAddBackslash (sf->mlpszFolder); - } - sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder)); - } - } - - TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder)); - return sf; -} -/************************************************************************** -* IShellFolder::QueryInterface -* PARAMETERS -* REFIID riid, //[in ] Requested InterfaceID -* LPVOID* ppvObject) //[out] Interface* to hold the result -*/ -static HRESULT WINAPI IShellFolder_QueryInterface( - LPSHELLFOLDER this, REFIID riid, LPVOID *ppvObj) -{ char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ - { *ppvObj = this; - } - else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/ - { *ppvObj = (IShellFolder*)this; - } - - if(*ppvObj) - { (*(LPSHELLFOLDER*)ppvObj)->lpvtbl->fnAddRef(this); - TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE(shell,"-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/************************************************************************** -* IShellFolder::AddRef -*/ - -static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); - return ++(this->ref); -} - -/************************************************************************** - * IShellFolder_Release - */ -static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); - if (!--(this->ref)) - { TRACE(shell,"-- destroying IShellFolder(%p)\n",this); - - if (pdesktopfolder==this) - { pdesktopfolder=NULL; - TRACE(shell,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this); - } - if (this->pPidlMgr) - { PidlMgr_Destructor(this->pPidlMgr); - } - if(this->mpidlNSRoot) - { SHFree(this->mpidlNSRoot); - } - if(this->mpidl) - { SHFree(this->mpidl); - } - if(this->mlpszFolder) - { SHFree(this->mlpszFolder); - } - - HeapFree(GetProcessHeap(),0,this); - - return 0; - } - return this->ref; -} -/************************************************************************** -* IShellFolder_ParseDisplayName -* PARAMETERS -* HWND hwndOwner, //[in ] Parent window for any message's -* LPBC pbc, //[in ] reserved -* LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname. -* ULONG* pchEaten, //[out] (unicode) characters processed -* LPITEMIDLIST* ppidl, //[out] complex pidl to item -* ULONG* pdwAttributes //[out] items attributes -* -* FIXME: -* pdwAttributes: not used -*/ -static HRESULT WINAPI IShellFolder_ParseDisplayName( - LPSHELLFOLDER this, - HWND32 hwndOwner, - LPBC pbcReserved, - LPOLESTR32 lpszDisplayName, - DWORD *pchEaten, - LPITEMIDLIST *ppidl, - DWORD *pdwAttributes) -{ HRESULT hr=E_OUTOFMEMORY; - LPITEMIDLIST pidlFull=NULL, pidlTemp = NULL, pidlOld = NULL; - LPSTR pszNext=NULL; - CHAR szElement[MAX_PATH]; - BOOL32 bType; - - DWORD dwChars=lstrlen32W(lpszDisplayName) + 1; - LPSTR pszTemp=(LPSTR)HeapAlloc(GetProcessHeap(),0,dwChars * sizeof(CHAR)); - - TRACE(shell,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n", - this,hwndOwner,pbcReserved,lpszDisplayName,debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes); - - if(pszTemp) - { hr = E_FAIL; - WideCharToLocal32(pszTemp, lpszDisplayName, dwChars); - if(*pszTemp) - { if (strcmp(pszTemp,"Desktop")==0) - { pidlFull = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,2); - pidlFull->mkid.cb = 0; - } - else - { pidlFull = this->pPidlMgr->lpvtbl->fnCreateMyComputer(this->pPidlMgr); - - /* check if the lpszDisplayName is Folder or File*/ - bType = ! (GetFileAttributes32A(pszNext)&FILE_ATTRIBUTE_DIRECTORY); - pszNext = GetNextElement(pszTemp, szElement, MAX_PATH); - - pidlTemp = this->pPidlMgr->lpvtbl->fnCreateDrive(this->pPidlMgr,szElement); - pidlOld = pidlFull; - pidlFull = ILCombine(pidlFull,pidlTemp); - SHFree(pidlOld); - - if(pidlFull) - { while((pszNext=GetNextElement(pszNext, szElement, MAX_PATH))) - { if(!*pszNext && bType) - { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateValue(this->pPidlMgr,szElement); - } - else - { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateFolder(this->pPidlMgr,szElement); - } - pidlOld = pidlFull; - pidlFull = ILCombine(pidlFull,pidlTemp); - SHFree(pidlOld); - } - hr = S_OK; - } - } - } - } - HeapFree(GetProcessHeap(),0,pszTemp); - *ppidl = pidlFull; - return hr; -} - -/************************************************************************** -* IShellFolder_EnumObjects -* PARAMETERS -* HWND hwndOwner, //[in ] Parent Window -* DWORD grfFlags, //[in ] SHCONTF enumeration mask -* LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface -*/ -static HRESULT WINAPI IShellFolder_EnumObjects( - LPSHELLFOLDER this, - HWND32 hwndOwner, - DWORD dwFlags, - LPENUMIDLIST* ppEnumIDList) -{ HRESULT hr; - TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList); - - *ppEnumIDList = NULL; - *ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr); - TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList); - if(!*ppEnumIDList) - { return hr; - } - return S_OK; -} -/************************************************************************** - * IShellFolder_Initialize() - * IPersistFolder Method - */ -static HRESULT WINAPI IShellFolder_Initialize( - LPSHELLFOLDER this, - LPCITEMIDLIST pidl) -{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); - if(this->mpidlNSRoot) - { SHFree(this->mpidlNSRoot); - this->mpidlNSRoot = NULL; - } - this->mpidlNSRoot=ILClone(pidl); - return S_OK; -} - -/************************************************************************** -* IShellFolder_BindToObject -* PARAMETERS -* LPCITEMIDLIST pidl, //[in ] complex pidl to open -* LPBC pbc, //[in ] reserved -* REFIID riid, //[in ] Initial Interface -* LPVOID* ppvObject //[out] Interface* -*/ -static HRESULT WINAPI IShellFolder_BindToObject( - LPSHELLFOLDER this, - LPCITEMIDLIST pidl, - LPBC pbcReserved, - REFIID riid, - LPVOID * ppvOut) -{ char xriid[50]; - HRESULT hr; - LPSHELLFOLDER pShellFolder; - - WINE_StringFromCLSID(riid,xriid); - - TRACE(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl,pbcReserved,xriid,ppvOut); - - *ppvOut = NULL; - pShellFolder = IShellFolder_Constructor(this, pidl); - if(!pShellFolder) - return E_OUTOFMEMORY; - /* pShellFolder->lpvtbl->fnInitialize(pShellFolder, this->mpidlNSRoot);*/ - IShellFolder_Initialize(pShellFolder, this->mpidlNSRoot); - hr = pShellFolder->lpvtbl->fnQueryInterface(pShellFolder, riid, ppvOut); - pShellFolder->lpvtbl->fnRelease(pShellFolder); - TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut); - return hr; -} - -/************************************************************************** -* IShellFolder_BindToStorage -* PARAMETERS -* LPCITEMIDLIST pidl, //[in ] complex pidl to store -* LPBC pbc, //[in ] reserved -* REFIID riid, //[in ] Initial storage interface -* LPVOID* ppvObject //[out] Interface* returned -*/ -static HRESULT WINAPI IShellFolder_BindToStorage( - LPSHELLFOLDER this, - LPCITEMIDLIST pidl, /*simple/complex pidl*/ - LPBC pbcReserved, - REFIID riid, - LPVOID *ppvOut) -{ char xriid[50]; - WINE_StringFromCLSID(riid,xriid); - - FIXME(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl,pbcReserved,xriid,ppvOut); - - *ppvOut = NULL; - return E_NOTIMPL; -} - -/************************************************************************** -* IShellFolder_CompareIDs -* -* PARMETERS -* LPARAM lParam, //[in ] Column? -* LPCITEMIDLIST pidl1, //[in ] simple pidl -* LPCITEMIDLIST pidl2) //[in ] simple pidl -* FIXME -* we have to handle simple pidl's only -*/ -static HRESULT WINAPI IShellFolder_CompareIDs( - LPSHELLFOLDER this, - LPARAM lParam, - LPCITEMIDLIST pidl1, /*simple pidl*/ - LPCITEMIDLIST pidl2) /*simple pidl*/ -{ CHAR szString1[MAX_PATH] = ""; - CHAR szString2[MAX_PATH] = ""; - int nReturn; - LPCITEMIDLIST pidlTemp1 = pidl1, pidlTemp2 = pidl2; - - TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam,pidl1,pidl2); - - /*Special case - If one of the items is a Path and the other is a File, always - make the Path come before the File.*/ - - /* get the last item in each list */ - while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1))->mkid.cb) - pidlTemp1 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1); - while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2))->mkid.cb) - pidlTemp2 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2); - - /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */ - if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1) != this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp2)) - { if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1)) - return 1; - return -1; - } - - this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl1,szString1,sizeof(szString1)); - this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl2,szString1,sizeof(szString2)); - nReturn = strcasecmp(szString1, szString2); - if(nReturn) - return nReturn; - - this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl1,szString1,sizeof(szString1)); - this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl2,szString2,sizeof(szString2)); - nReturn = strcasecmp(szString1, szString2); - if(nReturn) - return nReturn; - - this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl1,szString1,sizeof(szString1)); - this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl2,szString2,sizeof(szString2)); - return strcasecmp(szString1, szString2); -} - -/************************************************************************** -* IShellFolder_CreateViewObject -* Creates an View Object representing the ShellFolder -* IShellView / IShellBrowser / IContextMenu -* -* PARAMETERS -* HWND hwndOwner, // Handle of owner window -* REFIID riid, // Requested initial interface -* LPVOID* ppvObject) // Resultant interface* -* -* NOTES -* the same as SHCreateShellFolderViewEx ??? -*/ -static HRESULT WINAPI IShellFolder_CreateViewObject( - LPSHELLFOLDER this, - HWND32 hwndOwner, - REFIID riid, - LPVOID *ppvOut) -{ LPSHELLVIEW pShellView; - char xriid[50]; - HRESULT hr; - - WINE_StringFromCLSID(riid,xriid); - TRACE(shell,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner,xriid,ppvOut); - - *ppvOut = NULL; - - pShellView = IShellView_Constructor(this, this->mpidl); - if(!pShellView) - return E_OUTOFMEMORY; - hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut); - pShellView->lpvtbl->fnRelease(pShellView); - TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut); - return hr; -} - -/************************************************************************** -* IShellFolder_GetAttributesOf -* -* PARAMETERS -* UINT cidl, //[in ] num elements in pidl array -+ LPCITEMIDLIST* apidl, //[in ] simple pidl array -* ULONG* rgfInOut) //[out] result array -* -* FIXME: quick hack -* Note: rgfInOut is documented as being an array of ULONGS. -* This does not seem to be the case. Testing this function using the shell to -* call it with cidl > 1 (by deleting multiple items) reveals that the shell -* passes ONE element in the array and writing to further elements will -* cause the shell to fail later. -*/ -static HRESULT WINAPI IShellFolder_GetAttributesOf( - LPSHELLFOLDER this, - UINT32 cidl, - LPCITEMIDLIST *apidl, /*simple pidl's*/ - DWORD *rgfInOut) -{ LPCITEMIDLIST * pidltemp; - DWORD i; - TRACE(shell,"(%p)->(%d,%p,%p)\n",this,cidl,apidl,rgfInOut); - - pidltemp=apidl; - *rgfInOut = 0x00; - i=cidl; - if ((! cidl )| (!apidl) | (!rgfInOut)) - return E_INVALIDARG; - - do - { if (*pidltemp) - { if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, *pidltemp)) - { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); - } - else if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, *pidltemp)) - { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER); - } - else if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, *pidltemp)) - { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM); - } - else if (this->pPidlMgr->lpvtbl->fnIsFolder(this->pPidlMgr, *pidltemp)) - { *rgfInOut |= (SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER); - } - else if (this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, *pidltemp)) - { *rgfInOut |= (SFGAO_FILESYSTEM); - } - } - pidltemp++; - cidl--; - } while (cidl > 0 && *pidltemp); - - return S_OK; -} -/************************************************************************** -* IShellFolder_GetUIObjectOf -* -* PARAMETERS -* HWND hwndOwner, //[in ] Parent window for any output -* UINT cidl, //[in ] array size -* LPCITEMIDLIST* apidl, //[in ] simple pidl array -* REFIID riid, //[in ] Requested Interface -* UINT* prgfInOut, //[ ] reserved -* LPVOID* ppvObject) //[out] Resulting Interface -* -* NOTES -* This function gets asked to return "view objects" for one or more (multiple select) -* items: -* The viewobject typically is an COM object with one of the following interfaces: -* IExtractIcon,IDataObject,IContextMenu -* In order to support icon positions in the default Listview your DataObject -* must implement the SetData method (in addition to GetData :) - the shell passes -* a barely documented "Icon positions" structure to SetData when the drag starts, -* and GetData's it if the drop is in another explorer window that needs the positions. -*/ -static HRESULT WINAPI IShellFolder_GetUIObjectOf( - LPSHELLFOLDER this, - HWND32 hwndOwner, - UINT32 cidl, - LPCITEMIDLIST * apidl, /* simple pidl's*/ - REFIID riid, - UINT32 * prgfInOut, - LPVOID * ppvOut) -{ char xclsid[50]; - - WINE_StringFromCLSID(riid,xclsid); - - FIXME(shell,"(%p)->(%u,%u,pidl=%p,\n\tIID:%s,%p,%p),stub!\n", - this,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut); - - *ppvOut = NULL; - return E_NOTIMPL; -} -/************************************************************************** -* IShellFolder_GetDisplayNameOf -* Retrieves the display name for the specified file object or subfolder -* -* PARAMETERS -* LPCITEMIDLIST pidl, //[in ] complex pidl to item -* DWORD dwFlags, //[in ] SHGNO formatting flags -* LPSTRRET lpName) //[out] Returned display name -* -* FIXME -* if the name is in the pidl the ret value should be a STRRET_OFFSET -*/ -#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00) -#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF) - -static HRESULT WINAPI IShellFolder_GetDisplayNameOf( - LPSHELLFOLDER this, - LPCITEMIDLIST pidl, /* simple/complex pidl*/ - DWORD dwFlags, - LPSTRRET lpName) -{ CHAR szText[MAX_PATH]; - CHAR szTemp[MAX_PATH]; - CHAR szSpecial[MAX_PATH]; - CHAR szDrive[MAX_PATH]; - DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags; - LPITEMIDLIST pidlTemp=NULL; - BOOL32 bSimplePidl=FALSE; - - TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName); - - if (!pidl) - { return E_OUTOFMEMORY; - } - - szSpecial[0]=0x00; - szDrive[0]=0x00; - - /* test if simple(relative) or complex(absolute) pidl */ - pidlTemp = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidl); - if (pidlTemp->mkid.cb==0x00) - { bSimplePidl = TRUE; - } - if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, pidl)) - { strcpy (szText,"Desktop"); - } - else - { if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl)) - { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH); - } - if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, pidl)) - { pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); - if (pidlTemp) - { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH); - } - if ( dwFlags==SHGDN_NORMAL || dwFlags==SHGDN_INFOLDER) - { GetVolumeInformation32A(szTemp,szDrive,MAX_PATH,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0); - if (szTemp[2]=='\\') - { szTemp[2]=0x00; - } - strcat (szDrive," ("); - strcat (szDrive,szTemp); - strcat (szDrive,")"); - } - else - { PathAddBackslash (szTemp); - strcpy(szDrive,szTemp); - } - } - - switch(dwFlags) - { case SHGDN_NORMAL: - this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH); - break; - case SHGDN_INFOLDER: - pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); - if (pidlTemp) - { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szText, MAX_PATH); - } - break; - case SHGDN_FORPARSING: - if (bSimplePidl) - { /* if the IShellFolder has parents, get the path from the - parent and add the ItemName*/ - szText[0]=0x00; - if (this->mlpszFolder && strlen (this->mlpszFolder)) - { if (strcmp(this->mlpszFolder,"My Computer")) - { strcpy (szText,this->mlpszFolder); - PathAddBackslash (szText); - } - } - pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); - if (pidlTemp) - { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH ); - } - strcat(szText,szTemp); - } - else - { /* if the pidl is absolute, get everything from the pidl*/ - this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH); - } - break; - default: return E_INVALIDARG; - } - if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00)) - { strcpy(szText,szDrive); - } - if (szText[0]==0x00 && szSpecial[0]!=0x00) - { strcpy(szText,szSpecial); - } - } - - TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText); - - if(!(lpName)) - { return E_OUTOFMEMORY; - } - lpName->uType = STRRET_CSTR; - strcpy(lpName->u.cStr,szText); - return S_OK; -} - -/************************************************************************** -* IShellFolder_SetNameOf -* Changes the name of a file object or subfolder, possibly changing its item -* identifier in the process. -* -* PARAMETERS -* HWND hwndOwner, //[in ] Owner window for output -* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change -* LPCOLESTR lpszName, //[in ] the items new display name -* DWORD dwFlags, //[in ] SHGNO formatting flags -* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned -*/ -static HRESULT WINAPI IShellFolder_SetNameOf( - LPSHELLFOLDER this, - HWND32 hwndOwner, - LPCITEMIDLIST pidl, /*simple pidl*/ - LPCOLESTR32 lpName, - DWORD dw, - LPITEMIDLIST *pPidlOut) -{ FIXME(shell,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n", - this,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut); - return E_NOTIMPL; -} - -/************************************************************************** -* IShellLink Implementation -*/ -static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*); -static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK); -static ULONG WINAPI IShellLink_Release(LPSHELLLINK); - -/************************************************************************** -* IShellLink_VTable -*/ -static struct IShellLink_VTable slvt = { - IShellLink_QueryInterface, - IShellLink_AddRef, - IShellLink_Release, - (void *)0xcafe0004, - (void *)0xcafe0005, - (void *)0xcafe0006, - (void *)0xcafe0007, - (void *)0xcafe0008, - (void *)0xcafe0009, - (void *)0xcafe0010, - (void *)0xcafe0011, - (void *)0xcafe0012, - (void *)0xcafe0013, - (void *)0xcafe0014, - (void *)0xcafe0015, - (void *)0xcafe0016, - (void *)0xcafe0017, - (void *)0xcafe0018, - (void *)0xcafe0019, - (void *)0xcafe0020, - (void *)0xcafe0021 -}; - -/************************************************************************** - * IShellLink_Constructor - */ -LPSHELLLINK IShellLink_Constructor() -{ LPSHELLLINK sl; - - sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink)); - sl->ref = 1; - sl->lpvtbl = &slvt; - TRACE(shell,"(%p)->()\n",sl); - return sl; -} - -/************************************************************************** - * IShellLink::QueryInterface - */ -static HRESULT WINAPI IShellLink_QueryInterface( - LPSHELLLINK this, REFIID riid, LPVOID *ppvObj) -{ char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ - { *ppvObj = this; - } - else if(IsEqualIID(riid, &IID_IShellLink)) /*IShellLink*/ - { *ppvObj = (LPSHELLLINK)this; - } - - if(*ppvObj) - { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this); - TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE(shell,"-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} -/****************************************************************************** - * IShellLink_AddRef - */ -static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); - return ++(this->ref); -} -/****************************************************************************** - * IClassFactory_Release - */ -static ULONG WINAPI IShellLink_Release(LPSHELLLINK this) -{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); - if (!--(this->ref)) - { TRACE(shell,"-- destroying IShellLink(%p)\n",this); - HeapFree(GetProcessHeap(),0,this); - return 0; - } - return this->ref; -} - - -/************************************************************************** -* INTERNAL CLASS pidlmgr -*/ -LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR); -LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR); -LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR,LPCSTR); -LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR,LPCSTR); -LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR,LPCSTR); -/*void PidlMgr_Delete(LPPIDLMGR,LPITEMIDLIST);*/ -LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR,LPITEMIDLIST); -BOOL32 PidlMgr_GetDesktop(LPPIDLMGR,LPCITEMIDLIST,LPSTR); -BOOL32 PidlMgr_GetDrive(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16); -LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR,LPCITEMIDLIST); -DWORD PidlMgr_GetItemText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16); -BOOL32 PidlMgr_IsDesktop(LPPIDLMGR,LPCITEMIDLIST); -BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR,LPCITEMIDLIST); -BOOL32 PidlMgr_IsDrive(LPPIDLMGR,LPCITEMIDLIST); -BOOL32 PidlMgr_IsFolder(LPPIDLMGR,LPCITEMIDLIST); -BOOL32 PidlMgr_IsValue(LPPIDLMGR,LPCITEMIDLIST); -BOOL32 PidlMgr_HasFolders(LPPIDLMGR,LPSTR,LPCITEMIDLIST); -DWORD PidlMgr_GetFolderText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); -DWORD PidlMgr_GetValueText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); -BOOL32 PidlMgr_GetValueType(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPDWORD); -DWORD PidlMgr_GetDataText(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPSTR,DWORD); -DWORD PidlMgr_GetPidlPath(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); -LPITEMIDLIST PidlMgr_Create(LPPIDLMGR,PIDLTYPE,LPVOID,UINT16); -DWORD PidlMgr_GetData(LPPIDLMGR,PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT16); -LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR,LPCITEMIDLIST); -BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST*,LPITEMIDLIST*); - -static struct PidlMgr_VTable pmgrvt = { - PidlMgr_CreateDesktop, - PidlMgr_CreateMyComputer, - PidlMgr_CreateDrive, - PidlMgr_CreateFolder, - PidlMgr_CreateValue, - /* PidlMgr_Delete,*/ - PidlMgr_GetNextItem, - PidlMgr_GetDesktop, - PidlMgr_GetDrive, - PidlMgr_GetLastItem, - PidlMgr_GetItemText, - PidlMgr_IsDesktop, - PidlMgr_IsMyComputer, - PidlMgr_IsDrive, - PidlMgr_IsFolder, - PidlMgr_IsValue, - PidlMgr_HasFolders, - PidlMgr_GetFolderText, - PidlMgr_GetValueText, - PidlMgr_GetValueType, - PidlMgr_GetDataText, - PidlMgr_GetPidlPath, - PidlMgr_Create, - PidlMgr_GetData, - PidlMgr_GetDataPointer, - PidlMgr_SeparatePathAndValue -}; -/************************************************************************** - * PidlMgr_Constructor - */ -LPPIDLMGR PidlMgr_Constructor() -{ LPPIDLMGR pmgr; - pmgr = (LPPIDLMGR)HeapAlloc(GetProcessHeap(),0,sizeof(pidlmgr)); - pmgr->lpvtbl = &pmgrvt; - TRACE(shell,"(%p)->()\n",pmgr); - /** FIXME DllRefCount++;*/ - return pmgr; -} -/************************************************************************** - * PidlMgr_Destructor - */ -void PidlMgr_Destructor(LPPIDLMGR this) -{ HeapFree(GetProcessHeap(),0,this); - TRACE(shell,"(%p)->()\n",this); - /** FIXME DllRefCount--;*/ -} - -/************************************************************************** - * PidlMgr_CreateDesktop() - * PidlMgr_CreateMyComputer() - * PidlMgr_CreateDrive() - * PidlMgr_CreateFolder() - * PidlMgr_CreateValue() - */ -LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this) -{ TRACE(shell,"(%p)->()\n",this); - return PidlMgr_Create(this,PT_DESKTOP, NULL, 0); -} -LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this) -{ TRACE(shell,"(%p)->()\n",this); - return PidlMgr_Create(this,PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1); -} -LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR this, LPCSTR lpszNew) -{ char sTemp[4]; - strncpy (sTemp,lpszNew,4); - sTemp[2]='\\'; - sTemp[3]=0x00; - TRACE(shell,"(%p)->(%s)\n",this,sTemp); - return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4); -} -LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew) -{ TRACE(shell,"(%p)->(%s)\n",this,lpszNew); - return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1); -} -LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew) -{ TRACE(shell,"(%p)->(%s)\n",this,lpszNew); - return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1); -} -/************************************************************************** - * PidlMgr_Delete() - * Deletes a PIDL - */ -/*void PidlMgr_Delete(LPPIDLMGR this,LPITEMIDLIST pidl) -{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); - HeapFree(GetProcessHeap(),0,pidl); -} -*/ -/************************************************************************** - * PidlMgr_GetNextItem() - */ -LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR this, LPITEMIDLIST pidl) -{ LPITEMIDLIST nextpidl; - - TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); - if(pidl) - { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb); -/* TRACE(shell,"-- (%p)->(next pidl=%p)\n",this,nextpidl);*/ - return nextpidl; - } - else - { return (NULL); - } -} -/************************************************************************** - * PidlMgr_GetDesktop() - * - * FIXME: quick hack - */ -BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut) -{ TRACE(shell,"(%p)->(%p %p)\n",this,pidl,pOut); - return (BOOL32)PidlMgr_GetData(this,PT_DESKTOP, pidl, (LPVOID)pOut, 255); -} -/************************************************************************** - * PidlMgr_GetDrive() - * - * FIXME: quick hack - */ -BOOL32 PidlMgr_GetDrive(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize) -{ LPITEMIDLIST pidlTemp=NULL; - - TRACE(shell,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize); - if(PidlMgr_IsMyComputer(this,pidl)) - { pidlTemp = PidlMgr_GetNextItem(this,pidl); - } - else if (pidlTemp && PidlMgr_IsDrive(this,pidlTemp)) - { return (BOOL32)PidlMgr_GetData(this,PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize); - } - return FALSE; -} -/************************************************************************** - * PidlMgr_GetLastItem() - * Gets the last item in the list - */ -LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR this,LPCITEMIDLIST pidl) -{ LPITEMIDLIST pidlLast = NULL; - - TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); - - if(pidl) - { while(pidl->mkid.cb) - { pidlLast = (LPITEMIDLIST)pidl; - pidl = PidlMgr_GetNextItem(this,pidl); - } - } - return pidlLast; -} -/************************************************************************** - * PidlMgr_GetItemText() - * Gets the text for only this item - */ -DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize) -{ TRACE(shell,"(%p)->(pidl=%p %p %x)\n",this,pidl,lpszText,uSize); - if (PidlMgr_IsMyComputer(this, pidl)) - { return PidlMgr_GetData(this,PT_MYCOMP, pidl, (LPVOID)lpszText, uSize); - } - if (PidlMgr_IsDrive(this, pidl)) - { return PidlMgr_GetData(this,PT_DRIVE, pidl, (LPVOID)lpszText, uSize); - } - return PidlMgr_GetData(this,PT_TEXT, pidl, (LPVOID)lpszText, uSize); -} -/************************************************************************** - * PidlMgr_IsDesktop() - * PidlMgr_IsDrive() - * PidlMgr_IsFolder() - * PidlMgr_IsValue() -*/ -BOOL32 PidlMgr_IsDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl) -{ TRACE(shell,"%p->(%p)\n",this,pidl); - - if (! pidl) - return FALSE; - - return ( pidl->mkid.cb == 0x00 ); -} - -BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl) -{ LPPIDLDATA pData; - TRACE(shell,"%p->(%p)\n",this,pidl); - - if (! pidl) - return FALSE; - - pData = PidlMgr_GetDataPointer(this,pidl); - return (PT_MYCOMP == pData->type); -} - -BOOL32 PidlMgr_IsDrive(LPPIDLMGR this,LPCITEMIDLIST pidl) -{ LPPIDLDATA pData; - TRACE(shell,"%p->(%p)\n",this,pidl); - - if (! pidl) - return FALSE; - - pData = PidlMgr_GetDataPointer(this,pidl); - return (PT_DRIVE == pData->type); -} - -BOOL32 PidlMgr_IsFolder(LPPIDLMGR this,LPCITEMIDLIST pidl) -{ LPPIDLDATA pData; - TRACE(shell,"%p->(%p)\n",this,pidl); - - if (! pidl) - return FALSE; - - pData = PidlMgr_GetDataPointer(this,pidl); - return (PT_FOLDER == pData->type); -} - -BOOL32 PidlMgr_IsValue(LPPIDLMGR this,LPCITEMIDLIST pidl) -{ LPPIDLDATA pData; - TRACE(shell,"%p->(%p)\n",this,pidl); - - if (! pidl) - return FALSE; - - pData = PidlMgr_GetDataPointer(this,pidl); - return (PT_VALUE == pData->type); -} -/************************************************************************** - * PidlMgr_HasFolders() - * fixme: quick hack - */ -BOOL32 PidlMgr_HasFolders(LPPIDLMGR this, LPSTR pszPath, LPCITEMIDLIST pidl) -{ BOOL32 bResult= FALSE; - WIN32_FIND_DATA32A stffile; - HANDLE32 hFile; - - TRACE (shell,"(%p)->%p %p\n",this, pszPath, pidl); - - hFile = FindFirstFile32A(pszPath,&stffile); - do - { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { bResult= TRUE; - } - } while( FindNextFile32A(hFile,&stffile)); - FindClose32 (hFile); - - return bResult; -} - - -/************************************************************************** - * PidlMgr_GetFolderText() - * Creates a Path string from a PIDL, filtering out the special Folders - */ -DWORD PidlMgr_GetFolderText(LPPIDLMGR this,LPCITEMIDLIST pidl, - LPSTR lpszPath, DWORD dwSize) -{ LPITEMIDLIST pidlTemp; - DWORD dwCopied = 0; - - TRACE(shell,"(%p)->(%p)\n",this,pidl); - - if(!pidl) - { return 0; - } - - if(PidlMgr_IsMyComputer(this,pidl)) - { pidlTemp = PidlMgr_GetNextItem(this,pidl); - TRACE(shell,"-- (%p)->skip My Computer\n",this); - } - else - { pidlTemp = (LPITEMIDLIST)pidl; - } - - //if this is NULL, return the required size of the buffer - if(!lpszPath) - { while(pidlTemp->mkid.cb) - { LPPIDLDATA pData = PidlMgr_GetDataPointer(this,pidlTemp); - - //add the length of this item plus one for the backslash - dwCopied += strlen(pData->szText) + 1; /* fixme pData->szText is not every time a string*/ - - pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); - } - - //add one for the NULL terminator - TRACE(shell,"-- (%p)->(size=%lu)\n",this,dwCopied); - return dwCopied + 1; - } - - *lpszPath = 0; - - while(pidlTemp->mkid.cb && (dwCopied < dwSize)) - { LPPIDLDATA pData = PidlMgr_GetDataPointer(this,pidlTemp); - - //if this item is a value, then skip it and finish - if(PT_VALUE == pData->type) - { break; - } - - strcat(lpszPath, pData->szText); - strcat(lpszPath, "\\"); - dwCopied += strlen(pData->szText) + 1; - pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); - - TRACE(shell,"-- (%p)->(size=%lu,%s)\n",this,dwCopied,lpszPath); - } - - //remove the last backslash if necessary - if(dwCopied) - { if(*(lpszPath + strlen(lpszPath) - 1) == '\\') - { *(lpszPath + strlen(lpszPath) - 1) = 0; - dwCopied--; - } - } - TRACE(shell,"-- (%p)->(path=%s)\n",this,lpszPath); - return dwCopied; -} - - -/************************************************************************** - * PidlMgr_GetValueText() - * Gets the text for the last item in the list - */ -DWORD PidlMgr_GetValueText(LPPIDLMGR this, - LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize) -{ LPITEMIDLIST pidlTemp=pidl; - CHAR szText[MAX_PATH]; - - TRACE(shell,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize); - - if(!pidl) - { return 0; - } - - while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp)) - { pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); - } - - if(!pidlTemp->mkid.cb) - { return 0; - } - - PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText)); - - if(!lpszValue) - { return strlen(szText) + 1; - } - strcpy(lpszValue, szText); - TRACE(shell,"-- (%p)->(pidl=%p %p=%s 0x%08lx)\n",this,pidl,lpszValue,lpszValue,dwSize); - return strlen(lpszValue); -} -/************************************************************************** - * PidlMgr_GetValueType() - */ -BOOL32 PidlMgr_GetValueType( LPPIDLMGR this, - LPCITEMIDLIST pidlPath, - LPCITEMIDLIST pidlValue, - LPDWORD pdwType) -{ LPSTR lpszFolder, - lpszValueName; - DWORD dwNameSize; - - FIXME(shell,"(%p)->(%p %p %p) stub\n",this,pidlPath,pidlValue,pdwType); - - if(!pidlPath) - { return FALSE; - } - - if(!pidlValue) - { return FALSE; - } - - if(!pdwType) - { return FALSE; - } - - //get the Desktop - //PidlMgr_GetDesktop(this,pidlPath); - - /* fixme: add the driveletter here*/ - - //assemble the Folder string - dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0); - lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); - if(!lpszFolder) - { return FALSE; - } - PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize); - - //assemble the value name - dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0); - lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); - if(!lpszValueName) - { HeapFree(GetProcessHeap(),0,lpszFolder); - return FALSE; - } - PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize); - - /* fixme: we've got the path now do something with it - -like get the filetype*/ - - pdwType=NULL; - - HeapFree(GetProcessHeap(),0,lpszFolder); - HeapFree(GetProcessHeap(),0,lpszValueName); - return TRUE; -} -/************************************************************************** - * PidlMgr_GetDataText() - */ -DWORD PidlMgr_GetDataText( LPPIDLMGR this, - LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize) -{ LPSTR lpszFolder, - lpszValueName; - DWORD dwNameSize; - - FIXME(shell,"(%p)->(pidl=%p pidl=%p) stub\n",this,pidlPath,pidlValue); - - if(!lpszOut || !pidlPath || !pidlValue) - { return FALSE; - } - - /* fixme: get the driveletter*/ - - //assemble the Folder string - dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0); - lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); - if(!lpszFolder) - { return FALSE; - } - PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize); - - //assemble the value name - dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0); - lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); - if(!lpszValueName) - { HeapFree(GetProcessHeap(),0,lpszFolder); - return FALSE; - } - PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize); - - /* fixme: we've got the path now do something with it*/ - - HeapFree(GetProcessHeap(),0,lpszFolder); - HeapFree(GetProcessHeap(),0,lpszValueName); - - TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,lpszOut,lpszOut,dwOutSize); - - return TRUE; -} - -/************************************************************************** - * CPidlMgr::GetPidlPath() - * Create a string that includes the Drive name, the folder text and - * the value text. - */ -DWORD PidlMgr_GetPidlPath(LPPIDLMGR this, - LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize) -{ LPSTR lpszTemp; - WORD len; - - TRACE(shell,"(%p)->(%p,%lu)\n",this,lpszOut,dwOutSize); - - if(!lpszOut) - { return 0; - } - - *lpszOut = 0; - lpszTemp = lpszOut; - - dwOutSize -= PidlMgr_GetFolderText(this,pidl, lpszTemp, dwOutSize); - - //add a backslash if necessary - len = strlen(lpszTemp); - if (len && lpszTemp[len-1]!='\\') - { lpszTemp[len+0]='\\'; - lpszTemp[len+1]='\0'; - dwOutSize--; - } - - lpszTemp = lpszOut + strlen(lpszOut); - - //add the value string - PidlMgr_GetValueText(this,pidl, lpszTemp, dwOutSize); - - //remove the last backslash if necessary - if(*(lpszOut + strlen(lpszOut) - 1) == '\\') - { *(lpszOut + strlen(lpszOut) - 1) = 0; - } - - TRACE(shell,"-- (%p)->(%p=%s,%lu)\n",this,lpszOut,lpszOut,dwOutSize); - - return strlen(lpszOut); - -} - -/************************************************************************** - * PidlMgr_Create() - * Creates a new PIDL - * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE - * pIn = data - * uInSize = size of data - */ - -LPITEMIDLIST PidlMgr_Create(LPPIDLMGR this,PIDLTYPE type, LPVOID pIn, UINT16 uInSize) -{ LPITEMIDLIST pidlOut=NULL; - UINT16 uSize; - LPITEMIDLIST pidlTemp=NULL; - LPPIDLDATA pData; - - TRACE(shell,"(%p)->(%x %p %x)\n",this,type,pIn,uInSize); - - if ( type == PT_DESKTOP) - { pidlOut = SHAlloc(2); - pidlOut->mkid.cb=0x0000; - return pidlOut; - } - - if (! pIn) - { return NULL; - } - - uSize = 2 + (sizeof(PIDLTYPE)) + uInSize + 2; /* cb + PIDLTYPE + uInSize +2 */ - pidlOut = SHAlloc(uSize); - pidlTemp = pidlOut; - if(pidlOut) - { pidlTemp->mkid.cb = uSize - 2; - pData =(LPPIDLDATA) &(pidlTemp->mkid.abID[0]); - pData->type = type; - switch(type) - { case PT_MYCOMP: - memcpy(pData->szText, pIn, uInSize); - TRACE(shell,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText)); - break; - case PT_DRIVE: - memcpy(pData->szText, pIn, uInSize); - TRACE(shell,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText)); - break; - case PT_FOLDER: - case PT_VALUE: - memcpy(pData->szText, pIn, uInSize); - TRACE(shell,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText)); - break; - default: - FIXME(shell,"- (%p) wrong argument\n",this); - break; - } - - pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); - pidlTemp->mkid.cb = 0x00; - } - TRACE(shell,"-- (%p)->(pidl=%p, size=%u)\n",this,pidlOut,uSize-2); - return pidlOut; -} -/************************************************************************** - * PidlMgr_GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16) - */ -DWORD PidlMgr_GetData( - LPPIDLMGR this, - PIDLTYPE type, - LPCITEMIDLIST pidl, - LPVOID pOut, - UINT16 uOutSize) -{ LPPIDLDATA pData; - DWORD dwReturn=0; - - TRACE(shell,"(%p)->(%x %p %p %x)\n",this,type,pidl,pOut,uOutSize); - - if(!pidl) - { return 0; - } - - pData = PidlMgr_GetDataPointer(this,pidl); - - //copy the data - switch(type) - { case PT_MYCOMP: if(uOutSize < 1) - return 0; - if(PT_MYCOMP != pData->type) - return 0; - *(LPSTR)pOut = 0; - strncpy((LPSTR)pOut, "My Computer", uOutSize); - dwReturn = strlen((LPSTR)pOut); - break; - - case PT_DRIVE: if(uOutSize < 1) - return 0; - if(PT_DRIVE != pData->type) - return 0; - *(LPSTR)pOut = 0; - strncpy((LPSTR)pOut, pData->szText, uOutSize); - dwReturn = strlen((LPSTR)pOut); - break; - - case PT_FOLDER: - case PT_VALUE: - case PT_TEXT: *(LPSTR)pOut = 0; - strncpy((LPSTR)pOut, pData->szText, uOutSize); - dwReturn = strlen((LPSTR)pOut); - break; - default: break; - } - TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,pOut,(char*)pOut,dwReturn); - return dwReturn; -} - - -/************************************************************************** - * PidlMgr_GetDataPointer() - */ -LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR this,LPITEMIDLIST pidl) -{ if(!pidl) - { return NULL; - } - TRACE (shell,"(%p)->(%p)\n" ,this, pidl); - return (LPPIDLDATA)(pidl->mkid.abID); -} - -/************************************************************************** - * CPidlMgr_SeparatePathAndValue) - * Creates a separate path and value PIDL from a fully qualified PIDL. - */ -BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR this, - LPITEMIDLIST pidlFQ, LPITEMIDLIST *ppidlPath, LPITEMIDLIST *ppidlValue) -{ LPITEMIDLIST pidlTemp; - TRACE (shell,"(%p)->(pidl=%p pidl=%p pidl=%p)",this,pidlFQ,ppidlPath,ppidlValue); - if(!pidlFQ) - { return FALSE; - } - - *ppidlValue = PidlMgr_GetLastItem(this,pidlFQ); - - if(!PidlMgr_IsValue(this,*ppidlValue)) - { return FALSE; - } - - *ppidlValue = ILClone(*ppidlValue); - *ppidlPath = ILClone(pidlFQ); - - pidlTemp = PidlMgr_GetLastItem(this,*ppidlPath); - pidlTemp->mkid.cb = 0x00; - - return TRUE; -} diff --git a/ole/nls/nor.nls b/ole/nls/nor.nls index 49256488553..f2355b14696 100644 --- a/ole/nls/nor.nls +++ b/ole/nls/nor.nls @@ -1,14 +1,14 @@ /* * OLE2NLS library - * Norway (Bokmael) + * Norway (Bokmaal) * (Norwegian strings in iso-8859-1) */ /* LOCVAL(LOCALE_ILANGUAGE,"") */ -LOCVAL(LOCALE_SLANGUAGE,"Norsk (Bokmæl)") -LOCVAL(LOCALE_SENGLANGUAGE,"Norwegian (Bokmael)") +LOCVAL(LOCALE_SLANGUAGE,"Norsk (Bokmål)") +LOCVAL(LOCALE_SENGLANGUAGE,"Norwegian (Bokmaal)") LOCVAL(LOCALE_SABBREVLANGNAME,"nor") -LOCVAL(LOCALE_SNATIVELANGNAME,"bokmæl") +LOCVAL(LOCALE_SNATIVELANGNAME,"bokmål") LOCVAL(LOCALE_ICOUNTRY,"47") LOCVAL(LOCALE_SCOUNTRY,"Norge") LOCVAL(LOCALE_SENGCOUNTRY,"Norway") diff --git a/ole/ole2.c b/ole/ole2.c index 5bfe3c764bc..228b01c4649 100644 --- a/ole/ole2.c +++ b/ole/ole2.c @@ -85,7 +85,7 @@ HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPVOID *pprot) { } /*********************************************************************** - * RegisterDragDrop (OLE2.35) + * RegisterDragDrop16 (OLE2.35) */ HRESULT WINAPI RegisterDragDrop16( HWND16 hwnd, @@ -95,3 +95,13 @@ HRESULT WINAPI RegisterDragDrop16( return S_OK; } +/*********************************************************************** + * RegisterDragDrop32 (OLE32.139) + */ +HRESULT WINAPI RegisterDragDrop32( + HWND32 hwnd, + LPDROPTARGET pDropTarget +) { + FIXME(ole,"(0x%04x,%p),stub!\n",hwnd,pDropTarget); + return S_OK; +} diff --git a/programs/Makefile.in b/programs/Makefile.in index aaf3c7c204a..686f5b34adc 100644 --- a/programs/Makefile.in +++ b/programs/Makefile.in @@ -18,6 +18,9 @@ depend: install: for i in $(SUBDIRS); do (cd $$i; $(MAKE) install) || exit 1; done +uninstall: + for i in $(SUBDIRS); do (cd $$i; $(MAKE) uninstall) || exit 1; done + clean: for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done diff --git a/programs/clock/Makefile.in b/programs/clock/Makefile.in index 6acd6a8308b..ad759a535c9 100644 --- a/programs/clock/Makefile.in +++ b/programs/clock/Makefile.in @@ -49,6 +49,9 @@ clock: $(MOSTOBJS) $(STRINGOBJS) install: dummy $(INSTALL_PROGRAM) clock $(bindir)/clock +uninstall: dummy + $(RM) $(bindir)/clock + $(RC_SRCS:.rc=.s): $(WRC) dummy: diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in index 46fed24780a..fe8193366a2 100644 --- a/programs/notepad/Makefile.in +++ b/programs/notepad/Makefile.in @@ -49,6 +49,9 @@ notepad: $(MOSTOBJS) $(STRINGOBJS) install: dummy $(INSTALL_PROGRAM) notepad $(bindir)/notepad +uninstall: dummy + $(RM) $(bindir)/notepad + $(RC_SRCS:.rc=.s): $(WRC) dummy: diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in index 0a6e2cdb9a8..6662fbd9c55 100644 --- a/programs/progman/Makefile.in +++ b/programs/progman/Makefile.in @@ -54,6 +54,9 @@ progman: $(MOSTOBJS) $(STRINGOBJS) install: dummy $(INSTALL_PROGRAM) progman $(bindir)/progman +uninstall: dummy + $(RM) $(bindir)/progman + $(RC_SRCS:.rc=.s): $(WRC) dummy: diff --git a/programs/regtest/Makefile.in b/programs/regtest/Makefile.in index 98683d476d0..a1a1e8dfdd8 100644 --- a/programs/regtest/Makefile.in +++ b/programs/regtest/Makefile.in @@ -19,7 +19,10 @@ regtest: $(OBJS) $(CC) -o regtest $(OBJS) $(LDOPTIONS) $(ALL_LIBS) install: dummy - $(INSTALL_PROGRAM) regtest $(bindir)/program + $(INSTALL_PROGRAM) regtest $(bindir)/regtest + +uninstall: dummy + $(RM) $(bindir)/regtest dummy: diff --git a/programs/view/Makefile.in b/programs/view/Makefile.in index 0aea7f6fab2..b531e803d02 100644 --- a/programs/view/Makefile.in +++ b/programs/view/Makefile.in @@ -37,6 +37,9 @@ view: $(OBJS) install: dummy $(INSTALL_PROGRAM) view $(bindir)/view +uninstall: dummy + $(RM) $(bindir)/view + $(RC_SRCS:.rc=.s): $(WRC) dummy: diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in index 76c40f00dd9..a95fa77bebc 100644 --- a/programs/winhelp/Makefile.in +++ b/programs/winhelp/Makefile.in @@ -53,6 +53,9 @@ install: dummy $(INSTALL_PROGRAM) winhelp $(bindir)/winhelp $(INSTALL_PROGRAM) hlp2sgml $(bindir)/hlp2sgml +uninstall: dummy + $(RM) $(bindir)/winhelp $(bindir)/hlp2sgml + y.tab.c y.tab.h: macro.yacc.y $(YACC) -d -t $(SRCDIR)/macro.yacc.y diff --git a/programs/winver/Makefile.in b/programs/winver/Makefile.in index ed5911b8f3e..60820046a7c 100644 --- a/programs/winver/Makefile.in +++ b/programs/winver/Makefile.in @@ -19,7 +19,10 @@ winver: $(OBJS) $(CC) -o winver $(OBJS) $(LDOPTIONS) $(ALL_LIBS) install: dummy - $(INSTALL_PROGRAM) winver $(bindir)/program + $(INSTALL_PROGRAM) winver $(bindir)/winver + +uninstall: dummy + $(RM) $(bindir)/winver dummy: diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 5ea46b43ca1..04c579e897e 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -385,7 +385,7 @@ void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr, int ordinal ) MSG( " (called from %p)", __builtin_return_address(1) ); #endif MSG( "\n" ); - TASK_KillCurrentTask(1); + ExitProcess(1); } diff --git a/relay32/comctl32.spec b/relay32/comctl32.spec index 8c7aa82cbef..c385cf69064 100644 --- a/relay32/comctl32.spec +++ b/relay32/comctl32.spec @@ -114,11 +114,11 @@ init ComCtl32LibMain 236 stub Str_SetPtrW 320 stdcall DSA_Create(long long) DSA_Create -321 stdcall DSA_Destroy(long) DSA_Destroy -322 stdcall DSA_GetItem(long long long) DSA_GetItem +321 stdcall DSA_Destroy(ptr) DSA_Destroy +322 stdcall DSA_GetItem(ptr long long) DSA_GetItem 323 stdcall DSA_GetItemPtr(long long) DSA_GetItemPtr 324 stdcall DSA_InsertItem(long long long) DSA_InsertItem -325 stub DSA_SetItem +325 stdcall DSA_SetItem (long long long) DSA_SetItem 326 stdcall DSA_DeleteItem(long long) DSA_DeleteItem 327 stub DSA_DeleteAllItems diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec index 087e09bf459..8f31000bcd5 100644 --- a/relay32/gdi32.spec +++ b/relay32/gdi32.spec @@ -166,7 +166,7 @@ type win32 162 stdcall GetClipBox(long ptr) GetClipBox32 163 stdcall GetClipRgn(long long) GetClipRgn32 164 stub GetColorAdjustment -165 stub GetColorSpace +165 stdcall GetColorSpace(long) GetColorSpace 166 stdcall GetCurrentObject(long long) GetCurrentObject 167 stdcall GetCurrentPositionEx(long ptr) GetCurrentPositionEx32 168 stdcall GetDCOrgEx(long ptr) GetDCOrgEx @@ -319,7 +319,7 @@ type win32 315 stdcall SetEnhMetaFileBits(long ptr) SetEnhMetaFileBits 316 stub SetFontEnumeration 317 stdcall SetGraphicsMode(long long) SetGraphicsMode -318 stub SetICMMode +318 stdcall SetICMMode(long long) SetICMMode 319 stub SetICMProfileA 320 stub SetICMProfileW 321 stdcall SetMapMode(long long) SetMapMode32 diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec index 85765770ff9..2c08e16912c 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -12,15 +12,15 @@ type win32 # - code generated by the MS Thunk Compiler # - symbols exported by the Oct 94 beta version of kernel32.dll - 1 stdcall VxDCall0(long) VxDCall - 2 stdcall VxDCall1(long) VxDCall - 3 stdcall VxDCall2(long) VxDCall - 4 stdcall VxDCall3(long) VxDCall - 5 stdcall VxDCall4(long) VxDCall - 6 stdcall VxDCall5(long) VxDCall - 7 stdcall VxDCall6(long) VxDCall - 8 stdcall VxDCall7(long) VxDCall - 9 stdcall VxDCall8(long) VxDCall + 1 register VxDCall0() VxDCall0 + 2 register VxDCall1() VxDCall1 + 3 register VxDCall2() VxDCall2 + 4 register VxDCall3() VxDCall3 + 5 register VxDCall4() VxDCall4 + 6 register VxDCall5() VxDCall5 + 7 register VxDCall6() VxDCall6 + 8 register VxDCall7() VxDCall7 + 9 register VxDCall8() VxDCall8 10 stdcall k32CharToOemA(str str) CharToOem32A 11 stdcall k32CharToOemBuffA(str str long) CharToOemBuff32A 12 stdcall k32OemToCharA(ptr ptr) OemToChar32A @@ -530,12 +530,12 @@ type win32 513 stub LockFileEx 514 stdcall LockResource(long) LockResource32 515 stdcall MakeCriticalSectionGlobal(ptr) MakeCriticalSectionGlobal -516 stub MapHInstLS +516 register MapHInstLS() MapHInstLS 517 stub MapHInstLS_PN -518 stub MapHInstSL +518 register MapHInstSL() MapHInstSL 519 stub MapHInstSL_PN -520 stub MapHModuleLS -521 stub MapHModuleSL +520 stdcall MapHModuleLS(long) MapHModuleLS +521 stdcall MapHModuleSL(long) MapHModuleSL 522 stdcall MapLS(ptr) MapLS 523 stdcall MapSL(long) MapSL 524 stdcall MapSLFix(long) MapSLFix @@ -698,7 +698,7 @@ type win32 681 stdcall SuspendThread(long) SuspendThread 682 stdcall SystemTimeToFileTime(ptr ptr) SystemTimeToFileTime 683 stub SystemTimeToTzSpecificLocalTime -684 stdcall TerminateProcess(ptr long) TerminateProcess +684 stdcall TerminateProcess(long long) TerminateProcess 685 stdcall TerminateThread(long long) TerminateThread 686 stub Thread32First 687 stub Thread32Next diff --git a/relay32/mpr.spec b/relay32/mpr.spec index d1768b51845..51d20e82b3c 100644 --- a/relay32/mpr.spec +++ b/relay32/mpr.spec @@ -86,7 +86,7 @@ type win32 0083 stub WNetGetResourceParentW 0084 stub WNetGetUniversalNameA 0085 stub WNetGetUniversalNameW -0086 stub WNetGetUserA +0086 stdcall WNetGetUserA(str ptr ptr) WNetGetUser32A 0087 stub WNetGetUserW 0088 stub WNetLogoffA 0089 stub WNetLogoffW diff --git a/relay32/ole32.spec b/relay32/ole32.spec index bb6197c51a5..4883fdbb4e0 100644 --- a/relay32/ole32.spec +++ b/relay32/ole32.spec @@ -139,7 +139,7 @@ type win32 136 stub ReadFmtUserTypeStg 137 stub ReadOleStg 138 stub ReadStringStream -139 stub RegisterDragDrop +139 stdcall RegisterDragDrop(long ptr) RegisterDragDrop32 140 stub ReleaseStgMedium 141 stub RevokeDragDrop 142 stub SetConvertStg diff --git a/relay32/shell32.spec b/relay32/shell32.spec index ecfefabeb6d..64e3546fc1a 100644 --- a/relay32/shell32.spec +++ b/relay32/shell32.spec @@ -22,7 +22,7 @@ init Shell32LibMain 14 stub Control_FillCache_RunDLLW@16 # exported by name 15 stdcall ILGetDisplayName(ptr ptr) ILGetDisplayName 16 stdcall ILFindLastID(ptr) ILFindLastID - 17 stub ILRemoveLastID@4 + 17 stdcall ILRemoveLastID@4(ptr) ILRemoveLastID 18 stdcall ILClone(ptr) ILClone 19 stub ILCloneFirst@4 20 stub ILGlobalClone@4 @@ -158,7 +158,7 @@ init Shell32LibMain 150 stub ExtractAssociatedIconExA # exported by name 151 stub SHLoadOLE 152 stdcall ILGetSize(ptr) ILGetSize - 153 stub ILGetNext + 153 stdcall ILGetNext(ptr) ILGetNext 154 stub ILAppend 155 stdcall ILFree(ptr) ILFree 156 stub ILGlobalFree @@ -297,8 +297,8 @@ init Shell32LibMain 288 stdcall ShellAboutA(long str str long) ShellAbout32A 289 stdcall ShellAboutW(long wstr wstr long) ShellAbout32W 290 stdcall ShellExecuteA(long str str str str long) ShellExecute32A - 291 stdcall ShellExecuteEx (long) ShellExecuteEx - 292 stub ShellExecuteExA + 291 stdcall ShellExecuteEx (long) ShellExecuteEx32A + 292 stdcall ShellExecuteExA (long) ShellExecuteEx32A 293 stub ShellExecuteExW 294 stub ShellExecuteW 295 stub ShellHookProc # exported by name @@ -373,3 +373,6 @@ init Shell32LibMain 680 stub IsUserAdmin 1217 stub FOOBAR1217 # no joke! This is the real name!! + +# later additions ... FIXME: incorrect ordinals +1218 stdcall SHGetSpecialFolderPathA(long long long long) SHGetSpecialFolderPath diff --git a/relay32/snoop.c b/relay32/snoop.c index 534607d5fa8..9bc4e38e0c8 100644 --- a/relay32/snoop.c +++ b/relay32/snoop.c @@ -4,7 +4,6 @@ * Copyright 1998 Marcus Meissner */ -#ifdef __i386__ #include #include "windows.h" @@ -19,6 +18,8 @@ #include "debugstr.h" #include "debug.h" +#ifdef __i386__ + char **debug_snoop_excludelist = NULL, **debug_snoop_includelist = NULL; #ifdef NEED_UNDERSCORE_PREFIX diff --git a/relay32/winmm.spec b/relay32/winmm.spec index 2ebbdd7ac7c..98d51cc97bc 100644 --- a/relay32/winmm.spec +++ b/relay32/winmm.spec @@ -5,7 +5,7 @@ type win32 2 stdcall WINMM_2(ptr long long) PlaySound32A 3 stub WINMM_3 4 stub CloseDriver - 5 stub DefDriverProc + 5 stdcall DefDriverProc(long long long long long) DefDriverProc 6 stub DriverCallback 7 stub DrvClose 8 stub DrvDefDriverProc @@ -19,7 +19,7 @@ type win32 16 stdcall OpenDriverA(str str long) OpenDriver32A 17 stdcall PlaySound(ptr long long) PlaySound32A 18 stdcall PlaySoundW(ptr long long) PlaySound32W - 19 stub SendDriverMessage + 19 stdcall SendDriverMessage(long long long long) SendDriverMessage32 20 stdcall auxGetDevCapsA(long ptr long) auxGetDevCaps32A 21 stdcall auxGetDevCapsW(long ptr long) auxGetDevCaps32W 22 stdcall auxGetNumDevs() auxGetNumDevs32 @@ -127,7 +127,7 @@ type win32 124 stdcall mmioRead(long ptr long) mmioRead32 125 stub mmioRenameA 126 stub mmioRenameW -127 stub mmioSeek +127 stdcall mmioSeek(long long long) mmioSeek32 128 stub mmioSendMessage 129 stub mmioSetBuffer 130 stub mmioSetInfo diff --git a/scheduler/client.c b/scheduler/client.c index 4a35bcfec98..e39d82d09ec 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -140,8 +140,9 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd, vec[0].iov_base = &head; vec[0].iov_len = sizeof(head); - if ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1) + while ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1) { + if (errno == EINTR) continue; perror("recvmsg"); CLIENT_ProtocolError( "recvmsg\n" ); } @@ -378,6 +379,7 @@ int CLIENT_DuplicateHandle( int src_process, int src_handle, int dst_process, in return reply.handle; } + /*********************************************************************** * CLIENT_GetProcessInfo * @@ -394,6 +396,22 @@ int CLIENT_GetProcessInfo( int handle, struct get_process_info_reply *reply ) } +/*********************************************************************** + * CLIENT_GetThreadInfo + * + * Send a get thread info request. Return 0 if OK. + */ +int CLIENT_GetThreadInfo( int handle, struct get_thread_info_reply *reply ) +{ + int len, err; + + CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &handle, sizeof(handle) ); + err = CLIENT_WaitReply( &len, NULL, 1, reply, sizeof(*reply) ); + CHECK_LEN( len, sizeof(*reply) ); + return err; +} + + /*********************************************************************** * CLIENT_OpenProcess * @@ -414,3 +432,26 @@ int CLIENT_OpenProcess( void *pid, DWORD access, BOOL32 inherit ) CHECK_LEN( len, sizeof(reply) ); return reply.handle; } + + +/*********************************************************************** + * CLIENT_Select + */ +int CLIENT_Select( int count, int *handles, int flags, int timeout ) +{ + struct select_request req; + struct select_reply reply; + int len; + + req.count = count; + req.flags = flags; + req.timeout = timeout; + + CLIENT_SendRequest( REQ_SELECT, -1, 2, + &req, sizeof(req), + handles, count * sizeof(int) ); + CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); + CHECK_LEN( len, sizeof(reply) ); + return reply.signaled; +} + diff --git a/scheduler/critsection.c b/scheduler/critsection.c index e154abe3a86..4cd478a24e3 100644 --- a/scheduler/critsection.c +++ b/scheduler/critsection.c @@ -156,7 +156,7 @@ void WINAPI EnterCriticalSection( CRITICAL_SECTION *crit ) struct sembuf sop; sop.sem_num = 0; sop.sem_op = -1; - sop.sem_flg = SEM_UNDO; + sop.sem_flg = 0/*SEM_UNDO*/; do { ret = semop( (int)crit->Reserved, &sop, 1 ); @@ -224,7 +224,7 @@ void WINAPI LeaveCriticalSection( CRITICAL_SECTION *crit ) struct sembuf sop; sop.sem_num = 0; sop.sem_op = 1; - sop.sem_flg = SEM_UNDO; + sop.sem_flg = 0/*SEM_UNDO*/; semop( (int)crit->Reserved, &sop, 1 ); } } diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c index 960e9622b97..aebca61c313 100644 --- a/scheduler/k32obj.c +++ b/scheduler/k32obj.c @@ -21,6 +21,7 @@ extern const K32OBJ_OPS THREAD_Ops; extern const K32OBJ_OPS FILE_Ops; extern const K32OBJ_OPS CHANGE_Ops; extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops; +extern const K32OBJ_OPS DEVICE_Ops; extern const K32OBJ_OPS CONSOLE_Ops; static const K32OBJ_OPS K32OBJ_NullOps = @@ -49,7 +50,7 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] = &K32OBJ_NullOps, /* K32OBJ_SCREEN_BUFFER */ &MEM_MAPPED_FILE_Ops, /* K32OBJ_MEM_MAPPED_FILE */ &K32OBJ_NullOps, /* K32OBJ_SERIAL */ - &K32OBJ_NullOps, /* K32OBJ_DEVICE_IOCTL */ + &DEVICE_Ops, /* K32OBJ_DEVICE_IOCTL */ &K32OBJ_NullOps, /* K32OBJ_PIPE */ &K32OBJ_NullOps, /* K32OBJ_MAILSLOT */ &K32OBJ_NullOps, /* K32OBJ_TOOLHELP_SNAPSHOT */ diff --git a/scheduler/process.c b/scheduler/process.c index 3ccd3d21461..3c1f94a8810 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -128,7 +128,8 @@ static BOOL32 PROCESS_BuildEnvDB( PDB32 *pdb ) /*********************************************************************** * PROCESS_InheritEnvDB */ -static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env ) +static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env, + STARTUPINFO32A *startup ) { if (!(pdb->env_db = HeapAlloc(pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB)))) return FALSE; @@ -143,10 +144,25 @@ static BOOL32 PROCESS_InheritEnvDB( PDB32 *pdb, LPCSTR cmd_line, LPCSTR env ) if (!(pdb->env_db->cmd_line = HEAP_strdupA( pdb->heap, 0, cmd_line ))) return FALSE; + /* Remember startup info */ + if (!(pdb->env_db->startup_info = + HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFO32A) ))) + return FALSE; + *pdb->env_db->startup_info = *startup; + /* Inherit the standard handles */ - pdb->env_db->hStdin = pdb->parent->env_db->hStdin; - pdb->env_db->hStdout = pdb->parent->env_db->hStdout; - pdb->env_db->hStderr = pdb->parent->env_db->hStderr; + if (pdb->env_db->startup_info->dwFlags & STARTF_USESTDHANDLES) + { + pdb->env_db->hStdin = pdb->env_db->startup_info->hStdInput; + pdb->env_db->hStdout = pdb->env_db->startup_info->hStdOutput; + pdb->env_db->hStderr = pdb->env_db->startup_info->hStdError; + } + else + { + pdb->env_db->hStdin = pdb->parent->env_db->hStdin; + pdb->env_db->hStdout = pdb->parent->env_db->hStdout; + pdb->env_db->hStderr = pdb->parent->env_db->hStderr; + } return TRUE; } @@ -249,13 +265,15 @@ BOOL32 PROCESS_Init(void) */ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, HINSTANCE16 hInstance, HINSTANCE16 hPrevInstance, - UINT32 cmdShow, PROCESS_INFORMATION *info ) + STARTUPINFO32A *startup, PROCESS_INFORMATION *info ) { DWORD size, commit; int server_thandle, server_phandle; + UINT32 cmdShow = 0; THDB *thdb = NULL; PDB32 *parent = PROCESS_Current(); PDB32 *pdb = PROCESS_CreatePDB( parent ); + TDB *pTask; if (!pdb) return NULL; info->hThread = info->hProcess = INVALID_HANDLE_VALUE32; @@ -278,7 +296,7 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, /* Inherit the env DB from the parent */ - if (!PROCESS_InheritEnvDB( pdb, cmd_line, env )) goto error; + if (!PROCESS_InheritEnvDB( pdb, cmd_line, env, startup )) goto error; /* Create the main thread */ @@ -295,12 +313,22 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, FALSE, server_phandle )) == INVALID_HANDLE_VALUE32) goto error; info->dwProcessId = PDB_TO_PROCESS_ID(pdb); - info->dwProcessId = THDB_TO_THREAD_ID(thdb); + info->dwThreadId = THDB_TO_THREAD_ID(thdb); +#if 0 thdb->unix_pid = getpid(); /* FIXME: wrong here ... */ +#else + /* All Win16 'threads' have the same unix_pid, no matter by which thread + they were created ! */ + pTask = (TDB *)GlobalLock16( parent->task ); + thdb->unix_pid = pTask? pTask->thdb->unix_pid : THREAD_Current()->unix_pid; +#endif /* Create a Win16 task for this process */ + if (startup->dwFlags & STARTF_USESHOWWINDOW) + cmdShow = startup->wShowWindow; + pdb->task = TASK_Create( thdb, pModule, hInstance, hPrevInstance, cmdShow); if (!pdb->task) goto error; @@ -386,6 +414,11 @@ static void PROCESS_Destroy( K32OBJ *ptr ) void WINAPI ExitProcess( DWORD status ) { PDB32 *pdb = PROCESS_Current(); + TDB *pTask = (TDB *)GlobalLock16( pdb->task ); + if ( pTask ) pTask->nEvents++; + + if ( pTask && pTask->thdb != THREAD_Current() ) + ExitThread( status ); SYSTEM_LOCK(); /* FIXME: should kill all running threads of this process */ @@ -399,6 +432,20 @@ void WINAPI ExitProcess( DWORD status ) } +/****************************************************************************** + * TerminateProcess (KERNEL32.684) + */ +BOOL32 WINAPI TerminateProcess( HANDLE32 handle, DWORD exit_code ) +{ + int server_handle; + BOOL32 ret; + PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_TERMINATE, &server_handle ); + if (!pdb) return FALSE; + ret = !CLIENT_TerminateProcess( server_handle, exit_code ); + K32OBJ_DecCount( &pdb->header ); + return ret; +} + /*********************************************************************** * GetCurrentProcess (KERNEL32.198) */ @@ -757,7 +804,7 @@ void PROCESS_SuspendOtherThreads(void) entry = pdb->thread_list->next; for (;;) { - if (entry->thread != THREAD_Current()) + if (entry->thread != THREAD_Current() && !THREAD_IsWin16(entry->thread)) { HANDLE32 handle = HANDLE_Alloc( PROCESS_Current(), &entry->thread->header, @@ -787,7 +834,7 @@ void PROCESS_ResumeOtherThreads(void) entry = pdb->thread_list->next; for (;;) { - if (entry->thread != THREAD_Current()) + if (entry->thread != THREAD_Current() && !THREAD_IsWin16(entry->thread)) { HANDLE32 handle = HANDLE_Alloc( PROCESS_Current(), &entry->thread->header, diff --git a/scheduler/synchro.c b/scheduler/synchro.c index 229134c9a48..4ed9a25e7bf 100644 --- a/scheduler/synchro.c +++ b/scheduler/synchro.c @@ -13,6 +13,7 @@ #include "process.h" #include "thread.h" #include "winerror.h" +#include "server.h" #include "debug.h" /*********************************************************************** @@ -25,15 +26,16 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, DWORD i; K32OBJ **ptr; + SYSTEM_LOCK(); wait->count = count; wait->signaled = WAIT_FAILED; wait->wait_all = wait_all; wait->wait_msg = wait_msg; - SYSTEM_LOCK(); for (i = 0, ptr = wait->objs; i < count; i++, ptr++) { if (!(*ptr = HANDLE_GetObjPtr( PROCESS_Current(), handles[i], - K32OBJ_UNKNOWN, SYNCHRONIZE, NULL ))) + K32OBJ_UNKNOWN, SYNCHRONIZE, + &wait->server[i] ))) { ERR(win32, "Bad handle %08x\n", handles[i]); break; @@ -251,7 +253,7 @@ void SYNC_WakeUp( THREAD_QUEUE *wait_queue, DWORD max ) THDB *thdb = entry->thread; if (SYNC_CheckCondition( &thdb->wait_struct, THDB_TO_THREAD_ID(thdb) )) { - TRACE(win32, "waking up %04x\n", thdb->teb_sel ); + TRACE(win32, "waking up %04x (pid %d)\n", thdb->teb_sel, thdb->unix_pid ); if (thdb->unix_pid) kill( thdb->unix_pid, SIGUSR1 ); else @@ -314,14 +316,50 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles, wait->signaled = WAIT_FAILED; else { - /* Now wait for it */ - SYNC_WaitForCondition( wait, timeout ); - SYNC_FreeWaitStruct( wait ); + int i; + /* Check if we can use a server wait */ + for (i = 0; i < count; i++) + if (wait->server[i] == -1) break; + if (i == count) + { + int flags = 0; + SYSTEM_UNLOCK(); + if (wait_all) flags |= SELECT_ALL; + if (alertable) flags |= SELECT_ALERTABLE; + if (wait_msg) flags |= SELECT_MSG; + if (timeout != INFINITE32) flags |= SELECT_TIMEOUT; + return CLIENT_Select( count, wait->server, flags, timeout ); + } + else + { + /* Now wait for it */ + SYNC_WaitForCondition( wait, timeout ); + SYNC_FreeWaitStruct( wait ); + } } SYSTEM_UNLOCK(); return wait->signaled; } +/*********************************************************************** + * Sleep (KERNEL32.679) + */ +VOID WINAPI Sleep( DWORD timeout ) +{ + SYNC_DoWait( 0, NULL, FALSE, timeout, FALSE, FALSE ); +} + +/****************************************************************************** + * SleepEx (KERNEL32.680) + */ +DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable ) +{ + DWORD ret = SYNC_DoWait( 0, NULL, FALSE, timeout, alertable, FALSE ); + if (ret != WAIT_IO_COMPLETION) ret = 0; + return ret; +} + + /*********************************************************************** * WaitForSingleObject (KERNEL32.723) */ diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c index d63d30f84f4..9ec3b7a9460 100644 --- a/scheduler/sysdeps.c +++ b/scheduler/sysdeps.c @@ -115,6 +115,8 @@ int SYSDEPS_SpawnThread( THDB *thread ) */ void SYSDEPS_ExitThread(void) { + THDB *thdb = THREAD_Current(); + close( thdb->socket ); _exit( 0 ); } diff --git a/scheduler/syslevel.c b/scheduler/syslevel.c index 50a5dd323c3..483dbb05ac4 100644 --- a/scheduler/syslevel.c +++ b/scheduler/syslevel.c @@ -13,6 +13,9 @@ static CRITICAL_SECTION Win16Mutex; static SEGPTR segpWin16Mutex; +/* Global variable to save current TEB while in 16-bit code */ +WORD SYSLEVEL_Win16CurrentTeb = 0; + /************************************************************************ * SYSLEVEL_Init @@ -49,6 +52,9 @@ SEGPTR WINAPI GetpWin16Lock16(void) VOID WINAPI _EnterSysLevel(CRITICAL_SECTION *lock) { EnterCriticalSection(lock); + + if (lock == &Win16Mutex) + GET_FS( SYSLEVEL_Win16CurrentTeb ); } /************************************************************************ diff --git a/scheduler/thread.c b/scheduler/thread.c index 2fabdbcce82..60365d529ad 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -9,6 +9,9 @@ #include #include "thread.h" #include "process.h" +#include "task.h" +#include "module.h" +#include "user.h" #include "winerror.h" #include "heap.h" #include "selectors.h" @@ -78,6 +81,20 @@ THDB *THREAD_Current(void) return (THDB *)((char *)NtCurrentTeb() - (int)&((THDB *)0)->teb); } +/*********************************************************************** + * THREAD_IsWin16 + */ +BOOL32 THREAD_IsWin16( THDB *thdb ) +{ + if (!thdb || !thdb->process) + return TRUE; + else + { + TDB* pTask = (TDB*)GlobalLock16( thdb->process->task ); + return !pTask || pTask->thdb == thdb; + } +} + /*********************************************************************** * THREAD_AddQueue @@ -688,7 +705,7 @@ BOOL32 WINAPI SetThreadPriority( /********************************************************************** - * TerminateThread [KERNEL32.???] Terminates a thread + * TerminateThread [KERNEL32.685] Terminates a thread * * RETURNS * Success: TRUE @@ -698,9 +715,15 @@ BOOL32 WINAPI TerminateThread( HANDLE32 handle, /* [in] Handle to thread */ DWORD exitcode) /* [in] Exit code for thread */ { - FIXME(thread,"(0x%08x,%ld): stub\n",handle,exitcode); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return TRUE; + int server_handle; + BOOL32 ret; + THDB *thread; + + if (!(thread = THREAD_GetPtr( handle, THREAD_TERMINATE, &server_handle ))) + return FALSE; + ret = !CLIENT_TerminateThread( server_handle, exitcode ); + K32OBJ_DecCount( &thread->header ); + return ret; } @@ -716,10 +739,17 @@ BOOL32 WINAPI GetExitCodeThread( LPDWORD exitcode) /* [out] Address to receive termination status */ { THDB *thread; - - if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, NULL ))) + int server_handle; + + if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, &server_handle ))) return FALSE; - if (exitcode) *exitcode = thread->exit_code; + if (server_handle != -1) + { + struct get_thread_info_reply info; + CLIENT_GetThreadInfo( server_handle, &info ); + if (exitcode) *exitcode = info.exit_code; + } + else if (exitcode) *exitcode = thread->exit_code; K32OBJ_DecCount( &thread->header ); return TRUE; } diff --git a/server/object.c b/server/object.c index 17a6843585b..c05a3104985 100644 --- a/server/object.c +++ b/server/object.c @@ -69,6 +69,8 @@ void init_object( struct object *obj, const struct object_ops *ops, { obj->refcount = 1; obj->ops = ops; + obj->head = NULL; + obj->tail = NULL; if (!name) obj->name = NULL; else obj->name = add_name( obj, name ); } @@ -89,6 +91,9 @@ void release_object( void *ptr ) assert( obj->refcount ); if (!--obj->refcount) { + /* if the refcount is 0, nobody can be in the wait queue */ + assert( !obj->head ); + assert( !obj->tail ); if (obj->name) free_name( obj ); obj->ops->destroy( obj ); } diff --git a/server/process.c b/server/process.c index b3adcb2bcc0..06d3d630087 100644 --- a/server/process.c +++ b/server/process.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -54,12 +55,17 @@ static struct process *first_process; /* process operations */ static void dump_process( struct object *obj, int verbose ); +static int process_signaled( struct object *obj, struct thread *thread ); +static int process_satisfied( struct object *obj, struct thread *thread ); static void destroy_process( struct object *obj ); static void free_handles( struct process *process ); +static int copy_handle_table( struct process *process, struct process *parent ); static const struct object_ops process_ops = { dump_process, + process_signaled, + process_satisfied, destroy_process }; @@ -67,10 +73,10 @@ static const struct object_ops process_ops = struct process *create_process(void) { struct process *process; - struct handle_entry *entries; if (!(process = malloc( sizeof(*process) ))) return NULL; - if (!(entries = malloc( MIN_HANDLE_ENTRIES * sizeof(struct handle_entry)))) + + if (!copy_handle_table( process, current ? current->process : NULL )) { free( process ); return NULL; @@ -81,14 +87,12 @@ struct process *create_process(void) process->thread_list = NULL; process->exit_code = 0x103; /* STILL_ACTIVE */ process->running_threads = 0; - process->handle_count = MIN_HANDLE_ENTRIES; - process->handle_last = -1; - process->entries = entries; if (first_process) first_process->prev = process; first_process = process; gettimeofday( &process->start_time, NULL ); + /* alloc a handle for the process itself */ alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 ); return process; } @@ -105,6 +109,7 @@ static void destroy_process( struct object *obj ) if (process->prev) process->prev->next = process->next; else first_process = process->next; free_handles( process ); + if (debug_level) memset( process, 0xbb, sizeof(process) ); /* catch errors */ free( process ); } @@ -117,6 +122,17 @@ static void dump_process( struct object *obj, int verbose ) printf( "Process next=%p prev=%p\n", process->next, process->prev ); } +static int process_signaled( struct object *obj, struct thread *thread ) +{ + struct process *process = (struct process *)obj; + return (process->running_threads > 0); +} + +static int process_satisfied( struct object *obj, struct thread *thread ) +{ + return 0; +} + /* get a process from an id (and increment the refcount) */ struct process *get_process_from_id( void *id ) { @@ -140,6 +156,7 @@ static void process_killed( struct process *process, int exit_code ) assert( !process->thread_list ); process->exit_code = exit_code; gettimeofday( &process->end_time, NULL ); + wake_up( &process->obj, 0 ); free_handles( process ); } @@ -308,6 +325,45 @@ static int shrink_handle_table( struct process *process ) return 1; } +/* copy the handle table of the parent process */ +/* return 1 if OK, 0 on error */ +static int copy_handle_table( struct process *process, struct process *parent ) +{ + struct handle_entry *ptr; + int i, count, last; + + if (!parent) /* first process */ + { + count = MIN_HANDLE_ENTRIES; + last = -1; + } + else + { + assert( parent->entries ); + count = parent->handle_count; + last = parent->handle_last; + } + + if (!(ptr = malloc( count * sizeof(struct handle_entry)))) return 0; + process->entries = ptr; + process->handle_count = count; + process->handle_last = last; + + if (last >= 0) + { + memcpy( ptr, parent->entries, (last + 1) * sizeof(struct handle_entry) ); + for (i = 0; i <= last; i++, ptr++) + { + if (!ptr->ptr) continue; + if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr ); + else ptr->ptr = NULL; /* don't inherit this entry */ + } + } + /* attempt to shrink the table */ + shrink_handle_table( process ); + return 1; +} + /* close a handle and decrement the refcount of the associated object */ /* return 1 if OK, 0 on error */ int close_handle( struct process *process, int handle ) @@ -390,7 +446,7 @@ void dump_handles( struct process *process ) if (!process->entries) return; entry = process->entries; - for (i = 0; i < process->handle_last; i++, entry++) + for (i = 0; i <= process->handle_last; i++, entry++) { if (!entry->ptr) continue; printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access ); diff --git a/server/request.c b/server/request.c index 397fe4fefd9..e481d760e20 100644 --- a/server/request.c +++ b/server/request.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ void call_timeout_handler( struct thread *thread ) current = thread; if (debug_level) trace_timeout(); CLEAR_ERROR(); - send_reply( current, -1, 0 ); + thread_timeout(); current = NULL; } @@ -131,6 +132,12 @@ DECL_HANDLER(new_thread) /* create a new thread */ DECL_HANDLER(init_thread) { + if (current->state != STARTING) + { + fatal_protocol_error( "init_thread: already running\n" ); + return; + } + current->state = RUNNING; current->unix_pid = req->unix_pid; if (!(current->name = malloc( len + 1 ))) { @@ -213,7 +220,21 @@ DECL_HANDLER(get_process_info) send_reply( current, -1, 1, &reply, sizeof(reply) ); } -/* open a handle a process */ +/* fetch information about a thread */ +DECL_HANDLER(get_thread_info) +{ + struct thread *thread; + struct get_thread_info_reply reply = { 0, 0 }; + + if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION ))) + { + get_thread_info( thread, &reply ); + release_object( thread ); + } + send_reply( current, -1, 1, &reply, sizeof(reply) ); +} + +/* open a handle to a process */ DECL_HANDLER(open_process) { struct open_process_reply reply = { -1 }; @@ -226,3 +247,12 @@ DECL_HANDLER(open_process) } send_reply( current, -1, 1, &reply, sizeof(reply) ); } + +/* select on a handle list */ +DECL_HANDLER(select) +{ + if (len != req->count * sizeof(int)) + fatal_protocol_error( "select: bad length %d for %d handles\n", + len, req->count ); + sleep_on( current, req->count, (int *)data, req->flags, req->timeout ); +} diff --git a/server/socket.c b/server/socket.c index 5d96a9354fe..fd857412704 100644 --- a/server/socket.c +++ b/server/socket.c @@ -165,9 +165,6 @@ static void do_read( int client_fd ) #endif int ret; - if (client->state == RUNNING) client->state = SENDING; - assert( client->state == SENDING ); - if (client->count < sizeof(client->head)) { vec.iov_base = (char *)&client->head + client->count; @@ -207,6 +204,9 @@ static void do_read( int client_fd ) return; } + if (client->state == RUNNING) client->state = SENDING; + assert( client->state == SENDING ); + client->count += ret; /* received the complete header yet? */ diff --git a/server/thread.c b/server/thread.c index 206e1a9507a..e250cc87328 100644 --- a/server/thread.c +++ b/server/thread.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -19,14 +20,37 @@ #include "server/thread.h" +/* thread queues */ + +struct wait_queue_entry +{ + struct wait_queue_entry *next; + struct wait_queue_entry *prev; + struct object *obj; + struct thread *thread; +}; + +struct thread_wait +{ + int count; /* count of objects */ + int flags; + struct timeval timeout; + struct wait_queue_entry queues[1]; +}; + + /* thread operations */ static void dump_thread( struct object *obj, int verbose ); +static int thread_signaled( struct object *obj, struct thread *thread ); +static int thread_satisfied( struct object *obj, struct thread *thread ); static void destroy_thread( struct object *obj ); static const struct object_ops thread_ops = { dump_thread, + thread_signaled, + thread_satisfied, destroy_thread }; @@ -55,7 +79,9 @@ struct thread *create_thread( int fd, void *pid, int *thread_handle, thread->process = process; thread->unix_pid = 0; /* not known yet */ thread->name = NULL; + thread->wait = NULL; thread->error = 0; + thread->state = STARTING; thread->exit_code = 0x103; /* STILL_ACTIVE */ thread->next = first_thread; thread->prev = NULL; @@ -104,6 +130,7 @@ static void destroy_thread( struct object *obj ) if (thread->prev) thread->prev->next = thread->next; else first_thread = thread->next; if (thread->name) free( thread->name ); + if (debug_level) memset( thread, 0xaa, sizeof(thread) ); /* catch errors */ free( thread ); } @@ -117,6 +144,17 @@ static void dump_thread( struct object *obj, int verbose ) thread->unix_pid, thread->client_fd, thread->name ); } +static int thread_signaled( struct object *obj, struct thread *thread ) +{ + struct thread *mythread = (struct thread *)obj; + return (mythread->state == TERMINATED); +} + +static int thread_satisfied( struct object *obj, struct thread *thread ) +{ + return 0; +} + /* get a thread pointer from a thread id (and increment the refcount) */ struct thread *get_thread_from_id( void *id ) { @@ -133,6 +171,14 @@ struct thread *get_thread_from_handle( int handle, unsigned int access ) access, &thread_ops ); } +/* get all information about a thread */ +void get_thread_info( struct thread *thread, + struct get_thread_info_reply *reply ) +{ + reply->pid = thread; + reply->exit_code = thread->exit_code; +} + /* send a reply to a thread */ int send_reply( struct thread *thread, int pass_fd, int n, ... /* arg_1, len_1, ..., arg_n, len_n */ ) @@ -152,6 +198,201 @@ int send_reply( struct thread *thread, int pass_fd, int n, return send_reply_v( thread->client_fd, thread->error, pass_fd, vec, n ); } +/* add a thread to an object wait queue; return 1 if OK, 0 on error */ +static void add_queue( struct object *obj, struct wait_queue_entry *entry ) +{ + entry->obj = obj; + entry->prev = obj->tail; + entry->next = NULL; + if (obj->tail) obj->tail->next = entry; + else obj->head = entry; + obj->tail = entry; +} + +/* remove a thread from an object wait queue */ +static void remove_queue( struct wait_queue_entry *entry ) +{ + struct object *obj = entry->obj; + + if (entry->next) entry->next->prev = entry->prev; + else obj->tail = entry->prev; + if (entry->prev) entry->prev->next = entry->next; + else obj->head = entry->next; + release_object( obj ); +} + +/* finish waiting */ +static void end_wait( struct thread *thread ) +{ + struct thread_wait *wait = thread->wait; + struct wait_queue_entry *entry; + int i; + + assert( wait ); + for (i = 0, entry = wait->queues; i < wait->count; i++) + remove_queue( entry++ ); + if (wait->flags & SELECT_TIMEOUT) set_timeout( thread->client_fd, NULL ); + free( wait ); + thread->wait = NULL; +} + +/* build the thread wait structure */ +static int wait_on( struct thread *thread, int count, + int *handles, int flags, int timeout ) +{ + struct thread_wait *wait; + struct wait_queue_entry *entry; + struct object *obj; + int i; + + if ((count < 0) || (count > MAXIMUM_WAIT_OBJECTS)) + { + SET_ERROR( ERROR_INVALID_PARAMETER ); + return 0; + } + if (!(wait = malloc( sizeof(*wait) + (count-1) * sizeof(*entry) ))) + { + SET_ERROR( ERROR_OUTOFMEMORY ); + return 0; + } + thread->wait = wait; + wait->count = count; + wait->flags = flags; + if (flags & SELECT_TIMEOUT) + { + gettimeofday( &wait->timeout, 0 ); + if (timeout) + { + wait->timeout.tv_usec += (timeout % 1000) * 1000; + if (wait->timeout.tv_usec >= 1000000) + { + wait->timeout.tv_usec -= 1000000; + wait->timeout.tv_sec++; + } + wait->timeout.tv_sec += timeout / 1000; + } + } + + for (i = 0, entry = wait->queues; i < count; i++, entry++) + { + if (!(obj = get_handle_obj( thread->process, handles[i], + SYNCHRONIZE, NULL ))) + { + wait->count = i - 1; + end_wait( thread ); + return 0; + } + entry->thread = thread; + add_queue( obj, entry ); + } + return 1; +} + +/* check if the thread waiting condition is satisfied */ +static int check_wait( struct thread *thread, int *signaled ) +{ + int i; + struct thread_wait *wait = thread->wait; + struct wait_queue_entry *entry = wait->queues; + struct timeval now; + + assert( wait ); + if (wait->flags & SELECT_ALL) + { + for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) + if (!entry->obj->ops->signaled( entry->obj, thread )) goto check_timeout; + /* Wait satisfied: tell it to all objects */ + *signaled = 0; + for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) + if (entry->obj->ops->satisfied( entry->obj, thread )) + *signaled = STATUS_ABANDONED_WAIT_0; + return 1; + } + else + { + for (i = 0, entry = wait->queues; i < wait->count; i++, entry++) + { + if (!entry->obj->ops->signaled( entry->obj, thread )) continue; + /* Wait satisfied: tell it to the object */ + *signaled = i; + if (entry->obj->ops->satisfied( entry->obj, thread )) + *signaled += STATUS_ABANDONED_WAIT_0; + return 1; + } + } + check_timeout: + if (!(wait->flags & SELECT_TIMEOUT)) return 0; + gettimeofday( &now, NULL ); + if ((now.tv_sec > wait->timeout.tv_sec) || + ((now.tv_sec == wait->timeout.tv_sec) && + (now.tv_usec >= wait->timeout.tv_usec))) + { + *signaled = STATUS_TIMEOUT; + return 1; + } + return 0; +} + +/* sleep on a list of objects */ +void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout ) +{ + struct select_reply reply; + + assert( !thread->wait ); + reply.signaled = -1; + if (!wait_on( thread, count, handles, flags, timeout )) goto done; + if (!check_wait( thread, &reply.signaled )) + { + /* we need to wait */ + if (flags & SELECT_TIMEOUT) + set_timeout( thread->client_fd, &thread->wait->timeout ); + return; + } + end_wait( thread ); + done: + send_reply( thread, -1, 1, &reply, sizeof(reply) ); +} + +/* attempt to wake up a thread */ +/* return 1 if OK, 0 if the wait condition is still not satisfied */ +static int wake_thread( struct thread *thread ) +{ + struct select_reply reply; + + if (!check_wait( thread, &reply.signaled )) return 0; + end_wait( thread ); + send_reply( thread, -1, 1, &reply, sizeof(reply) ); + return 1; +} + +/* timeout for the current thread */ +void thread_timeout(void) +{ + struct select_reply reply; + + assert( current->wait ); + + reply.signaled = STATUS_TIMEOUT; + end_wait( current ); + send_reply( current, -1, 1, &reply, sizeof(reply) ); +} + +/* attempt to wake threads sleeping on the object wait queue */ +void wake_up( struct object *obj, int max ) +{ + struct wait_queue_entry *entry = obj->head; + + while (entry) + { + struct wait_queue_entry *next = entry->next; + if (wake_thread( entry->thread )) + { + if (max && !--max) break; + } + entry = next; + } +} + /* kill a thread on the spot */ void kill_thread( struct thread *thread, int exit_code ) { @@ -162,7 +403,10 @@ void kill_thread( struct thread *thread, int exit_code ) /* a thread has been killed */ void thread_killed( struct thread *thread, int exit_code ) { + thread->state = TERMINATED; thread->exit_code = exit_code; + if (thread->wait) end_wait( thread ); remove_process_thread( thread->process, thread ); + wake_up( &thread->obj, 0 ); release_object( thread ); } diff --git a/server/trace.c b/server/trace.c index 712edeac516..a9158ce884c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1,6 +1,7 @@ /* File generated automatically by tools/make_requests; DO NOT EDIT!! */ #include +#include #include #include "server.h" #include "server/thread.h" @@ -46,6 +47,17 @@ static void dump_get_process_info_reply( struct get_process_info_reply *req ) printf( " exit_code=%d", req->exit_code ); } +static void dump_get_thread_info_request( struct get_thread_info_request *req ) +{ + printf( " handle=%d", req->handle ); +} + +static void dump_get_thread_info_reply( struct get_thread_info_reply *req ) +{ + printf( " pid=%p,", req->pid ); + printf( " exit_code=%d", req->exit_code ); +} + static void dump_close_handle_request( struct close_handle_request *req ) { printf( " handle=%d", req->handle ); @@ -79,6 +91,18 @@ static void dump_open_process_reply( struct open_process_reply *req ) printf( " handle=%d", req->handle ); } +static void dump_select_request( struct select_request *req ) +{ + printf( " count=%d,", req->count ); + printf( " flags=%d,", req->flags ); + printf( " timeout=%d", req->timeout ); +} + +static void dump_select_reply( struct select_reply *req ) +{ + printf( " signaled=%d", req->signaled ); +} + struct dumper { void (*dump_req)(); @@ -103,6 +127,9 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] = { (void(*)())dump_get_process_info_request, (void(*)())dump_get_process_info_reply, sizeof(struct get_process_info_request) }, + { (void(*)())dump_get_thread_info_request, + (void(*)())dump_get_thread_info_reply, + sizeof(struct get_thread_info_request) }, { (void(*)())dump_close_handle_request, (void(*)())0, sizeof(struct close_handle_request) }, @@ -112,6 +139,9 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] = { (void(*)())dump_open_process_request, (void(*)())dump_open_process_reply, sizeof(struct open_process_request) }, + { (void(*)())dump_select_request, + (void(*)())dump_select_reply, + sizeof(struct select_request) }, }; static const char * const req_names[REQ_NB_REQUESTS] = @@ -121,9 +151,11 @@ static const char * const req_names[REQ_NB_REQUESTS] = "terminate_process", "terminate_thread", "get_process_info", + "get_thread_info", "close_handle", "dup_handle", "open_process", + "select", }; void trace_request( enum request req, void *data, int len, int fd ) diff --git a/tools/build.c b/tools/build.c index 76d8b7e1f12..bd7f1e9103f 100644 --- a/tools/build.c +++ b/tools/build.c @@ -1630,7 +1630,7 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) #endif fprintf( outfile, "\tmovw %%bx,%%es\n" ); - fprintf( outfile, "\tmovw " PREFIX "CALLTO16_Current_fs,%%fs\n" ); + fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" ); /* Get the 32-bit stack pointer from the TEB */ @@ -1747,7 +1747,6 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2 ); fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET ); fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET ); - fprintf( outfile, "\tmovw %%fs," PREFIX "CALLTO16_Current_fs\n" ); if (reg_func) { @@ -1948,12 +1947,11 @@ static void BuildCallTo16Func( FILE *outfile, char *profile ) fprintf( outfile, "do_callto16_%s:\n", profile ); - /* Save the 32-bit stack and %fs */ + /* Save the 32-bit stack */ fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET ); fprintf( outfile, "\tmovl %%ebp,%%ebx\n" ); fprintf( outfile, "\tmovl %%esp,%%edx\n" ); - fprintf( outfile, "\tmovw %%fs," PREFIX "CALLTO16_Current_fs\n" ); if (reg_func) { @@ -2106,7 +2104,7 @@ static void BuildRet16Func( FILE *outfile ) #endif fprintf( outfile, "\tmovw %%bx,%%es\n" ); - fprintf( outfile, "\tmovw " PREFIX "CALLTO16_Current_fs,%%fs\n" ); + fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" ); /* Restore the 32-bit stack */ diff --git a/tools/make_requests b/tools/make_requests index 1cba5803e07..f02bd43f604 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -1,4 +1,4 @@ -#! /usr/bin/perl +#! /usr/bin/perl -w # # Build the server/trace.c and include/server/request.h files # from the contents of include/server.h. @@ -26,6 +26,7 @@ print TRACE < +#include #include #include "server.h" #include "server/thread.h" @@ -194,6 +195,7 @@ sub DO_REQUEST last if /^};$/; next if /^{$/; s!/\*.*\*/!!g; + next if /^\s*$/; / *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_"; my $type = $1; my $var = $3; @@ -215,6 +217,7 @@ sub DO_REPLY last if /^};$/; next if /^{$/; s!/\*.*\*/!!g; + next if /^\s*$/; / *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_"; my $type = $1; my $var = $3; @@ -238,7 +241,6 @@ sub DO_DUMP_FUNC print TRACE " printf( \" $var=$formats{$type}"; print TRACE "," if ($#_ > 0); print TRACE "\", req->$var );\n"; - $size .= "+sizeof($type)"; } print TRACE "}\n"; } diff --git a/tools/testrun b/tools/testrun index 499e1349be3..6508c0101a4 100755 --- a/tools/testrun +++ b/tools/testrun @@ -223,31 +223,6 @@ while ($exe=) { #print "skipping $exe, already done.\n"; next; } - - # check runfile if the exe is a DOS executeable or - # of different architecture (win32) - if (open(RUNFILE,"runs/$runfile.out")) { - while ($xrun=) { - chop($xrun); - if ($xrun=~ /LoadModule:.*error=11$/) { - $flag=1; - last; - } - if ($xrun=~ /LoadModule:.*error=21$/) { - $flag=2; - last; - } - } - close(RUNFILE); - if ($flag==1) { - #print "skipping $exe, seems to be a DOS executable.\n"; - next; - } - if ($flag==2) { - #print "skipping $exe, seems to be a non i386 executable.\n"; - next; - } - } # now testrun... print "$exe:\n"; $dir = $exe; diff --git a/win32/device.c b/win32/device.c index 7574bb5403a..9ce240e09c8 100644 --- a/win32/device.c +++ b/win32/device.c @@ -2,6 +2,8 @@ * Win32 device functions * * Copyright 1998 Marcus Meissner + * Copyright 1998 Ulrich Weigand + * */ #include @@ -23,8 +25,9 @@ #include "heap.h" #include "debug.h" #include "winioctl.h" +#include "stackframe.h" -void DEVICE_Destroy(K32OBJ *dev); +static void DEVICE_Destroy(K32OBJ *dev); const K32OBJ_OPS DEVICE_Ops = { NULL, /* signaled */ @@ -40,22 +43,240 @@ const K32OBJ_OPS DEVICE_Ops = typedef struct { K32OBJ header; - int mode; + + struct VxDInfo *info; char *devname; + int mode; + } DEVICE_OBJECT; -HANDLE32 -DEVICE_Open(LPCSTR filename, DWORD access) { - DEVICE_OBJECT *dev; - HANDLE32 handle; - dev = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) ); - if (!dev) - return INVALID_HANDLE_VALUE32; +static BOOL32 DeviceIo_VTDAPI(DEVICE_OBJECT *dev, DWORD dwIoControlCode, + LPVOID lpvInBuffer, DWORD cbInBuffer, + LPVOID lpvOutBuffer, DWORD cbOutBuffer, + LPDWORD lpcbBytesReturned, + LPOVERLAPPED lpOverlapped); + +static BOOL32 VxDCall_VMM( DWORD *retv, DWORD service, CONTEXT *context ); + +/* + * VxD names are taken from the Win95 DDK + */ + +struct VxDInfo +{ + LPCSTR name; + WORD id; + BOOL32 (*vxdcall)(DWORD *, DWORD, CONTEXT *); + BOOL32 (*deviceio)(DEVICE_OBJECT *, DWORD, LPVOID, DWORD, + LPVOID, DWORD, LPDWORD, LPOVERLAPPED); +} + VxDList[] = +{ + /* Standard VxD IDs */ + { "VMM", 0x0001, VxDCall_VMM, NULL }, + { "DEBUG", 0x0002, NULL, NULL }, + { "VPICD", 0x0003, NULL, NULL }, + { "VDMAD", 0x0004, NULL, NULL }, + { "VTD", 0x0005, NULL, NULL }, + { "V86MMGR", 0x0006, NULL, NULL }, + { "PAGESWAP", 0x0007, NULL, NULL }, + { "PARITY", 0x0008, NULL, NULL }, + { "REBOOT", 0x0009, NULL, NULL }, + { "VDD", 0x000A, NULL, NULL }, + { "VSD", 0x000B, NULL, NULL }, + { "VMD", 0x000C, NULL, NULL }, + { "VKD", 0x000D, NULL, NULL }, + { "VCD", 0x000E, NULL, NULL }, + { "VPD", 0x000F, NULL, NULL }, + { "BLOCKDEV", 0x0010, NULL, NULL }, + { "VMCPD", 0x0011, NULL, NULL }, + { "EBIOS", 0x0012, NULL, NULL }, + { "BIOSXLAT", 0x0013, NULL, NULL }, + { "VNETBIOS", 0x0014, NULL, NULL }, + { "DOSMGR", 0x0015, NULL, NULL }, + { "WINLOAD", 0x0016, NULL, NULL }, + { "SHELL", 0x0017, NULL, NULL }, + { "VMPOLL", 0x0018, NULL, NULL }, + { "VPROD", 0x0019, NULL, NULL }, + { "DOSNET", 0x001A, NULL, NULL }, + { "VFD", 0x001B, NULL, NULL }, + { "VDD2", 0x001C, NULL, NULL }, + { "WINDEBUG", 0x001D, NULL, NULL }, + { "TSRLOAD", 0x001E, NULL, NULL }, + { "BIOSHOOK", 0x001F, NULL, NULL }, + { "INT13", 0x0020, NULL, NULL }, + { "PAGEFILE", 0x0021, NULL, NULL }, + { "SCSI", 0x0022, NULL, NULL }, + { "MCA_POS", 0x0023, NULL, NULL }, + { "SCSIFD", 0x0024, NULL, NULL }, + { "VPEND", 0x0025, NULL, NULL }, + { "VPOWERD", 0x0026, NULL, NULL }, + { "VXDLDR", 0x0027, NULL, NULL }, + { "NDIS", 0x0028, NULL, NULL }, + { "BIOS_EXT", 0x0029, NULL, NULL }, + { "VWIN32", 0x002A, NULL, NULL }, + { "VCOMM", 0x002B, NULL, NULL }, + { "SPOOLER", 0x002C, NULL, NULL }, + { "WIN32S", 0x002D, NULL, NULL }, + { "DEBUGCMD", 0x002E, NULL, NULL }, + + { "VNB", 0x0031, NULL, NULL }, + { "SERVER", 0x0032, NULL, NULL }, + { "CONFIGMG", 0x0033, NULL, NULL }, + { "DWCFGMG", 0x0034, NULL, NULL }, + { "SCSIPORT", 0x0035, NULL, NULL }, + { "VFBACKUP", 0x0036, NULL, NULL }, + { "ENABLE", 0x0037, NULL, NULL }, + { "VCOND", 0x0038, NULL, NULL }, + + { "EFAX", 0x003A, NULL, NULL }, + { "DSVXD", 0x003B, NULL, NULL }, + { "ISAPNP", 0x003C, NULL, NULL }, + { "BIOS", 0x003D, NULL, NULL }, + { "WINSOCK", 0x003E, NULL, NULL }, + { "WSOCK", 0x003E, NULL, NULL }, + { "WSIPX", 0x003F, NULL, NULL }, + { "IFSMgr", 0x0040, NULL, NULL }, + { "VCDFSD", 0x0041, NULL, NULL }, + { "MRCI2", 0x0042, NULL, NULL }, + { "PCI", 0x0043, NULL, NULL }, + { "PELOADER", 0x0044, NULL, NULL }, + { "EISA", 0x0045, NULL, NULL }, + { "DRAGCLI", 0x0046, NULL, NULL }, + { "DRAGSRV", 0x0047, NULL, NULL }, + { "PERF", 0x0048, NULL, NULL }, + { "AWREDIR", 0x0049, NULL, NULL }, + + /* Far East support */ + { "ETEN", 0x0060, NULL, NULL }, + { "CHBIOS", 0x0061, NULL, NULL }, + { "VMSGD", 0x0062, NULL, NULL }, + { "VPPID", 0x0063, NULL, NULL }, + { "VIME", 0x0064, NULL, NULL }, + { "VHBIOSD", 0x0065, NULL, NULL }, + + /* Multimedia OEM IDs */ + { "VTDAPI", 0x0442, NULL, DeviceIo_VTDAPI }, + + /* Network Device IDs */ + { "VNetSup", 0x0480, NULL, NULL }, + { "VRedir", 0x0481, NULL, NULL }, + { "VBrowse", 0x0482, NULL, NULL }, + { "VSHARE", 0x0483, NULL, NULL }, + { "IFSMgr", 0x0484, NULL, NULL }, + { "MEMPROBE", 0x0485, NULL, NULL }, + { "VFAT", 0x0486, NULL, NULL }, + { "NWLINK", 0x0487, NULL, NULL }, + { "VNWLINK", 0x0487, NULL, NULL }, + { "NWSUP", 0x0487, NULL, NULL }, + { "VTDI", 0x0488, NULL, NULL }, + { "VIP", 0x0489, NULL, NULL }, + { "VTCP", 0x048A, NULL, NULL }, + { "VCache", 0x048B, NULL, NULL }, + { "VUDP", 0x048C, NULL, NULL }, + { "VAsync", 0x048D, NULL, NULL }, + { "NWREDIR", 0x048E, NULL, NULL }, + { "STAT80", 0x048F, NULL, NULL }, + { "SCSIPORT", 0x0490, NULL, NULL }, + { "FILESEC", 0x0491, NULL, NULL }, + { "NWSERVER", 0x0492, NULL, NULL }, + { "SECPROV", 0x0493, NULL, NULL }, + { "NSCL", 0x0494, NULL, NULL }, + { "WSTCP", 0x0495, NULL, NULL }, + { "NDIS2SUP", 0x0496, NULL, NULL }, + { "MSODISUP", 0x0497, NULL, NULL }, + { "Splitter", 0x0498, NULL, NULL }, + { "PPP", 0x0499, NULL, NULL }, + { "VDHCP", 0x049A, NULL, NULL }, + { "VNBT", 0x049B, NULL, NULL }, + { "LOGGER", 0x049D, NULL, NULL }, + { "EFILTER", 0x049E, NULL, NULL }, + { "FFILTER", 0x049F, NULL, NULL }, + { "TFILTER", 0x04A0, NULL, NULL }, + { "AFILTER", 0x04A1, NULL, NULL }, + { "IRLAMP", 0x04A2, NULL, NULL }, + + { NULL, 0, NULL, NULL } +}; + +/* + * VMM VxDCall service names are (mostly) taken from Stan Mitchell's + * "Inside the Windows 95 File System" + */ + +#define N_VMM_SERVICE 41 + +LPCSTR VMM_Service_Name[N_VMM_SERVICE] = +{ + "PageReserve", /* 0x0000 */ + "PageCommit", /* 0x0001 */ + "PageDecommit", /* 0x0002 */ + "PagerRegister", /* 0x0003 */ + "PagerQuery", /* 0x0004 */ + "HeapAllocate", /* 0x0005 */ + "ContextCreate", /* 0x0006 */ + "ContextDestroy", /* 0x0007 */ + "PageAttach", /* 0x0008 */ + "PageFlush", /* 0x0009 */ + "PageFree", /* 0x000A */ + "ContextSwitch", /* 0x000B */ + "HeapReAllocate", /* 0x000C */ + "PageModifyPerm", /* 0x000D */ + "PageQuery", /* 0x000E */ + "GetCurrentContext", /* 0x000F */ + "HeapFree", /* 0x0010 */ + "RegOpenKey", /* 0x0011 */ + "RegCreateKey", /* 0x0012 */ + "RegCloseKey", /* 0x0013 */ + "RegDeleteKey", /* 0x0014 */ + "RegSetValue", /* 0x0015 */ + "RegDeleteValue", /* 0x0016 */ + "RegQueryValue", /* 0x0017 */ + "RegEnumKey", /* 0x0018 */ + "RegEnumValue", /* 0x0019 */ + "RegQueryValueEx", /* 0x001A */ + "RegSetValueEx", /* 0x001B */ + "RegFlushKey", /* 0x001C */ + "RegQueryInfoKey", /* 0x001D */ + "GetDemandPageInfo", /* 0x001E */ + "BlockOnID", /* 0x001F */ + "SignalID", /* 0x0020 */ + "RegLoadKey", /* 0x0021 */ + "RegUnLoadKey", /* 0x0022 */ + "RegSaveKey", /* 0x0023 */ + "RegRemapPreDefKey", /* 0x0024 */ + "PageChangePager", /* 0x0025 */ + "RegQueryMultipleValues", /* 0x0026 */ + "RegReplaceKey", /* 0x0027 */ + "" /* 0x0028 -- What does this do??? */ +}; + + + +HANDLE32 DEVICE_Open(LPCSTR filename, DWORD access) +{ + DEVICE_OBJECT *dev; + HANDLE32 handle; + int i; + + dev = HeapAlloc( SystemHeap, 0, sizeof(DEVICE_OBJECT) ); + if (!dev) return INVALID_HANDLE_VALUE32; + dev->header.type = K32OBJ_DEVICE_IOCTL; - dev->header.refcount = 0; + dev->header.refcount = 1; dev->mode = access; dev->devname = HEAP_strdupA(SystemHeap,0,filename); + dev->info = NULL; + + for (i = 0; VxDList[i].name; i++) + if (!lstrcmpi32A(VxDList[i].name, filename)) + break; + if (VxDList[i].name) + dev->info = VxDList + i; + else + FIXME(win32, "Unknown VxD %s\n", filename); + handle = HANDLE_Alloc( PROCESS_Current(), &(dev->header), FILE_ALL_ACCESS | GENERIC_READ | @@ -65,9 +286,19 @@ DEVICE_Open(LPCSTR filename, DWORD access) { return handle; } -void -DEVICE_Destroy(K32OBJ *dev) { - assert(dev->type == K32OBJ_DEVICE_IOCTL); +static void DEVICE_Destroy(K32OBJ *obj) +{ + DEVICE_OBJECT *dev = (DEVICE_OBJECT *)obj; + assert( obj->type == K32OBJ_DEVICE_IOCTL ); + + if ( dev->devname ) + { + HeapFree( SystemHeap, 0, dev->devname ); + dev->devname = NULL; + } + + obj->type = K32OBJ_UNKNOWN; + HeapFree( SystemHeap, 0, dev ); } /**************************************************************************** @@ -80,7 +311,7 @@ DEVICE_Destroy(K32OBJ *dev) { * GetLastError can decypher. */ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, - LPVOID lpvlnBuffer, DWORD cblnBuffer, + LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPOVERLAPPED lpOverlapped) @@ -88,8 +319,8 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, DEVICE_OBJECT *dev = (DEVICE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(), hDevice, K32OBJ_DEVICE_IOCTL, 0 /*FIXME*/, NULL ); - FIXME(win32, "(%ld,%ld,%p,%ld,%p,%ld,%p,%p), stub\n", - hDevice,dwIoControlCode,lpvlnBuffer,cblnBuffer, + TRACE(win32, "(%d,%ld,%p,%ld,%p,%ld,%p,%p)\n", + hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer, lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped ); @@ -102,23 +333,15 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, /* Check if this is a user defined control code for a VxD */ if( HIWORD( dwIoControlCode ) == 0 ) { + if ( dev->info && dev->info->deviceio ) + return dev->info->deviceio( dev, dwIoControlCode, + lpvInBuffer, cbInBuffer, + lpvOutBuffer, cbOutBuffer, + lpcbBytesReturned, lpOverlapped ); + /* FIXME: Set appropriate error */ - FIXME(win32," VxD device %s msg\n",dev->devname); - - if (!strcmp(dev->devname,"VTDAPI")) - { - switch (dwIoControlCode) - { - case 5: if (lpvOutBuffer && (cbOutBuffer>=4)) - *(DWORD*)lpvOutBuffer = timeGetTime(); - if (lpcbBytesReturned) - *lpcbBytesReturned = 4; - return TRUE; - default: - break; - } - - } + FIXME( win32, "Unimplemented control %ld for VxD device %s\n", + dwIoControlCode, dev->devname ); } else { @@ -168,3 +391,297 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, } return FALSE; } + +/*********************************************************************** + * DeviceIo_VTDAPI + */ +static BOOL32 DeviceIo_VTDAPI(DEVICE_OBJECT *dev, DWORD dwIoControlCode, + LPVOID lpvInBuffer, DWORD cbInBuffer, + LPVOID lpvOutBuffer, DWORD cbOutBuffer, + LPDWORD lpcbBytesReturned, + LPOVERLAPPED lpOverlapped) +{ + BOOL32 retv = TRUE; + + switch (dwIoControlCode) + { + case 5: + if (lpvOutBuffer && (cbOutBuffer>=4)) + *(DWORD*)lpvOutBuffer = timeGetTime(); + + if (lpcbBytesReturned) + *lpcbBytesReturned = 4; + + break; + + default: + FIXME(win32, "Control %ld not implemented\n", dwIoControlCode); + retv = FALSE; + break; + } + + return retv; +} + + + + + +/*********************************************************************** + * VxDCall (KERNEL32.[1-9]) + */ +static void VxDCall( CONTEXT *context, int nArgs ) +{ + DWORD retv, service; + int i, ok = FALSE; + + /* Pop return address to caller */ + EIP_reg(context) = STACK32_POP(context); + + /* Pop requested service ID */ + service = STACK32_POP(context); + + TRACE(win32, "(%08lx, ...)\n", service); + + for (i = 0; VxDList[i].name; i++) + if (VxDList[i].id == HIWORD(service)) + break; + + if (!VxDList[i].name) + FIXME(win32, "Unknown VxD (%08lx)\n", service); + else if (!VxDList[i].vxdcall) + FIXME(win32, "Unimplemented VxD (%08lx)\n", service); + else + ok = VxDList[i].vxdcall(&retv, service, context); + + /* If unimplemented, trust the caller to have called the + version with the correct number of arguments */ + if (!ok) + { + ESP_reg(context) += 4 * nArgs; + retv = 0xffffffff; /* FIXME */ + } + + /* Push return address back onto stack */ + STACK32_PUSH(context, EIP_reg(context)); + + /* Return to caller */ + EAX_reg(context) = retv; +} + +REGS_ENTRYPOINT(VxDCall0) { VxDCall( context, 0 ); } +REGS_ENTRYPOINT(VxDCall1) { VxDCall( context, 1 ); } +REGS_ENTRYPOINT(VxDCall2) { VxDCall( context, 2 ); } +REGS_ENTRYPOINT(VxDCall3) { VxDCall( context, 3 ); } +REGS_ENTRYPOINT(VxDCall4) { VxDCall( context, 4 ); } +REGS_ENTRYPOINT(VxDCall5) { VxDCall( context, 5 ); } +REGS_ENTRYPOINT(VxDCall6) { VxDCall( context, 6 ); } +REGS_ENTRYPOINT(VxDCall7) { VxDCall( context, 7 ); } +REGS_ENTRYPOINT(VxDCall8) { VxDCall( context, 8 ); } + +/*********************************************************************** + * VxDCall_VMM + */ +BOOL32 VxDCall_VMM( DWORD *retv, DWORD service, CONTEXT *context ) +{ + BOOL32 ok = TRUE; + + switch ( LOWORD(service) ) + { + case 0x0011: /* RegOpenKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + LPHKEY retkey = (LPHKEY) STACK32_POP( context ); + *retv = RegOpenKey32A( hkey, lpszSubKey, retkey ); + } + break; + + case 0x0012: /* RegCreateKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + LPHKEY retkey = (LPHKEY) STACK32_POP( context ); + *retv = RegCreateKey32A( hkey, lpszSubKey, retkey ); + } + break; + + case 0x0013: /* RegCloseKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + *retv = RegCloseKey( hkey ); + } + break; + + case 0x0014: /* RegDeleteKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + *retv = RegDeleteKey32A( hkey, lpszSubKey ); + } + break; + + case 0x0015: /* RegSetValue */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + DWORD dwType = (DWORD) STACK32_POP( context ); + LPCSTR lpszData = (LPCSTR) STACK32_POP( context ); + DWORD cbData = (DWORD) STACK32_POP( context ); + *retv = RegSetValue32A( hkey, lpszSubKey, dwType, lpszData, cbData ); + } + break; + + case 0x0016: /* RegDeleteValue */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPSTR lpszValue = (LPSTR) STACK32_POP( context ); + *retv = RegDeleteValue32A( hkey, lpszValue ); + } + break; + + case 0x0017: /* RegQueryValue */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPSTR lpszSubKey = (LPSTR) STACK32_POP( context ); + LPSTR lpszData = (LPSTR) STACK32_POP( context ); + LPDWORD lpcbData = (LPDWORD)STACK32_POP( context ); + *retv = RegQueryValue32A( hkey, lpszSubKey, lpszData, lpcbData ); + } + break; + + case 0x0018: /* RegEnumKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + DWORD iSubkey = (DWORD) STACK32_POP( context ); + LPSTR lpszName = (LPSTR) STACK32_POP( context ); + DWORD lpcchName = (DWORD) STACK32_POP( context ); + *retv = RegEnumKey32A( hkey, iSubkey, lpszName, lpcchName ); + } + break; + + case 0x0019: /* RegEnumValue */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + DWORD iValue = (DWORD) STACK32_POP( context ); + LPSTR lpszValue = (LPSTR) STACK32_POP( context ); + LPDWORD lpcchValue = (LPDWORD)STACK32_POP( context ); + LPDWORD lpReserved = (LPDWORD)STACK32_POP( context ); + LPDWORD lpdwType = (LPDWORD)STACK32_POP( context ); + LPBYTE lpbData = (LPBYTE) STACK32_POP( context ); + LPDWORD lpcbData = (LPDWORD)STACK32_POP( context ); + *retv = RegEnumValue32A( hkey, iValue, lpszValue, lpcchValue, + lpReserved, lpdwType, lpbData, lpcbData ); + } + break; + + case 0x001A: /* RegQueryValueEx */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPSTR lpszValue = (LPSTR) STACK32_POP( context ); + LPDWORD lpReserved = (LPDWORD)STACK32_POP( context ); + LPDWORD lpdwType = (LPDWORD)STACK32_POP( context ); + LPBYTE lpbData = (LPBYTE) STACK32_POP( context ); + LPDWORD lpcbData = (LPDWORD)STACK32_POP( context ); + *retv = RegQueryValueEx32A( hkey, lpszValue, lpReserved, + lpdwType, lpbData, lpcbData ); + } + break; + + case 0x001B: /* RegSetValueEx */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPSTR lpszValue = (LPSTR) STACK32_POP( context ); + DWORD dwReserved = (DWORD) STACK32_POP( context ); + DWORD dwType = (DWORD) STACK32_POP( context ); + LPBYTE lpbData = (LPBYTE) STACK32_POP( context ); + DWORD cbData = (DWORD)STACK32_POP( context ); + *retv = RegSetValueEx32A( hkey, lpszValue, dwReserved, + dwType, lpbData, cbData ); + } + break; + + case 0x001C: /* RegFlushKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + *retv = RegFlushKey( hkey ); + } + break; + + case 0x001D: /* RegQueryInfoKey */ + { + /* NOTE: This VxDCall takes only a subset of the parameters that the + corresponding Win32 API call does. The implementation in Win95 + ADVAPI32 sets all output parameters not mentioned here to zero. */ + + HKEY hkey = (HKEY) STACK32_POP( context ); + LPDWORD lpcSubKeys = (LPDWORD)STACK32_POP( context ); + LPDWORD lpcchMaxSubKey + = (LPDWORD)STACK32_POP( context ); + LPDWORD lpcValues = (LPDWORD)STACK32_POP( context ); + LPDWORD lpcchMaxValueName + = (LPDWORD)STACK32_POP( context ); + LPDWORD lpcchMaxValueData + = (LPDWORD)STACK32_POP( context ); + *retv = RegQueryInfoKey32A( hkey, NULL, NULL, NULL, lpcSubKeys, lpcchMaxSubKey, + NULL, lpcValues, lpcchMaxValueName, lpcchMaxValueData, + NULL, NULL ); + } + break; + + case 0x0021: /* RegLoadKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + LPCSTR lpszFile = (LPCSTR) STACK32_POP( context ); + *retv = RegLoadKey32A( hkey, lpszSubKey, lpszFile ); + } + break; + + case 0x0022: /* RegUnLoadKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + *retv = RegUnLoadKey32A( hkey, lpszSubKey ); + } + break; + + case 0x0023: /* RegSaveKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszFile = (LPCSTR) STACK32_POP( context ); + LPSECURITY_ATTRIBUTES sa = + (LPSECURITY_ATTRIBUTES)STACK32_POP( context ); + *retv = RegSaveKey32A( hkey, lpszFile, sa ); + } + break; + +#if 0 /* Functions are not yet implemented in misc/registry.c */ + case 0x0024: /* RegRemapPreDefKey */ + case 0x0026: /* RegQueryMultipleValues */ +#endif + + case 0x0027: /* RegReplaceKey */ + { + HKEY hkey = (HKEY) STACK32_POP( context ); + LPCSTR lpszSubKey = (LPCSTR) STACK32_POP( context ); + LPCSTR lpszNewFile= (LPCSTR) STACK32_POP( context ); + LPCSTR lpszOldFile= (LPCSTR) STACK32_POP( context ); + *retv = RegReplaceKey32A( hkey, lpszSubKey, lpszNewFile, lpszOldFile ); + } + break; + + default: + if (LOWORD(service) < N_VMM_SERVICE) + FIXME(win32, "Unimplemented service %s (%08lx)\n", + VMM_Service_Name[LOWORD(service)], service); + else + FIXME(win32, "Unknown service %08lx\n", service); + + ok = FALSE; + break; + } + + return ok; +} + diff --git a/win32/file.c b/win32/file.c index fd1de18cc20..a595d86791f 100644 --- a/win32/file.c +++ b/win32/file.c @@ -138,16 +138,15 @@ HFILE32 WINAPI CreateFile32A(LPCSTR filename, DWORD access, DWORD sharing, if(template) FIXME(file, "template handles not supported.\n"); + if(!filename) + return HFILE_ERROR32; /* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars. */ if(!strncmp(filename, "\\\\?\\", 4) || !strncmp(filename, "\\\\.\\", 4)) { if (filename[2] == '.') - { - FIXME(file,"device name? %s\n",filename); - /* device? */ return DEVICE_Open( filename+4, access_flags | create_flags ); - } + filename += 4; if (!strncmp(filename, "UNC", 3)) { diff --git a/win32/kernel32.c b/win32/kernel32.c index 08eca15511a..1be5f93540b 100644 --- a/win32/kernel32.c +++ b/win32/kernel32.c @@ -18,6 +18,7 @@ #include "selectors.h" #include "task.h" #include "win.h" +#include "file.h" #include "debug.h" #include "flatthunk.h" #include "syslevel.h" @@ -252,6 +253,7 @@ REGS_ENTRYPOINT(QT_Thunk) (LPBYTE)ESP_reg(context)+4, argsize ); EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize ); + EDX_reg(context) = HIWORD(EAX_reg(context)); } @@ -378,6 +380,7 @@ REGS_ENTRYPOINT(FT_Thunk) } EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize ); + EDX_reg(context) = HIWORD(EAX_reg(context)); } /********************************************************************** @@ -1066,7 +1069,7 @@ BOOL16 WINAPI IsPeFormat( HFILE16 hf16 /* [in] open file, if filename is NULL */ ) { IMAGE_DOS_HEADER mzh; - HFILE32 hf=hf16; + HFILE32 hf=HFILE16_TO_HFILE32(hf16); OFSTRUCT ofs; DWORD xmagic; @@ -1205,10 +1208,3 @@ REGS_ENTRYPOINT(K32Thk1632Epilog) } } -/*********************************************************************** - * VxDCall (KERNEL32.1-8) - */ -DWORD WINAPI VxDCall(DWORD x) { - FIXME(vxd,"(0x%08lx), stub!\n",x); - return 0xffffffff; -} diff --git a/win32/newfns.c b/win32/newfns.c index 693c5f78da3..ced6b063087 100644 --- a/win32/newfns.c +++ b/win32/newfns.c @@ -360,32 +360,6 @@ BOOL32 WINAPI IsDebuggerPresent() { return FALSE; } -/****************************************************************************** - * SleepEx [KERNEL32.680] - * - * BUGS - * Unimplemented - */ -DWORD WINAPI SleepEx(DWORD x1,BOOL32 x2) -{ - FIXME(win32,":(%d,%ld): stub\n",x1,x2); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -/****************************************************************************** - * TerminateProcess [KERNEL32.684] - * - * BUGS - * Unimplemented - */ -int WINAPI TerminateProcess(HANDLE32 h, int ret) -{ - FIXME(win32,":(%p,%d): stub\n",h,ret); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - /****************************************************************************** * OpenDesktop32A [USER32.408] * diff --git a/win32/ordinals.c b/win32/ordinals.c index a9699cf402f..5b7427a2178 100644 --- a/win32/ordinals.c +++ b/win32/ordinals.c @@ -129,4 +129,3 @@ DWORD WINAPI _KERNEL32_99(DWORD x) { FIXME(win32,"(0x%08lx): stub\n",x); return 1; } - diff --git a/win32/process.c b/win32/process.c index 3a8543030ac..2e06bb41a13 100644 --- a/win32/process.c +++ b/win32/process.c @@ -58,50 +58,6 @@ BOOL32 WINAPI SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask return TRUE; } -/********************************************************************** - * CreateProcess32A [KERNEL32.171] - */ -BOOL32 WINAPI CreateProcess32A( - LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes, - LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles, - DWORD creationflags,LPVOID env,LPCSTR curdir, - LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo -) { - HINSTANCE16 hInst = 0; - if (processinfo) memset(processinfo, '\0', sizeof(*processinfo)); - - FIXME(win32,"(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p): calling WinExec32\n", - appname,cmdline,processattributes,threadattributes, - inherithandles,creationflags,env,curdir,startupinfo,processinfo); - - hInst = WinExec32(cmdline,TRUE); - - return hInst >= 32; -#if 0 - /* make from lcc uses system as fallback if CreateProcess returns - FALSE, so return false */ - return FALSE; -#endif -} - -/********************************************************************** - * CreateProcess32W [KERNEL32.172] - */ -BOOL32 WINAPI CreateProcess32W( - LPCWSTR appname,LPWSTR cmdline,LPSECURITY_ATTRIBUTES processattributes, - LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles, - DWORD creationflags,LPVOID env,LPCWSTR curdir, - LPSTARTUPINFO32W startupinfo,LPPROCESS_INFORMATION processinfo) -{ - FIXME(win32,"(%p,%s,%p,%p,%d,%08lx,%p,%s,%p,%p): stub\n", - appname,debugstr_w(cmdline),processattributes,threadattributes, - inherithandles,creationflags,env,debugstr_w(curdir),startupinfo, - processinfo ); - /* make from lcc uses system as fallback if CreateProcess returns - FALSE, so return false */ - return FALSE; -} - /********************************************************************** * ContinueDebugEvent [KERNEL32.146] */ diff --git a/win32/time.c b/win32/time.c index 9dc1e4c4b6d..fc82034710d 100644 --- a/win32/time.c +++ b/win32/time.c @@ -132,16 +132,6 @@ BOOL32 WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION tzinfo) } -/*********************************************************************** - * Sleep (KERNEL32.523) - */ -VOID WINAPI Sleep(DWORD cMilliseconds) -{ - if(cMilliseconds == INFINITE32) - while(1) sleep(1000); /* Spin forever */ - usleep(cMilliseconds*1000); -} - /*********************************************************************** * GetSystemTimeAsFileTime (KERNEL32) */ diff --git a/windows/keyboard.c b/windows/keyboard.c index ac4b5424831..667f2d58c64 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -277,13 +277,13 @@ BOOL32 KEYBOARD_Init(void) keysym = TSXLookupKeysym(&e2, i); switch (keysym) { - case ';': case ':': vkey = VK_OEM_1; break; - case '/': case '?': vkey = VK_OEM_2; break; - case '`': case '~': vkey = VK_OEM_3; break; + case ';': vkey = VK_OEM_1; break; + case '/': vkey = VK_OEM_2; break; + case '`': vkey = VK_OEM_3; break; case '[': vkey = VK_OEM_4; break; case '\\': vkey = VK_OEM_5; break; case ']': vkey = VK_OEM_6; break; - case '\'': case '\"': vkey = VK_OEM_7; break; + case '\'': vkey = VK_OEM_7; break; case ',': vkey = VK_OEM_COMMA; break; case '.': vkey = VK_OEM_PERIOD; break; case '-': vkey = VK_OEM_MINUS; break; @@ -391,13 +391,19 @@ void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event ) WORD vkey = 0; KEYLP keylp; static BOOL32 force_extended = FALSE; /* hack for AltGr translation */ - - int ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs); + + int ascii_chars; INT32 event_x = pWnd->rectWindow.left + event->x; INT32 event_y = pWnd->rectWindow.top + event->y; DWORD event_time = event->time - MSG_WineStartTicks; + /* this allows support for dead keys */ + if ((event->keycode >> 8) == 0x10) + event->keycode=(event->keycode & 0xff); + + ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs); + TRACE(key, "EVENT_key : state = %X\n", event->state); if (keysym == XK_Mode_switch) { @@ -831,6 +837,14 @@ msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message); } +/********************************************************************** + * ScreenSwitchEnable (KEYBOARD.100) + */ +VOID WINAPI ScreenSwitchEnable(WORD unused) +{ + FIXME(keyboard,"(%04x): stub\n",unused); +} + /********************************************************************** * OemKeyScan (KEYBOARD.128)(USER32.401) */ diff --git a/windows/mdi.c b/windows/mdi.c index 3478cb4300f..dadc4c8bf28 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -247,6 +247,23 @@ static LRESULT MDISetMenu( HWND32 hwnd, HMENU32 hmenuFrame, return 0; } +/********************************************************************** + * MDIRefreshMenu + */ +static LRESULT MDIRefreshMenu( HWND32 hwnd, HMENU32 hmenuFrame, + HMENU32 hmenuWindow) +{ + HWND32 hwndFrame = GetParent32(hwnd); + HMENU32 oldFrameMenu = GetMenu32(hwndFrame); + + TRACE(mdi, "%04x %04x %04x\n", + hwnd, hmenuFrame, hmenuWindow); + + FIXME(mdi,"partially function stub"); + + return oldFrameMenu; +} + /* ------------------ MDI child window functions ---------------------- */ @@ -983,6 +1000,9 @@ LRESULT WINAPI MDIClientWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam, case WM_MDISETMENU: return MDISetMenu( hwnd, (HMENU32)wParam, (HMENU32)lParam ); + case WM_MDIREFRESHMENU: + return MDIRefreshMenu( hwnd, (HMENU32)wParam, (HMENU32)lParam ); + case WM_MDITILE: ci->mdiFlags |= MDIF_NEEDUPDATE; ShowScrollBar32(hwnd,SB_BOTH,FALSE); diff --git a/windows/message.c b/windows/message.c index 4e8c632b3c2..972e6ef31d7 100644 --- a/windows/message.c +++ b/windows/message.c @@ -449,7 +449,8 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter, joySendMessages(); /* If the queue is empty, attempt to fill it */ - if (!sysMsgQueue->msgCount && TSXPending(display)) + if (!sysMsgQueue->msgCount && THREAD_IsWin16( THREAD_Current() ) + && TSXPending(display)) EVENT_WaitNetEvent( FALSE, FALSE ); for (i = kbd_msg = 0; i < sysMsgQueue->msgCount; i++, pos++) @@ -634,7 +635,10 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT16 msg, if (!(queue->wakeBits & QS_SMRESULT)) { queue->changeBits &= ~QS_SMRESULT; - DirectedYield( destQ->hTask ); + if (THREAD_IsWin16( THREAD_Current() )) + DirectedYield( destQ->hTask ); + else + QUEUE_Signal( destQ->hTask ); QUEUE_WaitBits( QS_SMRESULT ); TRACE(sendmsg,"\tsm: have result!\n"); } @@ -684,7 +688,7 @@ void WINAPI ReplyMessage16( LRESULT result ) } if(!(senderQ->wakeBits & QS_SMRESULT) ) break; - OldYield(); + if (THREAD_IsWin16(THREAD_Current())) OldYield(); } if( !senderQ ) { TRACE(msg,"\trpm: done\n"); return; } @@ -696,7 +700,7 @@ void WINAPI ReplyMessage16( LRESULT result ) queue->InSendMessageHandle = 0; QUEUE_SetWakeBit( senderQ, QS_SMRESULT ); - DirectedYield( queue->hSendingTask ); + if (THREAD_IsWin16(THREAD_Current())) DirectedYield( queue->hSendingTask ); } @@ -729,6 +733,9 @@ static BOOL32 MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last, if (IsTaskLocked()) flags |= PM_NOYIELD; + /* Never yield on Win32 threads */ + if (!THREAD_IsWin16(THREAD_Current())) flags |= PM_NOYIELD; + while(1) { hQueue = GetTaskQueue(0); diff --git a/windows/msgbox.c b/windows/msgbox.c index 441ea4a8121..831865ff812 100644 --- a/windows/msgbox.c +++ b/windows/msgbox.c @@ -320,7 +320,7 @@ void WINAPI FatalAppExit32A( UINT32 action, LPCSTR str ) { WARN(dialog,"AppExit\n"); MessageBox32A( 0, str, NULL, MB_SYSTEMMODAL | MB_OK ); - TASK_KillCurrentTask(0); + ExitProcess(0); } @@ -331,7 +331,7 @@ void WINAPI FatalAppExit32W( UINT32 action, LPCWSTR str ) { WARN(dialog,"AppExit\n"); MessageBox32W( 0, str, NULL, MB_SYSTEMMODAL | MB_OK ); - TASK_KillCurrentTask(0); + ExitProcess(0); } diff --git a/windows/queue.c b/windows/queue.c index 712dea1ef18..8ab1c80bd92 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -217,6 +217,59 @@ MESSAGEQUEUE *QUEUE_GetSysQueue(void) return sysMsgQueue; } +/*********************************************************************** + * QUEUE_Signal + */ +void QUEUE_Signal( HTASK16 hTask ) +{ + PDB32 *pdb; + THREAD_ENTRY *entry; + int wakeup = FALSE; + + TDB *pTask = (TDB *)GlobalLock16( hTask ); + if ( !pTask ) return; + + TRACE(msg, "calling SYNC_MsgWakeUp\n"); + + /* Wake up thread waiting for message */ + /* NOTE: This should really wake up *the* thread that owns + the queue. Since we dont't have thread-local message + queues yet, we wake up all waiting threads ... */ + SYSTEM_LOCK(); + pdb = pTask->thdb->process; + entry = pdb? pdb->thread_list->next : NULL; + + if (entry) + for (;;) + { + if (entry->thread->wait_struct.wait_msg) + { + SYNC_MsgWakeUp( entry->thread ); + wakeup = TRUE; + } + if (entry == pdb->thread_list) break; + entry = entry->next; + } + SYSTEM_UNLOCK(); + + if ( !wakeup && THREAD_IsWin16( THREAD_Current() ) ) + PostEvent( hTask ); +} + +/*********************************************************************** + * QUEUE_Wait + */ +void QUEUE_Wait( void ) +{ + if ( THREAD_IsWin16( THREAD_Current() ) ) + WaitEvent( 0 ); + else + { + TRACE(msg, "current task is 32-bit, calling SYNC_DoWait\n"); + SYNC_DoWait( 0, NULL, FALSE, INFINITE32, FALSE, TRUE ); + } +} + /*********************************************************************** * QUEUE_SetWakeBit @@ -235,28 +288,7 @@ void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit ) if (queue->wakeMask & bit) { queue->wakeMask = 0; - PostEvent( queue->hTask ); - - /* Wake up thread waiting for message */ - /* NOTE: This should really wake up *the* thread that owns - the queue. Since we dont't have thread-local message - queues yet, we wake up all waiting threads ... */ - SYSTEM_LOCK(); - { - TDB *pTask = (TDB *)GlobalLock16( queue->hTask ); - PDB32 *pdb = pTask? pTask->thdb->process : NULL; - THREAD_ENTRY *entry = pdb? pdb->thread_list->next : NULL; - - if (entry) - for (;;) - { - if (entry->thread->wait_struct.wait_msg) - SYNC_MsgWakeUp( entry->thread ); - if (entry == pdb->thread_list) break; - entry = entry->next; - } - } - SYSTEM_UNLOCK(); + QUEUE_Signal( queue->hTask ); } } @@ -306,7 +338,7 @@ void QUEUE_WaitBits( WORD bits ) TRACE(msg,"%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask); - WaitEvent( 0 ); + QUEUE_Wait(); } } diff --git a/windows/win.c b/windows/win.c index 1b09c8a36da..456f2153977 100644 --- a/windows/win.c +++ b/windows/win.c @@ -29,6 +29,7 @@ #include "clipboard.h" #include "winproc.h" #include "thread.h" +#include "process.h" #include "debug.h" #include "winerror.h" @@ -291,7 +292,6 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) PROPERTY_RemoveWindowProps( wndPtr ); wndPtr->dwMagic = 0; /* Mark it as invalid */ - wndPtr->hwndSelf = 0; if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT)) { @@ -326,10 +326,9 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu ); if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu ); if (wndPtr->window) EVENT_DestroyWindow( wndPtr ); - if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr ); - + DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */ WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW ); - + wndPtr->hwndSelf = 0; wndPtr->class->cWindows--; wndPtr->class = NULL; pWnd = wndPtr->next; @@ -493,13 +492,33 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, /* Fix the coordinates */ - if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0; + if (cs->x == CW_USEDEFAULT32) + { + PDB32 *pdb = PROCESS_Current(); + if ( !(cs->style & (WS_CHILD | WS_POPUP)) + && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) ) + { + cs->x = pdb->env_db->startup_info->dwX; + cs->y = pdb->env_db->startup_info->dwY; + } + else + { + cs->x = 0; + cs->y = 0; + } + } if (cs->cx == CW_USEDEFAULT32) { -/* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0; - else */ + PDB32 *pdb = PROCESS_Current(); + if ( !(cs->style & (WS_CHILD | WS_POPUP)) + && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) ) { - cs->cx = 600; + cs->cx = pdb->env_db->startup_info->dwXSize; + cs->cy = pdb->env_db->startup_info->dwYSize; + } + else + { + cs->cx = 600; /* FIXME */ cs->cy = 400; } } @@ -2274,11 +2293,13 @@ static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func, /* Make sure that the window still exists */ if (!IsWindow32((*ppWnd)->hwndSelf)) continue; /* Build children list first */ - if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL ))) - return FALSE; - if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE; - ret = WIN_EnumChildWindows( childList, func, lParam ); - HeapFree( SystemHeap, 0, childList ); + childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL ); + ret = func( (*ppWnd)->hwndSelf, lParam ); + if (childList) + { + if (ret) ret = WIN_EnumChildWindows( childList, func, lParam ); + HeapFree( SystemHeap, 0, childList ); + } if (!ret) return FALSE; } return TRUE; diff --git a/windows/winpos.c b/windows/winpos.c index 8bec5195715..74af90a0a7f 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -53,6 +53,7 @@ static HWND32 hwndActive = 0; /* Currently active window */ static HWND32 hwndPrevActive = 0; /* Previously active window */ +static HWND32 hGlobalShellWindow=0; /*the shell*/ static LPCSTR atomInternalPos; @@ -702,9 +703,10 @@ HWND16 WINAPI GetShellWindow16(void) * SetShellWindow32 (USER32.504) */ HWND32 WINAPI SetShellWindow32(HWND32 hwndshell) -{ - FIXME(win, "(%08x): empty stub\n",hwndshell ); - return 0; +{ WARN(win, "(hWnd=%08x) semi stub\n",hwndshell ); + + hGlobalShellWindow = hwndshell; + return hGlobalShellWindow; } @@ -712,9 +714,9 @@ HWND32 WINAPI SetShellWindow32(HWND32 hwndshell) * GetShellWindow32 (USER32.287) */ HWND32 WINAPI GetShellWindow32(void) -{ - FIXME(win, "(void): empty stub\n" ); - return 0; +{ WARN(win, "(hWnd=%x) semi stub\n",hGlobalShellWindow ); + + return hGlobalShellWindow; } diff --git a/windows/winproc.c b/windows/winproc.c index f62f86f2e89..bb6ff926470 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -730,6 +730,8 @@ INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32, *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL32) ); return 1; case WM_MDISETMENU: + if(wParam16==TRUE) + *pmsg32=WM_MDIREFRESHMENU; *pwparam32 = (WPARAM32)(HMENU32)LOWORD(*plparam); *plparam = (LPARAM)(HMENU32)HIWORD(*plparam); return 0;