Release 980822
Sat Aug 22 17:46:19 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de>
* [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 <juergen.schmied@metronet.de>
* [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 <lav@long.yar.ru>
* [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 <adrian@select.com.au>
* [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 <julliard@lrc.epfl.ch>
* [server/process.c] [server/thread.c]
Implemented object wait queues and synchronization.
Fri Aug 21 18:40:02 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
* [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 <bon@elektron.ikp.physik.tu-darmstadt.de>
* [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 <marcus@jet.franken.de>
* [*/*]
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 <ovek@arcticnet.no>
* [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 <turchanov@usa.net>
* [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 <srtxg@chanae.alphanet.ch>
* [windows/keyboard.c]
Corrected keyboard code to properly handle keys : ? ~ and "
on non US keyboards.
Sat Aug 15 18:47:14 1998 Brian Craft <bcboy@dorothy.wanglab.brandeis.edu>
* [windows/win.c]
Fixed severe bug in EnumChildWindwos().
Thu Aug 13 21:05:35 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
* [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 <jrj120@psu.edu>
* [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 <weigand@informatik.uni-erlangen.de>
* [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.
diff --git a/ANNOUNCE b/ANNOUNCE
index 303c5bd..5c0bea1 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 @@
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 bd9cb45..b6e4c54 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,213 @@
----------------------------------------------------------------------
+Sat Aug 22 17:46:19 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+ * [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 <juergen.schmied@metronet.de>
+
+ * [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 <lav@long.yar.ru>
+
+ * [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 <adrian@select.com.au>
+
+ * [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 <julliard@lrc.epfl.ch>
+
+ * [server/process.c] [server/thread.c]
+ Implemented object wait queues and synchronization.
+
+Fri Aug 21 18:40:02 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>
+
+ * [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 <bon@elektron.ikp.physik.tu-darmstadt.de>
+
+ * [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 <marcus@jet.franken.de>
+
+ * [*/*]
+ 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 <ovek@arcticnet.no>
+
+ * [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 <turchanov@usa.net>
+
+ * [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 <srtxg@chanae.alphanet.ch>
+
+ * [windows/keyboard.c]
+ Corrected keyboard code to properly handle keys : ? ~ and "
+ on non US keyboards.
+
+Sat Aug 15 18:47:14 1998 Brian Craft <bcboy@dorothy.wanglab.brandeis.edu>
+
+ * [windows/win.c]
+ Fixed severe bug in EnumChildWindwos().
+
+Thu Aug 13 21:05:35 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
+
+ * [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 <jrj120@psu.edu>
+
+ * [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]
@@ -15,6 +224,33 @@
* [loader/task.c]
InitTask needs to decrement the SP register by two as Win95 does.
+Sun Aug 9 02:41:28 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de>
+
+ * [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 <marcus@jet.franken.de>
* [*/*]
diff --git a/Makefile.in b/Makefile.in
index 52a3b6a..3f88e15 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 @@
tools \
tools/wrc \
controls \
+ dlls/shell32 \
files \
graphics \
graphics/metafiledrv \
@@ -75,6 +77,7 @@
LIBOBJS = \
controls/controls.o \
+ dlls/shell32/shell32.o \
files/files.o \
graphics/graphics.o \
graphics/metafiledrv/metafiledrv.o \
@@ -112,6 +115,8 @@
install:: install_$(MAIN_TARGET)
+uninstall:: uninstall_$(MAIN_TARGET)
+
emu: wine
lib: $(LIBSUBDIRS) $(LIB_TARGET)
@@ -129,28 +134,47 @@
$(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 840938e..4c6f44c 100755
--- a/configure
+++ b/configure
@@ -3396,6 +3396,8 @@
Makefile
controls/Makefile
debugger/Makefile
+dlls/Makefile
+dlls/shell32/Makefile
documentation/Makefile
files/Makefile
graphics/Makefile
@@ -3531,6 +3533,8 @@
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 19731df..cf1d414 100644
--- a/configure.in
+++ b/configure.in
@@ -460,6 +460,8 @@
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 7027960..aa5c83d 100644
--- a/controls/comctl32undoc.c
+++ b/controls/comctl32undoc.c
@@ -2,7 +2,7 @@
* Undocumented functions from COMCTL32.DLL
*
* Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
- *
+ * 1998 Juergen Schmied <j.schmied@metronet.de>
* 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_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 @@
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 @@
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 @@
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 @@
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; i<dsaPtr->dwElementSize;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 4be6540..629fc50 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 @@
/***********************************************************************
* 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 @@
* 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 @@
*
* 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 @@
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 @@
* 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 @@
/***********************************************************************
- * 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 fc01e53..45a25c6 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -3852,7 +3852,7 @@
/**********************************************************************
* 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 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 2e335c0..60612c2 100644
--- a/controls/pager.c
+++ b/controls/pager.c
@@ -25,6 +25,17 @@
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)
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr(wndPtr);
@@ -51,6 +62,28 @@
}
+// << 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 @@
}
+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 @@
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 @@
infoPtr->clrBk = GetSysColor32 (COLOR_BTNFACE);
infoPtr->iBorder = 0;
infoPtr->iButtonSize = 0;
+ infoPtr->iPos = 0;
return 0;
@@ -148,7 +194,7 @@
- /* free tree view info data */
+ /* free pager info data */
HeapFree (GetProcessHeap (), 0, infoPtr);
return 0;
@@ -169,15 +215,19 @@
}
+// << 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 @@
// 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 @@
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 @@
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 9280cf9..a36bbff 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 @@
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 6a883d5..142ffb6 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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_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_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_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_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 @@
}
-static LRESULT
+__inline__ static LRESULT
TOOLBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
return TOOLBAR_InternalHitTest (wndPtr, (LPPOINT32)lParam);
@@ -1262,7 +1330,7 @@
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_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 @@
infoPtr->buttons[nIndex].idCommand = (INT32)lParam;
+ if (infoPtr->hwndToolTip) {
+
+ FIXME (toolbar, "change tool tip!\n");
+
+ }
+
return TRUE;
}
@@ -1608,7 +1694,20 @@
}
-// << 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_DrawButton (wndPtr, btnPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
+ if (infoPtr->hwndToolTip) {
+
+ FIXME (toolbar, "change tool tip!\n");
+
+ }
+
return TRUE;
}
@@ -1698,10 +1803,15 @@
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 @@
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 @@
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_NCActivate >>
static LRESULT
@@ -2005,8 +2118,7 @@
{
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_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 @@
// 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 @@
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 @@
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 @@
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 e0e8477..baf6971 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
-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 @@
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 f3d080b..8fb9c96 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -1075,7 +1075,7 @@
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 0000000..efbafbc
--- /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 0000000..59a0004
--- /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 0000000..52ce253
--- /dev/null
+++ b/dlls/shell32/contmenu.c
@@ -0,0 +1,383 @@
+/*
+ * IContextMenu
+ *
+ * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
+ */
+#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 0000000..4afff0c
--- /dev/null
+++ b/dlls/shell32/enumidlist.c
@@ -0,0 +1,357 @@
+/*
+ * IEnumIDList
+ *
+ * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#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 0000000..e9e078c
--- /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 !!!
+ * <contact juergen.schmied@metronet.de, 980801>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#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 0000000..7b1440a
--- /dev/null
+++ b/dlls/shell32/pidl.c
@@ -0,0 +1,846 @@
+/*
+ * pidl Handling
+ *
+ * Copyright 1998 Juergen Schmied
+ *
+ * !!! currently work in progress on all classes !!!
+ * <contact juergen.schmied@metronet.de, 980801>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#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 0000000..0817b53
--- /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 0000000..2a348f8
--- /dev/null
+++ b/dlls/shell32/shell32_main.c
@@ -0,0 +1,962 @@
+/*
+ * Shell basics
+ *
+ * 1998 Marcus Meissner
+ * 1998 Juergen Schmied (jsch) * <juergen.schmied@metronet.de>
+ */
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#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 0000000..da0d843
--- /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 0000000..fbbc42e
--- /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 <juergen.schmied@metronet.de>
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#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 9076838..ae9990f 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 @@
{ 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 @@
* 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 @@
);
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 @@
*
* 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 @@
*
* 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);
@@ -632,125 +504,6 @@
}
/*************************************************************************
- *
- */
-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]
*
* Format and output errormessage.
@@ -775,7 +528,6 @@
/*MessageBox32A(hwnd,buf3,buf,id|0x10000);*/
}
-
/*************************************************************************
* SHRestricted [SHELL32.100]
*
@@ -817,49 +569,6 @@
}
/*************************************************************************
- * 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]
*
* NOTES
@@ -918,22 +627,6 @@
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 @@
return 0;
}
-
/*************************************************************************
* RunFileDlg [SHELL32.61]
*
@@ -985,7 +677,6 @@
return 0;
}
-
/*************************************************************************
* ExitWindowsDialog [SHELL32.60]
*
@@ -999,7 +690,6 @@
return 0;
}
-
/*************************************************************************
* ArrangeWindows [SHELL32.184]
*
@@ -1013,7 +703,6 @@
return 0;
}
-
/*************************************************************************
* SHCLSIDFromString [SHELL32.147]
*
@@ -1024,7 +713,6 @@
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 @@
* 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 0000000..4a516cf
--- /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 !!!
+ * <contact juergen.schmied@metronet.de>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#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, (dwOut<dwCopy)? dwOut : dwCopy);
+
+ if(*pszTail)
+ { pszTail++;
+ }
+
+ TRACE(shell,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext),debugstr_a(pszOut),dwOut);
+ return pszTail;
+}
+
+/***********************************************************************
+* IShellFolder implementation
+*/
+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_GetFolderPath
+};
+/**************************************************************************
+* 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((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 0000000..90796db
--- /dev/null
+++ b/dlls/shell32/shlview.c
@@ -0,0 +1,1185 @@
+/*
+ * ShellView
+ *
+ * Copyright 1998 Juergen Schmied
+ *
+ * !!! currently work in progress on all classes 980801 !!!
+ * <contact juergen.schmied@metronet.de>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#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 0000000..508a31d
--- /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 0000000..7ce0202
--- /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 fdf44b1..fb551bd 100644
--- a/documentation/Makefile.in
+++ b/documentation/Makefile.in
@@ -52,10 +52,16 @@
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 6f854a2..43b4430 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 0000000..d002e4a
--- /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 0000000..d90b70b
--- /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>
+
+
+
+----------
+<juergen.schmied@metronet.de>
diff --git a/documentation/shell32 b/documentation/shell32
new file mode 100644
index 0000000..4fcb2ef
--- /dev/null
+++ b/documentation/shell32
@@ -0,0 +1,71 @@
+ SHELL32
+ development status
+
+ Author needed!! Any volunteers??
+ mail to <juergen.schmied@metronet.de>
+
+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 <juergen.schmied@metronet.de>
+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 e61e8e7..fd168c4 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_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 @@
#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 @@
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 @@
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 @@
/* 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 @@
!(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 @@
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 @@
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 @@
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 @@
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 @@
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 6ae8d60..a2bd5dd 100644
--- a/files/file.c
+++ b/files/file.c
@@ -871,7 +871,7 @@
*/
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 @@
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 @@
/* 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 @@
*/
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 @@
{
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 @@
*/
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 @@
*/
HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
{
- return _lopen32( path, mode );
+ return HFILE32_TO_HFILE16(_lopen32( path, mode ));
}
@@ -1091,7 +1091,7 @@
*/
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 @@
*/
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 _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 ecdd09c..49b58d7 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -945,7 +945,7 @@
/***********************************************************************
* 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 @@
* 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 @@
/***********************************************************************
* 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 @@
/***********************************************************************
* 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 4420891..3c64fcc 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 <unistd.h>
#include <assert.h>
#include "ts_xlib.h"
-#ifdef HAVE_LIBXXSHM
-#include "ts_xshm.h"
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
#include <sys/signal.h>
#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 @@
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 @@
{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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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_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 @@
(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 @@
* 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 @@
FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
return DDERR_GENERIC;
}
- for (i=start;i<end;i++) {
- xc.pixel = i;
+ for (i=0;i<count;i++) {
+ xc.pixel = i+start;
TSXQueryColor(display,this->cm,&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;i<count;i++) {
+ xc.red = palent[i].peRed<<8;
+ xc.blue = palent[i].peBlue<<8;
+ xc.green = palent[i].peGreen<<8;
+ xc.flags = DoRed|DoBlue|DoGreen;
+ xc.pixel = start+i;
+ TSXStoreColor(display,this->cm,&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;i<end;i++) {
- xc.red = palent[i-start].peRed<<8;
- xc.blue = palent[i-start].peBlue<<8;
- xc.green = palent[i-start].peGreen<<8;
- xc.flags = DoRed|DoBlue|DoGreen;
- xc.pixel = i;
- TSXStoreColor(display,this->cm,&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;i<count;i++) {
+ xc.red = palent[i].peRed<<8;
+ xc.blue = palent[i].peBlue<<8;
+ xc.green = palent[i].peGreen<<8;
+ xc.flags = DoRed|DoBlue|DoGreen;
+ xc.pixel = i+start;
+ TSXStoreColor(display,this->cm,&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 @@
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 @@
(void*)4,
IDirectDrawPalette_GetEntries,
IDirectDrawPalette_Initialize,
- common_IDirectDrawPalette_SetEntries
+ Xlib_IDirectDrawPalette_SetEntries
};
/*******************************************************************************
@@ -1189,7 +1034,7 @@
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 @@
/*******************************************************************************
* 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 @@
#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 @@
} 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 @@
/* 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 @@
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 @@
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;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
@@ -1455,7 +1262,7 @@
dsprintf(ddraw, "%s ", flagmap[i].name);
TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
}
- this->d.mainwindow = hwnd;
+/* this->d.mainwindow = hwnd;*/
return 0;
}
@@ -1493,9 +1300,9 @@
* 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 @@
#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;i<depcount;i++)
- if (depths[i]==depth)
- break;
- TSXFree(depths);
- if (i==depcount) {/* not found */
- sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
- MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
- return DDERR_UNSUPPORTEDMODE;
- }
- if (this->d.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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
}
/* 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 @@
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 @@
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 @@
(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 @@
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 @@
(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 @@
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 @@
#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 @@
* 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 6797fcc..57b3316 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -755,8 +755,8 @@
/**********************************************************************
* 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 ead31bb..ee62d63 100644
--- a/graphics/psdrv/driver.c
+++ b/graphics/psdrv/driver.c
@@ -44,8 +44,10 @@
}
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 3195200..6a62a5a 100644
--- a/graphics/psdrv/init.c
+++ b/graphics/psdrv/init.c
@@ -169,6 +169,12 @@
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 @@
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 @@
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 @@
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 ef1cf1c..3e5f189 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -753,7 +753,7 @@
* 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 d0a7ef1..8fdcc88 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -218,7 +218,7 @@
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 354c5af..50e9960 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -8,7 +8,7 @@
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 ca9f6bb..2d5e33e 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -236,7 +236,7 @@
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 299977b..3c925a42 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -368,7 +368,7 @@
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 0000000..2cfc70b
--- /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 04f29ff..3284c98 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -55,14 +55,64 @@
#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 @@
#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 @@
#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 @@
#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 58ea6ff..db87666 100644
--- a/include/ddraw.h
+++ b/include/ddraw.h
@@ -876,7 +876,6 @@
struct _common_directdrawdata {
DWORD depth;
DWORD height,width; /* SetDisplayMode */
- HWND32 mainwindow;
};
struct _dga_directdrawdata {
@@ -887,12 +886,16 @@
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 _common_directdrawdata d;
union {
struct _xlib_directdrawdata xlib;
- struct _xlib_directdrawdata xshm;
struct _dga_directdrawdata dga;
} e;
};
@@ -957,8 +959,6 @@
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 @@
#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 @@
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 _common_directdrawsurface s;
union {
struct _dga_directdrawsurface dga;
- struct _xshm_directdrawsurface xshm;
struct _xlib_directdrawsurface xlib;
} t;
};
@@ -1181,5 +1176,8 @@
#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 9056a5c..962d826 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 14450de..60ceded 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 @@
{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 @@
"ole",
"pager",
"palette",
+"pidl",
"print",
"process",
"profile",
diff --git a/include/dosexe.h b/include/dosexe.h
index 56cd478..ad3a892 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 564314f..fc5f806 100644
--- a/include/file.h
+++ b/include/file.h
@@ -40,6 +40,17 @@
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 fcb1786..c8ca418 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -200,7 +200,7 @@
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 710b1e4..298f67b 100644
--- a/include/header.h
+++ b/include/header.h
@@ -18,32 +18,32 @@
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 5f4c766..6855762 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -17,6 +17,7 @@
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 @@
/* 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 485d784..bc0e25f 100644
--- a/include/module.h
+++ b/include/module.h
@@ -52,6 +52,7 @@
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 @@
{
LPSTR lpEnvAddress;
LPSTR lpCmdLine;
- LPSTR lpCmdShow;
+ UINT16 *lpCmdShow;
DWORD dwReserved;
} LOADPARAMS32;
@@ -140,8 +141,6 @@
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 fe992ff..0808084 100644
--- a/include/pager.h
+++ b/include/pager.h
@@ -14,7 +14,8 @@
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 5b91461..bba5733 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -40,8 +40,9 @@
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 8f82294..539aee1 100644
--- a/include/process.h
+++ b/include/process.h
@@ -142,7 +142,7 @@
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 38136c5..f864dfe 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -80,6 +80,8 @@
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 152d6ee..ff92512 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 0b80e48..30e09ac 100644
--- a/include/server.h
+++ b/include/server.h
@@ -86,6 +86,18 @@
};
+/* 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 @@
};
+/* 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_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 bf6dcd3..5268061 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 574b732..b882ebc 100644
--- a/include/server/request.h
+++ b/include/server/request.h
@@ -10,9 +10,11 @@
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(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 @@
{ (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 9edbfdf..7f7df8d 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 @@
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 cda641c..e9dc4c5 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 @@
#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 @@
/* memory block with filenames follows */
} DROPFILESTRUCT, *LPDROPFILESTRUCT;
-/******************************
-* NOTIFYICONDATA
+/****************************************************************************
+* NOTIFYICONDATA
*/
typedef struct _NOTIFYICONDATA {
DWORD cbSize;
@@ -76,8 +90,8 @@
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 @@
} 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 @@
#define SHGetPathFromIDList WINELIB_NAME_AW(SHGetPathFromIDList)
/****************************************************************************
-* SHFILEINFO API
+* SHFILEINFO API
*/
typedef struct tagSHFILEINFO32A {
HICON32 hIcon; /* icon */
@@ -122,7 +137,7 @@
#define SHGetFileInfo WINELIB_NAME_AW(SHGetFileInfo)
/****************************************************************************
-* SHFILEOPSTRUCT API
+* SHFILEOPSTRUCT API
*/
typedef struct _SHFILEOPSTRUCTA
{ HWND32 hwnd;
@@ -153,7 +168,7 @@
DWORD WINAPI SHFileOperation32(LPSHFILEOPSTRUCT32 lpFileOp);
-/****************
+/****************************************************************************
* APPBARDATA
*/
typedef struct _AppBarData {
@@ -188,6 +203,7 @@
{ 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);
@@ -200,13 +216,17 @@
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 @@
#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 350fe57..4a900ac 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 @@
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 @@
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);
@@ -148,6 +154,136 @@
#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
/*****************************************************************************
* IEnumIDList interface
@@ -310,16 +446,20 @@
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 @@
*/
#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 @@
#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 @@
LPSHELLFOLDER pSFParent;
LPSHELLBROWSER pShellBrowser;
HWND32 hWnd;
+ HWND32 hWndList;
FOLDERSETTINGS FolderSettings;
HWND32 hWndParent;
+ HMENU32 hMenu;
+ UINT32 uState;
};
typedef GUID SHELLVIEWID;
@@ -498,19 +683,173 @@
#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 @@
#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 @@
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 595d91c..315564f 100644
--- a/include/sig_context.h
+++ b/include/sig_context.h
@@ -217,10 +217,10 @@
#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 56ac846..e151075 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 85f38cb..bde0351 100644
--- a/include/task.h
+++ b/include/task.h
@@ -147,6 +147,7 @@
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 e033b29..58ad89a 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -44,6 +44,7 @@
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 @@
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 fc05739..4af9f98 100644
--- a/include/toolbar.h
+++ b/include/toolbar.h
@@ -32,17 +32,18 @@
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 @@
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 b4875c0..2750cb4 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 @@
HINSTANCE32 hinst;
LPSTR lpszText;
LPARAM lParam;
-
- WNDPROC32 lpfnOrigProc;
} TTTOOL_INFO;
diff --git a/include/tweak.h b/include/tweak.h
index 346f6a0..06bffee 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 2311c01..a6ca120 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 b4cc236..16938f2 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 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 a94c819..e5c9f74 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1073,6 +1073,10 @@
#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 @@
BYTE pad0;
WORD key;
WORD cmd;
+ WORD pad1;
} ACCEL32, *LPACCEL32;
DECL_WINELIB_TYPE(ACCEL)
@@ -3178,6 +3183,7 @@
#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 @@
#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 @@
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 @@
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 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 @@
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 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 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 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 @@
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 @@
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 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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 12f1727..91db795 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -22,6 +22,9 @@
*/
#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 b4804ba..895676d 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -135,6 +135,7 @@
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(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 0bb9b24..5968388 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -98,7 +98,7 @@
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 c605049..67b4c7a 100644
--- a/loader/dos/Makefile.in
+++ b/loader/dos/Makefile.in
@@ -9,7 +9,9 @@
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 b5ad24f..9807ecf 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 <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
+#include <signal.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/vm86.h>
#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
/* 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 @@
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 3818daa..ec2e91d 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 <sys/stat.h>
#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 @@
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 @@
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 @@
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 @@
}
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 053c2c3..cce308f 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 <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef MZ_USESYSV
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#else
#include <sys/mman.h>
-#endif
#include <sys/vm86.h>
-#ifdef MZ_USESYSV
-#include <linux/mm.h> /* 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 @@
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 @@
/* 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 @@
/* 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 @@
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 @@
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 @@
for (x=0; x<mz_header.e_crlc; x++) {
if (_lread16(hFile,&reloc,sizeof(reloc)) != sizeof(reloc))
return 11; /* invalid exe */
- *(WORD*)SEGPTR16(load_start,reloc)+=load_seg;
+ *(WORD*)SEGPTR16(load_start,reloc)+=lpDosTask->load_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 @@
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 @@
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 @@
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 @@
NE_MODULE *pModule;
HFILE16 hFile;
OFSTRUCT ofs;
- PROCESS_INFORMATION info;
int err;
if ((lpDosTask = calloc(1, sizeof(DOSTASK))) == NULL)
@@ -252,29 +270,41 @@
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;
}
- MZ_InitTask( lpDosTask );
+ 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;
+ }
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 @@
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 21d5665..0804df3 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -11,6 +11,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "windows.h"
+#include "winerror.h"
#include "class.h"
#include "file.h"
#include "global.h"
@@ -284,16 +285,11 @@
/**********************************************************************
- * 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 @@
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 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 @@
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 @@
{
/* 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 @@
{
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 c085678..fb3b168 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 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 @@
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 c5d3fce..90fb416 100644
--- a/loader/ne/resource.c
+++ b/loader/ne/resource.c
@@ -374,7 +374,7 @@
*/
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 @@
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 76dc87e..8ef9b73 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -827,8 +827,9 @@
* 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 @@
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 @@
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 @@
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 @@
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 bff00b9..798b8a5 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -66,7 +66,7 @@
*/
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 @@
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 @@
{
HRSRC32 hRsrc;
HACCEL32 hRetval;
+ DWORD size;
if (HIWORD(lpTableName))
TRACE(accel, "%p '%s'\n",
@@ -244,6 +248,13 @@
}
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 0023c65..c626721 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 7d1814d..099333e 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "windows.h"
#include "user.h"
@@ -55,6 +56,9 @@
static void TASK_YieldToSystem(TDB*);
+extern BOOL32 THREAD_InitDone;
+
+
/***********************************************************************
* TASK_InstallTHHook
*/
@@ -78,7 +82,6 @@
return (hFirstTask != hTask) ? hFirstTask : 0;
}
-
/***********************************************************************
* TASK_LinkTask
*/
@@ -222,8 +225,7 @@
*/
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 @@
{
/* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*/
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 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
{
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 @@
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 @@
{
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 @@
{
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 @@
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 @@
*/
HTASK16 WINAPI LockCurrentTask( BOOL16 bLock )
{
- if (bLock) hLockedTask = hCurrentTask;
+ if (bLock) hLockedTask = GetCurrentTask();
else hLockedTask = 0;
return hLockedTask;
}
@@ -845,9 +947,14 @@
*/
void WINAPI OldYield(void)
{
- TDB *pCurTask;
+ TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
- pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+ if ( !THREAD_IsWin16( THREAD_Current() ) )
+ {
+ FIXME(task, "called for Win32 thread (%04x)!\n", THREAD_Current()->teb_sel);
+ return;
+ }
+
if (pCurTask) pCurTask->nEvents++; /* Make sure we get back here */
TASK_YieldToSystem(pCurTask);
if (pCurTask) pCurTask->nEvents--;
@@ -859,7 +966,14 @@
*/
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 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 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 @@
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 @@
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 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 @@
{
TDB *pTask;
- if (!hTask) hTask = hCurrentTask;
+ if (!hTask) hTask = GetCurrentTask();
if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0;
return pTask->hQueue;
}
@@ -1012,7 +1140,7 @@
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 @@
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 @@
*/
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 @@
{
TDB *pTask;
- if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+ if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
return pTask->hPDB;
}
@@ -1159,7 +1287,7 @@
{
TDB *pTask;
- if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+ if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
return pTask->version;
}
@@ -1172,7 +1300,7 @@
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 @@
{
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 @@
{
TDB *pTask;
- if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+ if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0;
return pTask->hInstance;
}
@@ -1248,7 +1376,7 @@
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 @@
{
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 @@
{
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 420d9e2..c1d3170 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -25,7 +25,6 @@
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 db21377..007f473 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -73,7 +73,7 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 4c3125d..8cafd4a 100644
--- a/misc/imagelist.c
+++ b/misc/imagelist.c
@@ -556,7 +556,7 @@
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 @@
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 @@
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 0255049..b2b4ae0 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -668,6 +668,7 @@
if (nSize && talloced<nSize) {
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
}
+ TRACE(resource,"-- %s\n",target);
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
/* nSize is the MINIMUM size */
*((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced);
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 792a7db..495ea9b 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -137,7 +137,7 @@
*/
HFILE16 WINAPI LZInit16( HFILE16 hfSrc )
{
- return LZInit32( hfSrc );
+ return LZInit32( HFILE16_TO_HFILE32(hfSrc) );
}
diff --git a/misc/network.c b/misc/network.c
index 89664d0..9dcda9e 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -7,6 +7,9 @@
*/
#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
#include "windows.h"
#include "winerror.h"
@@ -426,6 +429,31 @@
}
/**************************************************************************
+ * 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]
*/
int WINAPI WNetGetError(LPWORD nError)
diff --git a/misc/registry.c b/misc/registry.c
index 6f7ff91..b2d1de4 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -99,7 +99,9 @@
} *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 @@
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 @@
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 @@
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 @@
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 @@
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 1b8ebbf..6cdeec8 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
- * <contact juergen.schmied@metronet.de 980624>
*/
#include <assert.h>
#include <stdlib.h>
@@ -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 @@
*
* 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 @@
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 @@
{ 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)
@@ -708,69 +359,6 @@
}
/*************************************************************************
- * 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
*/
static DWORD SHELL_GetResourceTable(HFILE32 hFile,LPBYTE *retptr)
@@ -1186,40 +774,6 @@
}
-/*************************************************************************
- * 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 @@
}
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 d0bfddd..1affb0a 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 @@
*
* 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 @@
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 e53813a..f6be7ad 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 6bb650e..a4e95f1 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 @@
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 @@
}
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 @@
}
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 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 @@
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 @@
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 @@
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 @@
}
}
+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 @@
{
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
(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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 3f08ac8..caac7a3 100644
--- a/msdos/vxd.c
+++ b/msdos/vxd.c
@@ -806,7 +806,7 @@
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 d3adc76..654206f 100644
--- a/multimedia/dsound.c
+++ b/multimedia/dsound.c
@@ -242,6 +242,7 @@
this->dsound->nrofbuffers--;
this->dsound->lpvtbl->fnRelease(this->dsound);
}
+ HeapFree(GetProcessHeap(),0,this->buffer);
HeapFree(GetProcessHeap(),0,this);
return 0;
}
@@ -784,7 +785,7 @@
/* 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;j<sizeof(playbuf)/sizeof(playbuf[0])/2;j++) {
dsb->playpos=(dsb->playpos+1)%buflen;
if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
diff --git a/multimedia/mmio.c b/multimedia/mmio.c
index f6bdc77..8443ca1 100644
--- a/multimedia/mmio.c
+++ b/multimedia/mmio.c
@@ -32,7 +32,7 @@
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 @@
}
/* 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 @@
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 @@
* 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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
}
} else {
count += mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) pch, (LPARAM) cch);
+ if (count>0) lpmminfo->lBufOffset += count;
}
}
@@ -366,12 +472,18 @@
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 @@
}
} else {
count = mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) pch, (LPARAM) cch);
+ lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
}
GlobalUnlock16(hmmio);
@@ -404,14 +517,28 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 458a5be..40d4424 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -162,13 +162,17 @@
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 @@
{
WAVEHDR waveHdr;
HGLOBAL16 hData;
- INT32 count, bufsize;
+ INT32 count, bufsize, left = mmckInfo.cksize;
bufsize = 64000;
hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
@@ -246,10 +250,12 @@
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 a3df02b..2480f27 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -394,6 +394,22 @@
tbuf += pad;
}
break;
+
+ case 32:
+ for (h=0;h<height;h++)
+ {
+ for (w=0;w<bmp->bitmap.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 @@
sbuf += pad;
}
break;
+ case 32:
+ for (h=0;h<height;h++)
+ {
+ for (w=0;w<bmp->bitmap.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 @@
* 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 @@
return 0;
}
-
/**********************************************************************
* LoadBitmap16 (USER.175)
*
diff --git a/objects/color.c b/objects/color.c
index 6487adb..65fdccc 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -816,9 +816,11 @@
{
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 20243c3..1899d48 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -1497,3 +1497,24 @@
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 91434d3..95575b4 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -927,9 +927,9 @@
* 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 @@
/***********************************************************************
* 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 @@
* 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 @@
* 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 bbe7198..134f4fc 100644
--- a/ole/Makefile.in
+++ b/ole/Makefile.in
@@ -8,7 +8,6 @@
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 3ddde11..0000000
--- 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 !!!
- * <contact juergen.schmied@metronet.de, 980801>
- */
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#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, (dwOut<dwCopy)? dwOut : dwCopy);
-
- if(*pszTail)
- { pszTail++;
- }
-
- TRACE(shell,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext),debugstr_a(pszOut),dwOut);
- return pszTail;
-}
-
-/**************************************************************************
-* 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
- { 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 4925648..f2355b1 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 5bfe3c7..228b01c 100644
--- a/ole/ole2.c
+++ b/ole/ole2.c
@@ -85,7 +85,7 @@
}
/***********************************************************************
- * RegisterDragDrop (OLE2.35)
+ * RegisterDragDrop16 (OLE2.35)
*/
HRESULT WINAPI RegisterDragDrop16(
HWND16 hwnd,
@@ -95,3 +95,13 @@
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 aaf3c7c..686f5b3 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -18,6 +18,9 @@
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 6acd6a8..ad759a5 100644
--- a/programs/clock/Makefile.in
+++ b/programs/clock/Makefile.in
@@ -49,6 +49,9 @@
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 46fed24..fe81933 100644
--- a/programs/notepad/Makefile.in
+++ b/programs/notepad/Makefile.in
@@ -49,6 +49,9 @@
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 0a6e2cd..6662fbd 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -54,6 +54,9 @@
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 98683d4..a1a1e8d 100644
--- a/programs/regtest/Makefile.in
+++ b/programs/regtest/Makefile.in
@@ -19,7 +19,10 @@
$(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 0aea7f6..b531e80 100644
--- a/programs/view/Makefile.in
+++ b/programs/view/Makefile.in
@@ -37,6 +37,9 @@
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 76c40f0..a95fa77 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -53,6 +53,9 @@
$(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 ed5911b..6082004 100644
--- a/programs/winver/Makefile.in
+++ b/programs/winver/Makefile.in
@@ -19,7 +19,10 @@
$(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 5ea46b4..04c579e 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -385,7 +385,7 @@
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 8c7aa82..c385cf6 100644
--- a/relay32/comctl32.spec
+++ b/relay32/comctl32.spec
@@ -114,11 +114,11 @@
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 087e09b..8f31000 100644
--- a/relay32/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -166,7 +166,7 @@
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 @@
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 8576577..2c08e16 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -12,15 +12,15 @@
# - 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 @@
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 @@
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 d1768b5..51d20e8 100644
--- a/relay32/mpr.spec
+++ b/relay32/mpr.spec
@@ -86,7 +86,7 @@
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 bb6197c..4883fdb 100644
--- a/relay32/ole32.spec
+++ b/relay32/ole32.spec
@@ -139,7 +139,7 @@
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 ecfefab..64e3546 100644
--- a/relay32/shell32.spec
+++ b/relay32/shell32.spec
@@ -22,7 +22,7 @@
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 @@
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 @@
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 @@
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 534607d..9bc4e38 100644
--- a/relay32/snoop.c
+++ b/relay32/snoop.c
@@ -4,7 +4,6 @@
* Copyright 1998 Marcus Meissner
*/
-#ifdef __i386__
#include <assert.h>
#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 2ebbdd7..98d51cc 100644
--- a/relay32/winmm.spec
+++ b/relay32/winmm.spec
@@ -5,7 +5,7 @@
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 @@
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 @@
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 4a35bcf..e39d82d 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -140,8 +140,9 @@
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 @@
return reply.handle;
}
+
/***********************************************************************
* CLIENT_GetProcessInfo
*
@@ -395,6 +397,22 @@
/***********************************************************************
+ * 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
*
* Open a handle to a process.
@@ -414,3 +432,26 @@
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 e154abe..4cd478a 100644
--- a/scheduler/critsection.c
+++ b/scheduler/critsection.c
@@ -156,7 +156,7 @@
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 @@
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 960e962..aebca61 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -21,6 +21,7 @@
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 @@
&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 3ccd3d2..3c1f94a 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -128,7 +128,8 @@
/***********************************************************************
* 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 @@
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 @@
*/
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 @@
/* 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 @@
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 @@
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 @@
}
+/******************************************************************************
+ * 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 @@
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 @@
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 229134c..4ed9a25 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 @@
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 @@
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,15 +316,51 @@
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)
*/
DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index d63d30f..9ec3b7a 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -115,6 +115,8 @@
*/
void SYSDEPS_ExitThread(void)
{
+ THDB *thdb = THREAD_Current();
+ close( thdb->socket );
_exit( 0 );
}
diff --git a/scheduler/syslevel.c b/scheduler/syslevel.c
index 50a5dd3..483dbb0 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 @@
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 2fabdbc..60365d5 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -9,6 +9,9 @@
#include <unistd.h>
#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 @@
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 @@
/**********************************************************************
- * TerminateThread [KERNEL32.???] Terminates a thread
+ * TerminateThread [KERNEL32.685] Terminates a thread
*
* RETURNS
* Success: TRUE
@@ -698,9 +715,15 @@
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 @@
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 17a6843..c05a310 100644
--- a/server/object.c
+++ b/server/object.c
@@ -69,6 +69,8 @@
{
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 @@
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 b3adcb2..06d3d63 100644
--- a/server/process.c
+++ b/server/process.c
@@ -6,6 +6,7 @@
#include <assert.h>
#include <limits.h>
+#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
@@ -54,12 +55,17 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 397fe4f..e481d76 100644
--- a/server/request.c
+++ b/server/request.c
@@ -7,6 +7,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
@@ -71,7 +72,7 @@
current = thread;
if (debug_level) trace_timeout();
CLEAR_ERROR();
- send_reply( current, -1, 0 );
+ thread_timeout();
current = NULL;
}
@@ -131,6 +132,12 @@
/* 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 @@
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 @@
}
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 5d96a93..fd85741 100644
--- a/server/socket.c
+++ b/server/socket.c
@@ -165,9 +165,6 @@
#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 @@
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 206e1a9..e250cc8 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/* 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 712edea..a9158ce 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1,6 +1,7 @@
/* File generated automatically by tools/make_requests; DO NOT EDIT!! */
#include <stdio.h>
+#include <sys/types.h>
#include <sys/uio.h>
#include "server.h"
#include "server/thread.h"
@@ -46,6 +47,17 @@
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 @@
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 @@
{ (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 @@
{ (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 @@
"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 76d8b7e..bd7f1e9 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1630,7 +1630,7 @@
#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 @@
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 @@
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 @@
#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 1cba580..f02bd43 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 @@
/* File generated automatically by $0; DO NOT EDIT!! */
#include <stdio.h>
+#include <sys/types.h>
#include <sys/uio.h>
#include "server.h"
#include "server/thread.h"
@@ -194,6 +195,7 @@
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 @@
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 @@
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 499e134..6508c01 100755
--- a/tools/testrun
+++ b/tools/testrun
@@ -223,31 +223,6 @@
#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=<RUNFILE>) {
- 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 7574bb5..9ce240e 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 <errno.h>
@@ -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 @@
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 */
+ "<KERNEL32.101>" /* 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 @@
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 @@
* 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 @@
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 @@
/* 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 @@
}
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 fd1de18..a595d86 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -138,16 +138,15 @@
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 08eca15..1be5f93 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 @@
(LPBYTE)ESP_reg(context)+4, argsize );
EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
+ EDX_reg(context) = HIWORD(EAX_reg(context));
}
@@ -378,6 +380,7 @@
}
EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
+ EDX_reg(context) = HIWORD(EAX_reg(context));
}
/**********************************************************************
@@ -1066,7 +1069,7 @@
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 @@
}
}
-/***********************************************************************
- * 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 693c5f7..ced6b06 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -361,32 +361,6 @@
}
/******************************************************************************
- * 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]
*
* NOTES
diff --git a/win32/ordinals.c b/win32/ordinals.c
index a9699cf..5b7427a 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -129,4 +129,3 @@
FIXME(win32,"(0x%08lx): stub\n",x);
return 1;
}
-
diff --git a/win32/process.c b/win32/process.c
index 3a85430..2e06bb4 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -59,50 +59,6 @@
}
/**********************************************************************
- * 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]
*/
BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) {
diff --git a/win32/time.c b/win32/time.c
index 9dc1e4c..fc82034 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -133,16 +133,6 @@
/***********************************************************************
- * Sleep (KERNEL32.523)
- */
-VOID WINAPI Sleep(DWORD cMilliseconds)
-{
- if(cMilliseconds == INFINITE32)
- while(1) sleep(1000); /* Spin forever */
- usleep(cMilliseconds*1000);
-}
-
-/***********************************************************************
* GetSystemTimeAsFileTime (KERNEL32)
*/
VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME systemtimeAsfiletime) {
diff --git a/windows/keyboard.c b/windows/keyboard.c
index ac4b542..667f2d5 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -277,13 +277,13 @@
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 @@
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)
{
@@ -832,6 +838,14 @@
/**********************************************************************
+ * ScreenSwitchEnable (KEYBOARD.100)
+ */
+VOID WINAPI ScreenSwitchEnable(WORD unused)
+{
+ FIXME(keyboard,"(%04x): stub\n",unused);
+}
+
+/**********************************************************************
* OemKeyScan (KEYBOARD.128)(USER32.401)
*/
DWORD WINAPI OemKeyScan(WORD wOemChar)
diff --git a/windows/mdi.c b/windows/mdi.c
index 3478cb4..dadc4c8 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -247,6 +247,23 @@
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 @@
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 4e8c632..972e6ef 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -449,7 +449,8 @@
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 @@
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 @@
}
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 @@
queue->InSendMessageHandle = 0;
QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
- DirectedYield( queue->hSendingTask );
+ if (THREAD_IsWin16(THREAD_Current())) DirectedYield( queue->hSendingTask );
}
@@ -729,6 +733,9 @@
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 441ea4a..831865f 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -320,7 +320,7 @@
{
WARN(dialog,"AppExit\n");
MessageBox32A( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
- TASK_KillCurrentTask(0);
+ ExitProcess(0);
}
@@ -331,7 +331,7 @@
{
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 712dea1..8ab1c80 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -217,6 +217,59 @@
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 @@
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 @@
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 1b09c8a..456f215 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 @@
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 @@
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 @@
/* 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 @@
/* 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 8bec519..74af90a 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 @@
* 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 @@
* 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 f62f86f..bb6ff92 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -730,6 +730,8 @@
*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;