From acca129036736dc6514e94687bf1a4cc9453b792 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Fri, 25 Jul 2008 17:01:31 +0200 Subject: [PATCH] push decde5eed3d79f9d889b4d757f73e86ce6ff9241 --- .gitignore | 4 +- Makefile.in | 4 + configure | 196 ++- configure.ac | 42 +- dlls/Makefile.in | 2 + dlls/advapi32/registry.c | 21 +- dlls/advapi32/security.c | 23 +- dlls/advapi32/service.c | 3 - dlls/advapi32/tests/registry.c | 36 + dlls/advpack/files.c | 2 +- dlls/advpack/install.c | 2 +- dlls/appwiz.cpl/En.rc | 78 + dlls/{mstask => appwiz.cpl}/Makefile.in | 8 +- dlls/appwiz.cpl/appwiz.c | 787 ++++++++++ dlls/appwiz.cpl/appwiz.cpl.spec | 1 + dlls/appwiz.cpl/appwiz.ico | Bin 0 -> 766 bytes dlls/appwiz.cpl/appwiz.rc | 32 + dlls/appwiz.cpl/res.h | 54 + dlls/avifil32/avifile.c | 4 +- dlls/cabinet/cabinet_main.c | 5 +- dlls/comctl32/animate.c | 2 +- dlls/comctl32/comboex.c | 2 +- dlls/comctl32/comctl32.h | 1 + dlls/comctl32/commctrl.c | 44 + dlls/comctl32/datetime.c | 22 +- dlls/comctl32/flatsb.c | 2 +- dlls/comctl32/header.c | 70 +- dlls/comctl32/hotkey.c | 2 +- dlls/comctl32/ipaddress.c | 2 +- dlls/comctl32/listview.c | 2 +- dlls/comctl32/monthcal.c | 2 +- dlls/comctl32/nativefont.c | 2 +- dlls/comctl32/progress.c | 2 +- dlls/comctl32/rebar.c | 2 +- dlls/comctl32/rsrc.rc | 4 +- dlls/comctl32/status.c | 67 +- dlls/comctl32/syslink.c | 2 +- dlls/comctl32/tab.c | 2 +- dlls/comctl32/tests/comboex.c | 2 +- dlls/comctl32/tests/mru.c | 6 +- dlls/comctl32/tests/status.c | 87 +- dlls/comctl32/tests/toolbar.c | 19 + dlls/comctl32/theme_button.c | 31 +- dlls/comctl32/toolbar.c | 36 +- dlls/comctl32/tooltips.c | 2 +- dlls/comctl32/trackbar.c | 2 +- dlls/comctl32/treeview.c | 2 +- dlls/comctl32/updown.c | 2 +- dlls/crtdll/crtdll_main.c | 16 +- dlls/crypt32/sip.c | 11 +- dlls/crypt32/tests/base64.c | 6 +- dlls/crypt32/tests/msg.c | 179 ++- dlls/crypt32/tests/protectdata.c | 21 +- dlls/crypt32/tests/sip.c | 48 +- dlls/cryptnet/tests/cryptnet.c | 49 +- dlls/d3d9/tests/vertexdeclaration.c | 55 + dlls/d3d9/tests/visual.c | 36 +- dlls/d3dx8/Makefile.in | 3 +- dlls/d3dx8/d3dx8.spec | 2 +- dlls/d3dx8/math.c | 70 +- dlls/{mstask/mstask_main.c => d3dx8/mesh.c} | 30 +- dlls/d3dx8/tests/Makefile.in | 4 +- dlls/d3dx8/tests/mesh.c | 51 + dlls/d3dx9_36/d3dx9_36.spec | 4 +- dlls/d3dx9_36/math.c | 36 +- dlls/d3dx9_36/shader.c | 7 + dlls/d3dx9_36/tests/math.c | 29 +- dlls/d3dx9_36/tests/shader.c | 17 + dlls/ddraw/device.c | 69 +- dlls/dnsapi/record.c | 7 +- dlls/dnsapi/tests/record.c | 8 + dlls/dplayx/dplay.c | 2 +- dlls/dplayx/dplay_global.h | 2 +- dlls/dplayx/dplaysp.c | 2 +- dlls/dplayx/name_server.c | 2 +- dlls/dplayx/name_server.h | 2 +- dlls/dpnet/regsvr.c | 10 + dlls/{mstask => dpwsockx}/Makefile.in | 4 +- dlls/dpwsockx/dpwsockx.spec | 3 + .../d3dx9shader.h => dlls/dpwsockx/dpwsockx_dll.h | 22 +- .../mstask_main.c => dpwsockx/dpwsockx_main.c} | 42 +- dlls/dsound/mixer.c | 7 +- dlls/gdi32/dc.c | 5 +- dlls/gdi32/dib.c | 9 +- dlls/gdi32/freetype.c | 11 +- dlls/gdi32/tests/font.c | 32 +- dlls/gdiplus/brush.c | 110 ++ dlls/gdiplus/font.c | 66 + dlls/gdiplus/gdiplus.spec | 20 +- dlls/gdiplus/gdiplus_private.h | 41 + dlls/gdiplus/region.c | 128 +- dlls/gdiplus/tests/brush.c | 97 +- dlls/gdiplus/tests/font.c | 2 - dlls/gdiplus/tests/image.c | 14 + dlls/gdiplus/tests/region.c | 84 +- dlls/hhctrl.ocx/webbrowser.c | 94 +- dlls/inetmib1/main.c | 45 +- dlls/kernel32/kernel32.spec | 6 +- dlls/kernel32/path.c | 26 + dlls/kernel32/sync.c | 72 +- dlls/kernel32/tests/locale.c | 2 +- dlls/kernel32/tests/sync.c | 259 +++- dlls/kernel32/tests/thread.c | 8 + dlls/mlang/mlang.c | 536 ++++++- dlls/mshtml/htmldoc.c | 63 +- dlls/mshtml/omnavigator.c | 9 +- dlls/mshtml/tests/dom.c | 36 + dlls/msi/action.c | 2 +- dlls/msi/files.c | 11 - dlls/msi/helpers.c | 6 +- dlls/msi/msipriv.h | 5 - dlls/msi/package.c | 2 +- dlls/msi/tests/install.c | 405 +++++- dlls/msi/tests/package.c | 396 +++++ dlls/mstask/Makefile.in | 8 +- dlls/mstask/factory.c | 108 ++ dlls/mstask/mstask.spec | 4 +- .../version.rc => mstask/mstask_local.idl} | 8 +- dlls/mstask/mstask_main.c | 24 +- dlls/mstask/{mstask_main.c => mstask_private.h} | 41 +- dlls/mstask/task_scheduler.c | 176 +++ dlls/msvcrt/data.c | 56 +- dlls/msvcrt/file.c | 2 +- dlls/msvcrt/locale.c | 10 +- dlls/msvcrt/mbcs.c | 2 +- dlls/msxml3/saxreader.c | 329 ++++- dlls/msxml3/tests/domdoc.c | 5 +- dlls/msxml3/tests/saxreader.c | 164 ++- dlls/ntdll/heap.c | 30 +- dlls/ntdll/ntdll.spec | 10 +- dlls/ntdll/string.c | 38 +- dlls/ntdll/tests/string.c | 29 + dlls/ntdll/threadpool.c | 467 ++++++ dlls/ntdll/virtual.c | 10 +- dlls/ntoskrnl.exe/ntoskrnl.c | 4 +- dlls/ole32/clipboard.c | 3 + dlls/ole32/compobj.c | 3 +- dlls/ole32/tests/clipboard.c | 6 + dlls/oleaut32/olepicture.c | 13 +- dlls/oleaut32/safearray.c | 2 + dlls/oleaut32/tests/safearray.c | 16 +- dlls/oleaut32/tests/tmarshal.c | 4 +- dlls/oleaut32/tests/typelib.c | 4 +- dlls/oleaut32/tests/vartype.c | 6 +- dlls/oleaut32/version.rc | 2 + dlls/quartz/avisplit.c | 62 +- dlls/quartz/pin.c | 18 +- dlls/quartz/tests/avisplitter.c | 2 +- dlls/riched20/editor.c | 21 + dlls/riched20/editstr.h | 3 + dlls/riched20/paint.c | 36 +- dlls/riched20/tests/editor.c | 739 +++++++++- dlls/rpcrt4/epm_towers.h | 2 +- dlls/setupapi/tests/devinst.c | 4 +- dlls/setupapi/tests/misc.c | 1 + dlls/setupapi/tests/query.c | 2 + dlls/shell32/autocomplete.c | 3 +- dlls/shell32/control.c | 488 +++++-- dlls/shell32/cpanel.h | 19 +- dlls/shell32/cpanelfolder.c | 1 + dlls/shell32/shell32_Bg.rc | 26 + dlls/shell32/shell32_Ca.rc | 30 + dlls/shell32/shell32_Cn.rc | 26 + dlls/shell32/shell32_Cs.rc | 26 + dlls/shell32/shell32_Da.rc | 26 + dlls/shell32/shell32_De.rc | 26 + dlls/shell32/shell32_En.rc | 26 + dlls/shell32/shell32_Eo.rc | 26 + dlls/shell32/shell32_Es.rc | 26 + dlls/shell32/shell32_Fi.rc | 26 + dlls/shell32/shell32_Fr.rc | 26 + dlls/shell32/shell32_Hu.rc | 29 + dlls/shell32/shell32_It.rc | 26 + dlls/shell32/shell32_Ja.rc | 26 + dlls/shell32/shell32_Ko.rc | 27 + dlls/shell32/shell32_Nl.rc | 26 + dlls/shell32/shell32_No.rc | 26 + dlls/shell32/shell32_Pl.rc | 26 + dlls/shell32/shell32_Pt.rc | 55 + dlls/shell32/shell32_Ro.rc | 26 + dlls/shell32/shell32_Ru.rc | 26 + dlls/shell32/shell32_Si.rc | 26 + dlls/shell32/shell32_Sk.rc | 26 + dlls/shell32/shell32_Sv.rc | 29 + dlls/shell32/shell32_Tr.rc | 26 + dlls/shell32/shell32_Uk.rc | 26 + dlls/shell32/shell32_Wa.rc | 29 + dlls/shell32/shell32_Zh.rc | 26 + dlls/shell32/shellpath.c | 5 +- dlls/shell32/shresdef.h | 9 + dlls/shell32/tests/shelllink.c | 30 +- dlls/shell32/tests/shlexec.c | 47 +- dlls/snmpapi/tests/util.c | 1 + dlls/user32/dde_misc.c | 3 +- dlls/user32/painting.c | 2 + dlls/user32/tests/cursoricon.c | 39 +- dlls/user32/tests/input.c | 1 + dlls/user32/tests/menu.c | 8 +- dlls/user32/tests/sysparams.c | 3 +- dlls/user32/winpos.c | 14 +- dlls/usp10/tests/usp10.c | 32 +- dlls/uxtheme/tests/system.c | 4 +- dlls/wined3d/arb_program_shader.c | 45 +- dlls/wined3d/context.c | 161 ++- dlls/wined3d/device.c | 7 +- dlls/wined3d/directx.c | 15 +- dlls/wined3d/glsl_shader.c | 35 + dlls/wined3d/nvidia_texture_shader.c | 385 +++++ dlls/wined3d/state.c | 1117 +++++++++++++- dlls/wined3d/surface.c | 12 +- dlls/wined3d/utils.c | 1527 +------------------- dlls/wined3d/vertexdeclaration.c | 6 + dlls/wined3d/wined3d_private.h | 3 +- dlls/wineps.drv/Makefile.in | 2 +- dlls/winex11.drv/dib.c | 4 +- dlls/winex11.drv/keyboard.c | 33 + dlls/wininet/ftp.c | 10 +- dlls/wininet/http.c | 74 +- dlls/wininet/internet.c | 534 +++---- dlls/wininet/internet.h | 2 + dlls/wininet/tests/ftp.c | 2 - dlls/wininet/tests/http.c | 58 +- dlls/wininet/tests/internet.c | 4 +- dlls/winmm/tests/mci.c | 12 + dlls/winspool.drv/Makefile.in | 1 + dlls/wintrust/crypt.c | 247 +++- dlls/wintrust/tests/softpub.c | 2 +- include/Makefile.in | 2 - include/config.h.in | 3 + include/d3dx8mesh.h | 3 +- include/d3dx9math.h | 1 + include/d3dx9shader.h | 1 + include/gdiplusflat.h | 12 + include/mlang.idl | 88 ++ include/msidefs.h | 8 + include/vmrender.idl | 2 +- include/winbase.h | 1 + {dlls/dplayx => include/wine}/dplaysp.h | 0 include/wine/wined3d_gl.h | 15 + include/wine/wined3d_types.h | 2 + include/winhttp.h | 301 +++- include/winnt.h | 4 + include/winternl.h | 5 + loader/kthread.c | 4 +- programs/regedit/regproc.c | 2 - programs/winedbg/display.c | 10 +- programs/winetest/send.c | 6 +- programs/wordpad/Nl.rc | 2 + programs/wordpad/print.c | 2 +- programs/wordpad/wordpad.c | 2 +- programs/wordpad/wordpad.h | 2 +- server/thread.c | 3 +- tools/make_makefiles | 33 +- tools/runtest | 8 +- tools/wine.inf.in | 1 + tools/winebuild/build.h | 2 +- tools/winebuild/main.c | 3 + tools/winebuild/spec32.c | 14 +- tools/winegcc/winegcc.c | 17 + 259 files changed, 10906 insertions(+), 3088 deletions(-) create mode 100644 dlls/appwiz.cpl/En.rc copy dlls/{mstask => appwiz.cpl}/Makefile.in (63%) create mode 100644 dlls/appwiz.cpl/appwiz.c create mode 100644 dlls/appwiz.cpl/appwiz.cpl.spec create mode 100644 dlls/appwiz.cpl/appwiz.ico create mode 100644 dlls/appwiz.cpl/appwiz.rc create mode 100644 dlls/appwiz.cpl/res.h copy dlls/{mstask/mstask_main.c => d3dx8/mesh.c} (59%) create mode 100644 dlls/d3dx8/tests/mesh.c copy dlls/{mstask => dpwsockx}/Makefile.in (83%) create mode 100644 dlls/dpwsockx/dpwsockx.spec copy include/d3dx9shader.h => dlls/dpwsockx/dpwsockx_dll.h (74%) copy dlls/{mstask/mstask_main.c => dpwsockx/dpwsockx_main.c} (54%) create mode 100644 dlls/mstask/factory.c copy dlls/{oleaut32/version.rc => mstask/mstask_local.idl} (79%) copy dlls/mstask/{mstask_main.c => mstask_private.h} (64%) create mode 100644 dlls/mstask/task_scheduler.c rename {dlls/dplayx => include/wine}/dplaysp.h (100%) diff --git a/.gitignore b/.gitignore index ab49a43c725..72a2fdb9710 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,8 @@ dlls/msi/msiserver.tlb dlls/msi/msiserver_i.c dlls/msi/sql.tab.c dlls/msi/sql.tab.h +dlls/mstask/mstask_local.h +dlls/mstask/mstask_local_i.c dlls/msvideo.dll16 dlls/msxml3/msxml3_v1.tlb dlls/ole2.dll16 @@ -181,8 +183,6 @@ include/unknwn.h include/urlhist.h include/urlmon.h include/vmr9.h -include/wine/dcetypes.h -include/wine/epm.h include/wine/itss.h include/wine/svcctl.h include/wtypes.h diff --git a/Makefile.in b/Makefile.in index 1e7f4d878a5..bb1ec014d2d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -174,6 +174,7 @@ ALL_MAKEFILES = \ dlls/advpack/Makefile \ dlls/advpack/tests/Makefile \ dlls/amstream/Makefile \ + dlls/appwiz.cpl/Makefile \ dlls/atl/Makefile \ dlls/avicap32/Makefile \ dlls/avifil32/Makefile \ @@ -257,6 +258,7 @@ ALL_MAKEFILES = \ dlls/dpnet/Makefile \ dlls/dpnhpast/Makefile \ dlls/dpnlobby/Makefile \ + dlls/dpwsockx/Makefile \ dlls/dsound/Makefile \ dlls/dsound/tests/Makefile \ dlls/dssenh/Makefile \ @@ -605,6 +607,7 @@ dlls/advapi32/tests/Makefile: dlls/advapi32/tests/Makefile.in dlls/Maketest.rule dlls/advpack/Makefile: dlls/advpack/Makefile.in dlls/Makedll.rules dlls/advpack/tests/Makefile: dlls/advpack/tests/Makefile.in dlls/Maketest.rules dlls/amstream/Makefile: dlls/amstream/Makefile.in dlls/Makedll.rules +dlls/appwiz.cpl/Makefile: dlls/appwiz.cpl/Makefile.in dlls/Makedll.rules dlls/atl/Makefile: dlls/atl/Makefile.in dlls/Makedll.rules dlls/avicap32/Makefile: dlls/avicap32/Makefile.in dlls/Makedll.rules dlls/avifil32/Makefile: dlls/avifil32/Makefile.in dlls/Makedll.rules @@ -688,6 +691,7 @@ dlls/dpnaddr/Makefile: dlls/dpnaddr/Makefile.in dlls/Makedll.rules dlls/dpnet/Makefile: dlls/dpnet/Makefile.in dlls/Makedll.rules dlls/dpnhpast/Makefile: dlls/dpnhpast/Makefile.in dlls/Makedll.rules dlls/dpnlobby/Makefile: dlls/dpnlobby/Makefile.in dlls/Makedll.rules +dlls/dpwsockx/Makefile: dlls/dpwsockx/Makefile.in dlls/Makedll.rules dlls/dsound/Makefile: dlls/dsound/Makefile.in dlls/Makedll.rules dlls/dsound/tests/Makefile: dlls/dsound/tests/Makefile.in dlls/Maketest.rules dlls/dssenh/Makefile: dlls/dssenh/Makefile.in dlls/Makedll.rules diff --git a/configure b/configure index 633c20bbcf4..8432bac3dbb 100755 --- a/configure +++ b/configure @@ -761,10 +761,11 @@ FREETYPELIBS FREETYPEINCL FONTSSUBDIRS ESDCONFIG -ESDLIBS ESDINCL +ESDLIBS ALSALIBS AUDIOIOLIBS +CUPSINCL FONTCONFIGINCL EXTRACFLAGS BUILTINFLAG @@ -1953,7 +1954,7 @@ fi # Check whether --with-cups was given. if test "${with_cups+set}" = set; then - withval=$with_cups; if test "x$withval" = "xno"; then ac_cv_header_cups_cups_h=no; fi + withval=$with_cups; fi @@ -7243,7 +7244,6 @@ for ac_header in \ arpa/nameser.h \ asm/types.h \ capi20.h \ - cups/cups.h \ curses.h \ direct.h \ dlfcn.h \ @@ -7342,7 +7342,8 @@ for ac_header in \ termios.h \ unistd.h \ utime.h \ - valgrind/memcheck.h + valgrind/memcheck.h \ + valgrind/valgrind.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` @@ -13052,6 +13053,7 @@ fi if test "$sane_devel" != "no" -a "x$with_sane" != "xno" then ac_sane_incl="`$sane_devel --cflags`" + ac_sane_libs="`$sane_devel --ldflags`" ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ac_sane_incl" if test "${ac_cv_header_sane_sane_h+set}" = set; then @@ -13191,7 +13193,7 @@ if test "${ac_cv_lib_soname_sane+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_soname_save_LIBS=$LIBS -LIBS="-lsane $LIBS" +LIBS="-lsane $ac_sane_libs $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -13508,7 +13510,7 @@ if test "${ac_cv_lib_gphoto2_gp_camera_new+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lgphoto2 $GPHOTO2LIBS $LIBS" +LIBS="-lgphoto2 $ac_gphoto2_libs $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -14653,23 +14655,23 @@ fi if test "x$with_esd" != xno -a "x$ESDCONFIG" != x -a "x$ESDCONFIG" != x'"$ESDCONFIG"'; then - ESD_CFLAGS="" + ac_esd_incl="" for i in `$ESDCONFIG --cflags` do case "$i" in - -I*) ESD_CFLAGS="$ESD_CFLAGS $i";; + -I*) ac_esd_incl="$ac_esd_incl $i";; esac done - ESD_LIBS=`$ESDCONFIG --libs` + ac_esd_libs=`$ESDCONFIG --libs` save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ESD_CFLAGS" + CFLAGS="$CFLAGS $ac_esd_incl" { echo "$as_me:$LINENO: checking for esd_open_sound in -lesd" >&5 echo $ECHO_N "checking for esd_open_sound in -lesd... $ECHO_C" >&6; } if test "${ac_cv_lib_esd_esd_open_sound+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lesd $LIBS" +LIBS="-lesd $ac_esd_libs $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -14725,9 +14727,9 @@ fi { echo "$as_me:$LINENO: result: $ac_cv_lib_esd_esd_open_sound" >&5 echo "${ECHO_T}$ac_cv_lib_esd_esd_open_sound" >&6; } if test $ac_cv_lib_esd_esd_open_sound = yes; then - ESDLIBS=$ESD_LIBS + ESDINCL="$ac_esd_incl" - ESDINCL=$ESD_CFLAGS + ESDLIBS="$ac_esd_libs" cat >>confdefs.h <<\_ACEOF @@ -15030,15 +15032,161 @@ esac fi -if test "$ac_cv_header_cups_cups_h" = "yes" +CUPSINCL="" + +if test "x$with_cups" != "xno" then - { echo "$as_me:$LINENO: checking for -lcups" >&5 + ac_save_CPPFLAGS="$CPPFLAGS" + ac_cups_cflags=`cups-config --cflags 2>/dev/null` + ac_cups_libs="`cups-config --ldflags 2>/dev/null` `cups-config --libs 2>/dev/null`" + CPPFLAGS="$CPPFLAGS $ac_cups_cflags" + +for ac_header in cups/cups.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------ ## +## Report this to wine-devel@winehq.org ## +## ------------------------------------ ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + { echo "$as_me:$LINENO: checking for -lcups" >&5 echo $ECHO_N "checking for -lcups... $ECHO_C" >&6; } if test "${ac_cv_lib_soname_cups+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_soname_save_LIBS=$LIBS -LIBS="-lcups $LIBS" +LIBS="-lcups $ac_cups_libs $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -15107,9 +15255,14 @@ cat >>confdefs.h <<_ACEOF #define SONAME_LIBCUPS "$ac_cv_lib_soname_cups" _ACEOF + CUPSINCL="$ac_cups_cflags" +fi fi +done + + CPPFLAGS="$ac_save_CPPFLAGS" fi if test "x$ac_cv_lib_soname_cups" = "x"; then case "x$with_cups" in @@ -21795,6 +21948,8 @@ ac_config_files="$ac_config_files dlls/advpack/tests/Makefile" ac_config_files="$ac_config_files dlls/amstream/Makefile" +ac_config_files="$ac_config_files dlls/appwiz.cpl/Makefile" + ac_config_files="$ac_config_files dlls/atl/Makefile" ac_config_files="$ac_config_files dlls/avicap32/Makefile" @@ -21961,6 +22116,8 @@ ac_config_files="$ac_config_files dlls/dpnhpast/Makefile" ac_config_files="$ac_config_files dlls/dpnlobby/Makefile" +ac_config_files="$ac_config_files dlls/dpwsockx/Makefile" + ac_config_files="$ac_config_files dlls/dsound/Makefile" ac_config_files="$ac_config_files dlls/dsound/tests/Makefile" @@ -23185,6 +23342,7 @@ do "dlls/advpack/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/advpack/Makefile" ;; "dlls/advpack/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/advpack/tests/Makefile" ;; "dlls/amstream/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/amstream/Makefile" ;; + "dlls/appwiz.cpl/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/appwiz.cpl/Makefile" ;; "dlls/atl/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/atl/Makefile" ;; "dlls/avicap32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/avicap32/Makefile" ;; "dlls/avifil32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/avifil32/Makefile" ;; @@ -23268,6 +23426,7 @@ do "dlls/dpnet/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dpnet/Makefile" ;; "dlls/dpnhpast/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dpnhpast/Makefile" ;; "dlls/dpnlobby/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dpnlobby/Makefile" ;; + "dlls/dpwsockx/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dpwsockx/Makefile" ;; "dlls/dsound/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dsound/Makefile" ;; "dlls/dsound/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dsound/tests/Makefile" ;; "dlls/dssenh/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dssenh/Makefile" ;; @@ -23863,10 +24022,11 @@ FREETYPELIBS!$FREETYPELIBS$ac_delim FREETYPEINCL!$FREETYPEINCL$ac_delim FONTSSUBDIRS!$FONTSSUBDIRS$ac_delim ESDCONFIG!$ESDCONFIG$ac_delim -ESDLIBS!$ESDLIBS$ac_delim ESDINCL!$ESDINCL$ac_delim +ESDLIBS!$ESDLIBS$ac_delim ALSALIBS!$ALSALIBS$ac_delim AUDIOIOLIBS!$AUDIOIOLIBS$ac_delim +CUPSINCL!$CUPSINCL$ac_delim FONTCONFIGINCL!$FONTCONFIGINCL$ac_delim EXTRACFLAGS!$EXTRACFLAGS$ac_delim BUILTINFLAG!$BUILTINFLAG$ac_delim @@ -23883,7 +24043,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 82; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 83; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.ac b/configure.ac index f0ff217f7da..8dc6c5a3a7c 100644 --- a/configure.ac +++ b/configure.ac @@ -27,8 +27,7 @@ AC_ARG_WITH(cms, AS_HELP_STRING([--without-cms],[do not use CMS (color man [if test "x$withval" = "xno"; then ac_cv_header_lcms_h=no; ac_cv_header_lcms_lcms_h=no; fi]) AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support]), [if test "x$withval" = "xno"; then ac_cv_header_CoreAudio_CoreAudio_h=no; fi]) -AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS]), - [if test "x$withval" = "xno"; then ac_cv_header_cups_cups_h=no; fi]) +AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS])) AC_ARG_WITH(curses, AS_HELP_STRING([--without-curses],[do not use (n)curses]), [if test "x$withval" = "xno"; then ac_cv_header_ncurses_h=no; ac_cv_header_curses_h=no; fi]) AC_ARG_WITH(esd, AS_HELP_STRING([--without-esd],[do not use the EsounD sound support])) @@ -249,7 +248,6 @@ AC_CHECK_HEADERS(\ arpa/nameser.h \ asm/types.h \ capi20.h \ - cups/cups.h \ curses.h \ direct.h \ dlfcn.h \ @@ -348,7 +346,8 @@ AC_CHECK_HEADERS(\ termios.h \ unistd.h \ utime.h \ - valgrind/memcheck.h + valgrind/memcheck.h \ + valgrind/valgrind.h ) AC_HEADER_STAT() @@ -931,10 +930,11 @@ AC_CHECK_PROG(sane_devel,sane-config,sane-config,no) if test "$sane_devel" != "no" -a "x$with_sane" != "xno" then ac_sane_incl="`$sane_devel --cflags`" + ac_sane_libs="`$sane_devel --ldflags`" ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ac_sane_incl" AC_CHECK_HEADER(sane/sane.h, - [WINE_CHECK_SONAME(sane,sane_init,[AC_SUBST(SANEINCL,"$ac_sane_incl")])]) + [WINE_CHECK_SONAME(sane,sane_init,[AC_SUBST(SANEINCL,"$ac_sane_incl")],,[$ac_sane_libs])]) CPPFLAGS="$ac_save_CPPFLAGS" fi WINE_NOTICE_WITH(sane,[test "x$ac_cv_lib_soname_sane" = "x"], @@ -961,7 +961,7 @@ then [AC_DEFINE(HAVE_GPHOTO2, 1, [Define if we have libgphoto2 development environment]) AC_SUBST(GPHOTO2LIBS,"$ac_gphoto2_libs") AC_SUBST(GPHOTO2INCL,"$ac_gphoto2_incl")],, - [$GPHOTO2LIBS])]) + [$ac_gphoto2_libs])]) CPPFLAGS="$ac_save_CPPFLAGS" fi WINE_NOTICE_WITH(gphoto,[test "$ac_cv_lib_gphoto2_gp_camera_new" != "yes"], @@ -1080,20 +1080,21 @@ dnl **** Check for EsounD **** AC_PATH_PROG(ESDCONFIG, esd-config) if test "x$with_esd" != xno -a "x$ESDCONFIG" != x -a "x$ESDCONFIG" != x'"$ESDCONFIG"'; then - ESD_CFLAGS="" + ac_esd_incl="" for i in `$ESDCONFIG --cflags` do case "$i" in - -I*) ESD_CFLAGS="$ESD_CFLAGS $i";; + -I*) ac_esd_incl="$ac_esd_incl $i";; esac done - ESD_LIBS=`$ESDCONFIG --libs` + ac_esd_libs=`$ESDCONFIG --libs` save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $ESD_CFLAGS" + CFLAGS="$CFLAGS $ac_esd_incl" AC_CHECK_LIB(esd,esd_open_sound, - [AC_SUBST(ESDLIBS, $ESD_LIBS) - AC_SUBST(ESDINCL, $ESD_CFLAGS) - AC_DEFINE(HAVE_ESD, 1, [Define if you have EsounD sound server])]) + [AC_SUBST(ESDINCL, "$ac_esd_incl") + AC_SUBST(ESDLIBS, "$ac_esd_libs") + AC_DEFINE(HAVE_ESD, 1, [Define if you have EsounD sound server])],, + [$ac_esd_libs]) CFLAGS="$save_CFLAGS" fi @@ -1130,9 +1131,18 @@ WINE_NOTICE_WITH(capi,[test "x$ac_cv_lib_soname_capi20" = "x"], [libcapi20 development files not found, ISDN won't be supported.]) dnl **** Check for cups **** -if test "$ac_cv_header_cups_cups_h" = "yes" +AC_SUBST(CUPSINCL,"") +if test "x$with_cups" != "xno" then - WINE_CHECK_SONAME(cups,cupsGetDefault) + ac_save_CPPFLAGS="$CPPFLAGS" + ac_cups_cflags=`cups-config --cflags 2>/dev/null` + ac_cups_libs="`cups-config --ldflags 2>/dev/null` `cups-config --libs 2>/dev/null`" + CPPFLAGS="$CPPFLAGS $ac_cups_cflags" + AC_CHECK_HEADERS(cups/cups.h, + [WINE_CHECK_SONAME(cups,cupsGetDefault, + [CUPSINCL="$ac_cups_cflags"],, + [$ac_cups_libs])]) + CPPFLAGS="$ac_save_CPPFLAGS" fi WINE_NOTICE_WITH(cups,[test "x$ac_cv_lib_soname_cups" = "x"], [libcups development files not found, CUPS won't be supported.]) @@ -1727,6 +1737,7 @@ AC_CONFIG_FILES([dlls/advapi32/tests/Makefile]) AC_CONFIG_FILES([dlls/advpack/Makefile]) AC_CONFIG_FILES([dlls/advpack/tests/Makefile]) AC_CONFIG_FILES([dlls/amstream/Makefile]) +AC_CONFIG_FILES([dlls/appwiz.cpl/Makefile]) AC_CONFIG_FILES([dlls/atl/Makefile]) AC_CONFIG_FILES([dlls/avicap32/Makefile]) AC_CONFIG_FILES([dlls/avifil32/Makefile]) @@ -1810,6 +1821,7 @@ AC_CONFIG_FILES([dlls/dpnaddr/Makefile]) AC_CONFIG_FILES([dlls/dpnet/Makefile]) AC_CONFIG_FILES([dlls/dpnhpast/Makefile]) AC_CONFIG_FILES([dlls/dpnlobby/Makefile]) +AC_CONFIG_FILES([dlls/dpwsockx/Makefile]) AC_CONFIG_FILES([dlls/dsound/Makefile]) AC_CONFIG_FILES([dlls/dsound/tests/Makefile]) AC_CONFIG_FILES([dlls/dssenh/Makefile]) diff --git a/dlls/Makefile.in b/dlls/Makefile.in index c1062a89299..bbe28106899 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -24,6 +24,7 @@ BASEDIRS = \ advapi32 \ advpack \ amstream \ + appwiz.cpl \ atl \ avicap32 \ avifil32 \ @@ -90,6 +91,7 @@ BASEDIRS = \ dpnet \ dpnhpast \ dpnlobby \ + dpwsockx \ dsound \ dssenh \ dswave \ diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 9ce3da06330..4c97ed1338c 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -44,9 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg); -/* allowed bits for access mask */ -#define KEY_ACCESS_MASK (KEY_ALL_ACCESS | MAXIMUM_ALLOWED) - #define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT #define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA #define NB_SPECIAL_ROOT_KEYS ((UINT)HKEY_SPECIAL_ROOT_LAST - (UINT)HKEY_SPECIAL_ROOT_FIRST + 1) @@ -188,7 +185,6 @@ LSTATUS WINAPI RegCreateKeyExW( HKEY hkey, LPCWSTR name, DWORD reserved, LPWSTR UNICODE_STRING nameW, classW; if (reserved) return ERROR_INVALID_PARAMETER; - if (!(access & KEY_ACCESS_MASK) || (access & ~KEY_ACCESS_MASK)) return ERROR_ACCESS_DENIED; if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; attr.Length = sizeof(attr); @@ -243,7 +239,6 @@ LSTATUS WINAPI RegCreateKeyExA( HKEY hkey, LPCSTR name, DWORD reserved, LPSTR cl access = KEY_ALL_ACCESS; /* Win95 ignores the access mask */ if (name && *name == '\\') name++; /* win9x,ME ignores one (and only one) beginning backslash */ } - else if (!(access & KEY_ACCESS_MASK) || (access & ~KEY_ACCESS_MASK)) return ERROR_ACCESS_DENIED; if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; attr.Length = sizeof(attr); @@ -470,8 +465,8 @@ LSTATUS WINAPI RegEnumKeyExW( HKEY hkey, DWORD index, LPWSTR name, LPDWORD name_ KEY_NODE_INFORMATION *info = (KEY_NODE_INFORMATION *)buffer; DWORD total_size; - TRACE( "(%p,%d,%p,%p(%d),%p,%p,%p,%p)\n", hkey, index, name, name_len, - name_len ? *name_len : -1, reserved, class, class_len, ft ); + TRACE( "(%p,%d,%p,%p(%u),%p,%p,%p,%p)\n", hkey, index, name, name_len, + name_len ? *name_len : 0, reserved, class, class_len, ft ); if (reserved) return ERROR_INVALID_PARAMETER; if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; @@ -534,8 +529,8 @@ LSTATUS WINAPI RegEnumKeyExA( HKEY hkey, DWORD index, LPSTR name, LPDWORD name_l KEY_NODE_INFORMATION *info = (KEY_NODE_INFORMATION *)buffer; DWORD total_size; - TRACE( "(%p,%d,%p,%p(%d),%p,%p,%p,%p)\n", hkey, index, name, name_len, - name_len ? *name_len : -1, reserved, class, class_len, ft ); + TRACE( "(%p,%d,%p,%p(%u),%p,%p,%p,%p)\n", hkey, index, name, name_len, + name_len ? *name_len : 0, reserved, class, class_len, ft ); if (reserved) return ERROR_INVALID_PARAMETER; if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; @@ -1466,6 +1461,8 @@ static VOID ADVAPI_ApplyRestrictions( DWORD dwFlags, DWORD dwType, * expanded and pdwType is set to REG_SZ instead. * - Restrictions are applied after expanding, using RRF_RT_REG_EXPAND_SZ * without RRF_NOEXPAND is thus not allowed. + * An exception is the case where RRF_RT_ANY is specified, because then + * RRF_NOEXPAND is allowed. */ LSTATUS WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, @@ -1481,7 +1478,8 @@ LSTATUS WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, if (pvData && !pcbData) return ERROR_INVALID_PARAMETER; - if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND)) + if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND) && + ((dwFlags & RRF_RT_ANY) != RRF_RT_ANY)) return ERROR_INVALID_PARAMETER; if (pszSubKey && pszSubKey[0]) @@ -1576,7 +1574,8 @@ LSTATUS WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, if (pvData && !pcbData) return ERROR_INVALID_PARAMETER; - if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND)) + if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND) && + ((dwFlags & RRF_RT_ANY) != RRF_RT_ANY)) return ERROR_INVALID_PARAMETER; if (pszSubKey && pszSubKey[0]) diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 3423cbee6f5..95b7a7b2bd6 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -2119,28 +2119,31 @@ LookupAccountSidW( } if (dm) { + DWORD ac_len = lstrlenW(ac); + DWORD dm_len = lstrlenW(dm); BOOL status = TRUE; - if (*accountSize > lstrlenW(ac)) { + + if (*accountSize > ac_len) { if (account) lstrcpyW(account, ac); } - if (*domainSize > lstrlenW(dm)) { + if (*domainSize > dm_len) { if (domain) lstrcpyW(domain, dm); } - if (((*accountSize != 0) && (*accountSize < strlenW(ac))) || - ((*domainSize != 0) && (*domainSize < strlenW(dm)))) { + if (((*accountSize != 0) && (*accountSize < ac_len)) || + ((*domainSize != 0) && (*domainSize < dm_len))) { SetLastError(ERROR_INSUFFICIENT_BUFFER); status = FALSE; } if (*domainSize) - *domainSize = strlenW(dm); + *domainSize = dm_len; else - *domainSize = strlenW(dm) + 1; + *domainSize = dm_len + 1; if (*accountSize) - *accountSize = strlenW(ac); + *accountSize = ac_len; else - *accountSize = strlenW(ac) + 1; + *accountSize = ac_len + 1; *name_use = use; HeapFree(GetProcessHeap(), 0, computer_name); return status; @@ -4050,7 +4053,7 @@ static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen) static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen) { - int i; + size_t i; for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) { if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision))) @@ -4102,7 +4105,7 @@ static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) { static const WCHAR fmtW[] = {'0','x','%','x',0}; WCHAR buf[15]; - int i; + size_t i; if (mask == 0) return; diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index c04eb8cef69..45666ab9b31 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -1599,9 +1599,6 @@ QueryServiceConfigW( SC_HANDLE hService, move_string_to_buffer(&bufpos, &lpServiceConfig->lpServiceStartName); move_string_to_buffer(&bufpos, &lpServiceConfig->lpDisplayName); - if (bufpos - (LPBYTE)lpServiceConfig > cbBufSize) - ERR("Buffer overflow!\n"); - TRACE("Image path = %s\n", debugstr_w(lpServiceConfig->lpBinaryPathName) ); TRACE("Group = %s\n", debugstr_w(lpServiceConfig->lpLoadOrderGroup) ); TRACE("Dependencies = %s\n", debugstr_w(lpServiceConfig->lpDependencies) ); diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index c4f039afc6f..94ce15af034 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -858,6 +858,16 @@ static void test_get_value(void) /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ (not allowed without RRF_NOEXPAND) */ ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ, NULL, NULL, NULL); ok(ret == ERROR_INVALID_PARAMETER, "ret=%d\n", ret); + + /* Query REG_EXPAND_SZ using RRF_RT_ANY */ + buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); + ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_ANY, &type, buf, &size); + ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); + /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */ + ok(size == strlen(expanded)+1 || broken(size == strlen(sTestpath1)+1), + "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded), lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%d\n", type); + ok(!strcmp(expanded, buf), "expanded=\"%s\" buf=\"%s\"\n", expanded, buf); } static void test_reg_open_key(void) @@ -939,6 +949,19 @@ static void test_reg_open_key(void) ok(ret == ERROR_BAD_PATHNAME || /* NT/2k/XP */ ret == ERROR_FILE_NOT_FOUND /* Win9x,ME */ , "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret); + + /* WOW64 flags */ + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WOW64_32KEY, &hkResult); + ok((ret == ERROR_SUCCESS && hkResult != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), + "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + RegCloseKey(hkResult); + + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WOW64_64KEY, &hkResult); + ok((ret == ERROR_SUCCESS && hkResult != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), + "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + RegCloseKey(hkResult); } static void test_reg_create_key(void) @@ -964,6 +987,19 @@ static void test_reg_create_key(void) ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); RegDeleteKey(hkey1, NULL); } + + /* WOW64 flags - open an existing key */ + hkey1 = NULL; + ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_READ|KEY_WOW64_32KEY, NULL, &hkey1, NULL); + ok((ret == ERROR_SUCCESS && hkey1 != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), + "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + RegCloseKey(hkey1); + + hkey1 = NULL; + ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_READ|KEY_WOW64_64KEY, NULL, &hkey1, NULL); + ok((ret == ERROR_SUCCESS && hkey1 != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), + "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + RegCloseKey(hkey1); } static void test_reg_close_key(void) diff --git a/dlls/advpack/files.c b/dlls/advpack/files.c index 5e9ce30fee2..3aabc082c16 100644 --- a/dlls/advpack/files.c +++ b/dlls/advpack/files.c @@ -709,7 +709,7 @@ HRESULT WINAPI ExtractFilesA(LPCSTR CabName, LPCSTR ExpandDir, DWORD Flags, if (FileList) { szConvertedList = convert_file_list(FileList, &dwFileCount); - if (!szConvertedList || dwFileCount == -1) + if (!szConvertedList) { res = E_FAIL; goto done; diff --git a/dlls/advpack/install.c b/dlls/advpack/install.c index c5a5df00cda..0ec5ceb4add 100644 --- a/dlls/advpack/install.c +++ b/dlls/advpack/install.c @@ -39,7 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(advpack); #define SPAPI_ERROR 0xE0000000L #define SPAPI_PREFIX 0x800F0000L #define SPAPI_MASK 0xFFFFL -#define HRESULT_FROM_SPAPI(x) ((x & SPAPI_MASK) | SPAPI_PREFIX) +#define HRESULT_FROM_SPAPI(x) ((HRESULT)((x & SPAPI_MASK) | SPAPI_PREFIX)) #define ADV_HRESULT(x) ((x & SPAPI_ERROR) ? HRESULT_FROM_SPAPI(x) : HRESULT_FROM_WIN32(x)) diff --git a/dlls/appwiz.cpl/En.rc b/dlls/appwiz.cpl/En.rc new file mode 100644 index 00000000000..155f46cc0e1 --- /dev/null +++ b/dlls/appwiz.cpl/En.rc @@ -0,0 +1,78 @@ +/* +* Add/Remove Programs English resources +* +* Copyright 2001-2002, 2008 Owen Rudge +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +* +*/ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE +{ + IDS_CPL_TITLE, "Add/Remove Programs" + IDS_CPL_DESC, "Allows you to install new software, or remove existing software from your computer." + IDS_TAB1_TITLE, "Applications" + + IDS_UNINSTALL_FAILED, "Unable to execute the uninstaller, '%s'. Do you want to remove the uninstall entry for this program from the registry?" + + IDS_COLUMN_NAME, "Name" + IDS_COLUMN_PUBLISHER, "Publisher" + IDS_COLUMN_VERSION, "Version" +} + +/* TODO: it's best to use the constant WC_LISTVIEW instead of SysListView32 directly, but the Wine resource compiler doesn't seem to like that... */ + +IDD_MAIN DIALOG 0, 0, 320, 220 +STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Install/Uninstall" +FONT 8, "MS Sans Serif" +{ + CONTROL "To install a new program from a floppy disk, CD-ROM drive, or your hard drive, click Install.", 1000, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 7, 270, 20 + CONTROL "&Install...", IDC_INSTALL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 246, 26, 64, 14 + CONTROL "", -1, "STATIC", SS_LEFT | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 7, 46, 303, 1 + CONTROL 2, 1001, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 7, 7, 21, 20 + CONTROL "The following software can be automatically removed. To remove a program or to modify its installed components, select it from the list and click Add/Remove.", 1002, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 57, 270, 36 + CONTROL "", IDL_PROGRAMS, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SORTASCENDING | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 90, 303, 100 + CONTROL "Add/&Remove...", IDC_ADDREMOVE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 246, 198, 64, 14 + CONTROL "&Support Info...", IDC_SUPPORT_INFO, "button", BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 176, 198, 64, 14 + CONTROL 3, 1003, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 7, 57, 21, 20 +} + +IDD_INFO DIALOG 0, 0, 256, 138 +STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Support Information" +FONT 8, "MS Sans Serif" +{ + CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 103, 116, 50, 14 + CONTROL "The following information can be used to get technical support for %s:", IDC_INFO_LABEL, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 12, 9, 228, 19 + CONTROL "Publisher:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 30, 60, 8 + CONTROL "Version:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 40, 60, 8 + CONTROL "Contact:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 50, 60, 8 + CONTROL "Support Information:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 60, 64, 8 + CONTROL "Support Telephone:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 70, 68, 8 + CONTROL "Readme:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 80, 60, 8 + CONTROL "Product Updates:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 90, 60, 8 + CONTROL "Comments:", -1, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 16, 100, 60, 8 + CONTROL "", IDC_INFO_PUBLISHER, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 30, 136, 8 + CONTROL "", IDC_INFO_VERSION, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 40, 136, 8 + CONTROL "", IDC_INFO_CONTACT, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 50, 136, 8 + CONTROL "", IDC_INFO_SUPPORT, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 60, 136, 8 + CONTROL "", IDC_INFO_PHONE, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 70, 136, 8 + CONTROL "", IDC_INFO_README, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 80, 136, 8 + CONTROL "", IDC_INFO_UPDATES, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 90, 136, 8 + CONTROL "", IDC_INFO_COMMENTS, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 104, 100, 136, 8 +} diff --git a/dlls/mstask/Makefile.in b/dlls/appwiz.cpl/Makefile.in similarity index 63% copy from dlls/mstask/Makefile.in copy to dlls/appwiz.cpl/Makefile.in index 2fd0a66e8e6..141715d7447 100644 --- a/dlls/mstask/Makefile.in +++ b/dlls/appwiz.cpl/Makefile.in @@ -2,11 +2,13 @@ TOPSRCDIR = @top_srcdir@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ -MODULE = mstask.dll -IMPORTS = kernel32 +MODULE = appwiz.cpl +IMPORTS = kernel32 comctl32 advapi32 shell32 user32 C_SRCS = \ - mstask_main.c + appwiz.c + +RC_SRCS = appwiz.rc @MAKE_DLL_RULES@ diff --git a/dlls/appwiz.cpl/appwiz.c b/dlls/appwiz.cpl/appwiz.c new file mode 100644 index 00000000000..a13dea1d795 --- /dev/null +++ b/dlls/appwiz.cpl/appwiz.c @@ -0,0 +1,787 @@ +/* + * Add/Remove Programs applet + * Partially based on Wine Uninstaller + * + * Copyright 2000 Andreas Mohr + * Copyright 2004 Hannu Valtonen + * Copyright 2005 Jonathan Ernst + * Copyright 2001-2002, 2008 Owen Rudge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" +#include "wine/unicode.h" +#include "wine/debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "res.h" + +WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl); + +/* define a maximum length for various buffers we use */ +#define MAX_STRING_LEN 1024 + +typedef struct APPINFO { + int id; + + LPWSTR title; + LPWSTR path; + + LPWSTR icon; + int iconIdx; + + LPWSTR publisher; + LPWSTR version; + + HKEY regroot; + WCHAR regkey[MAX_STRING_LEN]; + + struct APPINFO *next; +} APPINFO; + +static struct APPINFO *AppInfo = NULL; +static HINSTANCE hInst; + +/* names of registry keys */ +static const WCHAR BackSlashW[] = { '\\', 0 }; +static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; +static const WCHAR DisplayIconW[] = {'D','i','s','p','l','a','y','I','c','o','n',0}; +static const WCHAR DisplayVersionW[] = {'D','i','s','p','l','a','y','V','e','r', + 's','i','o','n',0}; +static const WCHAR PublisherW[] = {'P','u','b','l','i','s','h','e','r',0}; +static const WCHAR UninstallCommandlineW[] = {'U','n','i','n','s','t','a','l','l', + 'S','t','r','i','n','g',0}; + +static const WCHAR PathUninstallW[] = { + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'U','n','i','n','s','t','a','l','l',0 }; + +/****************************************************************************** + * Name : DllMain + * Description: Entry point for DLL file + */ +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, + LPVOID lpvReserved) +{ + TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + hInst = hinstDLL; + break; + } + return TRUE; +} + +/****************************************************************************** + * Name : FreeAppInfo + * Description: Frees memory used by an AppInfo structure, and any children. + */ +static void FreeAppInfo(APPINFO *info) +{ + APPINFO *iter = info; + + while (iter) + { + if (iter->title) + HeapFree(GetProcessHeap(), 0, iter->title); + + if (iter->path) + HeapFree(GetProcessHeap(), 0, iter->path); + + if (iter->icon) + HeapFree(GetProcessHeap(), 0, iter->icon); + + if (iter->publisher) + HeapFree(GetProcessHeap(), 0, iter->publisher); + + if (iter->version) + HeapFree(GetProcessHeap(), 0, iter->version); + + iter = iter->next; + HeapFree(GetProcessHeap(), 0, iter); + } +} + +/****************************************************************************** + * Name : ReadApplicationsFromRegistry + * Description: Creates a linked list of uninstallable applications from the + * registry. + * Parameters : root - Which registry root to read from (HKCU/HKLM) + * Returns : TRUE if successful, FALSE otherwise + */ +static BOOL ReadApplicationsFromRegistry(HKEY root) +{ + HKEY hkeyUninst, hkeyApp; + int i, id = 0; + DWORD sizeOfSubKeyName, displen, uninstlen; + WCHAR subKeyName[256]; + WCHAR key_app[MAX_STRING_LEN]; + WCHAR *p; + APPINFO *iter = AppInfo; + LPWSTR iconPtr; + BOOL ret = FALSE; + + if (RegOpenKeyExW(root, PathUninstallW, 0, KEY_READ, &hkeyUninst) != + ERROR_SUCCESS) + return FALSE; + + lstrcpyW(key_app, PathUninstallW); + lstrcatW(key_app, BackSlashW); + p = key_app+lstrlenW(PathUninstallW)+1; + + sizeOfSubKeyName = sizeof(subKeyName) / sizeof(subKeyName[0]); + + if (iter) + { + /* find the end of the list */ + for (iter = AppInfo; iter->next; iter = iter->next); + } + + for (i = 0; RegEnumKeyExW(hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, + NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS; ++i) + { + lstrcpyW(p, subKeyName); + RegOpenKeyExW(root, key_app, 0, KEY_READ, &hkeyApp); + + displen = 0; + uninstlen = 0; + + if ((RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, NULL, &displen) == + ERROR_SUCCESS) && (RegQueryValueExW(hkeyApp, UninstallCommandlineW, + 0, 0, NULL, &uninstlen) == ERROR_SUCCESS)) + { + /* if we already have iter, allocate the next entry */ + if (iter) + { + iter->next = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(struct APPINFO)); + + if (!iter->next) + goto err; + + iter = iter->next; + } + else + { + /* if not, start the list */ + iter = AppInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(struct APPINFO)); + + if (!iter) + goto err; + } + + iter->title = HeapAlloc(GetProcessHeap(), 0, displen); + + if (!iter->title) + goto err; + + RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)iter->title, + &displen); + + /* now get DisplayIcon */ + displen = 0; + RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, NULL, &displen); + + if (displen == 0) + iter->icon = 0; + else + { + iter->icon = HeapAlloc(GetProcessHeap(), 0, displen); + + if (!iter->icon) + goto err; + + RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, (LPBYTE)iter->icon, + &displen); + + /* separate the index from the icon name, if supplied */ + iconPtr = strchrW(iter->icon, ','); + + if (iconPtr) + { + *iconPtr++ = 0; + iter->iconIdx = atoiW(iconPtr); + } + } + + iter->path = HeapAlloc(GetProcessHeap(), 0, uninstlen); + + if (!iter->path) + goto err; + + RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, + (LPBYTE)iter->path, &uninstlen); + + /* publisher, version */ + if (RegQueryValueExW(hkeyApp, PublisherW, 0, 0, NULL, &displen) == + ERROR_SUCCESS) + { + iter->publisher = HeapAlloc(GetProcessHeap(), 0, displen); + + if (!iter->publisher) + goto err; + + RegQueryValueExW(hkeyApp, PublisherW, 0, 0, (LPBYTE)iter->publisher, + &displen); + } + + if (RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, NULL, &displen) == + ERROR_SUCCESS) + { + iter->version = HeapAlloc(GetProcessHeap(), 0, displen); + + if (!iter->version) + goto err; + + RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, (LPBYTE)iter->version, + &displen); + } + + /* registry key */ + iter->regroot = root; + lstrcpyW(iter->regkey, subKeyName); + + iter->id = id++; + } + + RegCloseKey(hkeyApp); + sizeOfSubKeyName = sizeof(subKeyName) / sizeof(subKeyName[0]); + } + + ret = TRUE; + goto end; + +err: + RegCloseKey(hkeyApp); + FreeAppInfo(iter); + +end: + RegCloseKey(hkeyUninst); + return ret; +} + + +/****************************************************************************** + * Name : AddApplicationsToList + * Description: Populates the list box with applications. + * Parameters : hWnd - Handle of the dialog box + */ +static void AddApplicationsToList(HWND hWnd, HIMAGELIST hList) +{ + APPINFO *iter = AppInfo; + LVITEMW lvItem; + HICON hIcon; + int index; + + while (iter) + { + /* get the icon */ + index = 0; + + if (iter->icon) + { + if (ExtractIconExW(iter->icon, iter->iconIdx, NULL, &hIcon, 1) == 1) + { + index = ImageList_AddIcon(hList, hIcon); + DestroyIcon(hIcon); + } + } + + lvItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; + lvItem.iItem = iter->id; + lvItem.iSubItem = 0; + lvItem.pszText = iter->title; + lvItem.iImage = index; + lvItem.lParam = iter->id; + + index = ListView_InsertItemW(hWnd, &lvItem); + + /* now add the subitems (columns) */ + ListView_SetItemTextW(hWnd, index, 1, iter->publisher); + ListView_SetItemTextW(hWnd, index, 2, iter->version); + + iter = iter->next; + } +} + +/****************************************************************************** + * Name : RemoveItemsFromList + * Description: Clears the application list box. + * Parameters : hWnd - Handle of the dialog box + */ +static void RemoveItemsFromList(HWND hWnd) +{ + SendDlgItemMessageW(hWnd, IDL_PROGRAMS, LVM_DELETEALLITEMS, 0, 0); +} + +/****************************************************************************** + * Name : EmptyList + * Description: Frees memory used by the application linked list. + */ +static inline void EmptyList(void) +{ + FreeAppInfo(AppInfo); + AppInfo = NULL; +} + +/****************************************************************************** + * Name : UpdateButtons + * Description: Enables/disables the Add/Remove button depending on current + * selection in list box. + * Parameters : hWnd - Handle of the dialog box + */ +static void UpdateButtons(HWND hWnd) +{ + BOOL sel = ListView_GetSelectedCount(GetDlgItem(hWnd, IDL_PROGRAMS)) != 0; + + EnableWindow(GetDlgItem(hWnd, IDC_ADDREMOVE), sel); + EnableWindow(GetDlgItem(hWnd, IDC_SUPPORT_INFO), sel); +} + +/****************************************************************************** + * Name : UninstallProgram + * Description: Executes the specified program's installer. + * Parameters : id - the internal ID of the installer to remove + */ +static void UninstallProgram(int id) +{ + APPINFO *iter; + STARTUPINFOW si; + PROCESS_INFORMATION info; + WCHAR errormsg[MAX_STRING_LEN]; + WCHAR sUninstallFailed[MAX_STRING_LEN]; + HKEY hkey; + BOOL res; + + LoadStringW(hInst, IDS_UNINSTALL_FAILED, sUninstallFailed, + sizeof(sUninstallFailed) / sizeof(sUninstallFailed[0])); + + for (iter = AppInfo; iter; iter = iter->next) + { + if (iter->id == id) + { + TRACE("Uninstalling %s (%s)\n", wine_dbgstr_w(iter->title), + wine_dbgstr_w(iter->path)); + + memset(&si, 0, sizeof(STARTUPINFOW)); + si.cb = sizeof(STARTUPINFOW); + si.wShowWindow = SW_NORMAL; + res = CreateProcessW(NULL, iter->path, NULL, NULL, FALSE, 0, NULL, + NULL, &si, &info); + + if (res) + { + /* wait for the process to exit */ + WaitForSingleObject(info.hProcess, INFINITE); + } + else + { + wsprintfW(errormsg, sUninstallFailed, iter->path); + + if (MessageBoxW(0, errormsg, iter->title, MB_YESNO | + MB_ICONQUESTION) == IDYES) + { + /* delete the application's uninstall entry */ + RegOpenKeyExW(iter->regroot, PathUninstallW, 0, KEY_READ, &hkey); + RegDeleteKeyW(hkey, iter->regkey); + RegCloseKey(hkey); + } + } + + break; + } + } +} + +/****************************************************************************** + * Name : SupportInfoDlgProc + * Description: Callback procedure for support info dialog + * Parameters : hWnd - hWnd of the window + * msg - reason for calling function + * wParam - additional parameter + * lParam - additional parameter + * Returns : Dependant on message + */ +static BOOL CALLBACK SupportInfoDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + APPINFO *iter; + WCHAR oldtitle[MAX_STRING_LEN]; + WCHAR buf[MAX_STRING_LEN]; + + switch(msg) + { + case WM_INITDIALOG: + for (iter = AppInfo; iter; iter = iter->next) + { + if (iter->id == (int) lParam) + { + /* Update the main label with the app name */ + if (GetWindowTextW(GetDlgItem(hWnd, IDC_INFO_LABEL), oldtitle, + MAX_STRING_LEN) != 0) + { + wsprintfW(buf, oldtitle, iter->title); + SetWindowTextW(GetDlgItem(hWnd, IDC_INFO_LABEL), buf); + } + + break; + } + } + + return TRUE; + + case WM_DESTROY: + return 0; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hWnd, TRUE); + break; + + } + + return TRUE; + } + + return FALSE; +} + +/****************************************************************************** + * Name : SupportInfo + * Description: Displays the Support Information dialog + * Parameters : hWnd - Handle of the main dialog + * id - ID of the application to display information for + */ +static void SupportInfo(HWND hWnd, int id) +{ + DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_INFO), hWnd, (DLGPROC) + SupportInfoDlgProc, (LPARAM) id); +} + +/* Definition of column headers for AddListViewColumns function */ +typedef struct AppWizColumn { + int width; + int fmt; + int title; +} AppWizColumn; + +AppWizColumn columns[] = { + {200, LVCFMT_LEFT, IDS_COLUMN_NAME}, + {150, LVCFMT_LEFT, IDS_COLUMN_PUBLISHER}, + {100, LVCFMT_LEFT, IDS_COLUMN_VERSION}, +}; + +/****************************************************************************** + * Name : AddListViewColumns + * Description: Adds column headers to the list view control. + * Parameters : hWnd - Handle of the list view control. + * Returns : TRUE if completed successfully, FALSE otherwise. + */ +static BOOL AddListViewColumns(HWND hWnd) +{ + WCHAR buf[MAX_STRING_LEN]; + LVCOLUMNW lvc; + int i; + + lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; + + /* Add the columns */ + for (i = 0; i < sizeof(columns) / sizeof(columns[0]); i++) + { + lvc.iSubItem = i; + lvc.pszText = buf; + + /* set width and format */ + lvc.cx = columns[i].width; + lvc.fmt = columns[i].fmt; + + LoadStringW(hInst, columns[i].title, buf, sizeof(buf) / sizeof(buf[0])); + + if (ListView_InsertColumnW(hWnd, i, &lvc) == -1) + return FALSE; + } + + return TRUE; +} + +/****************************************************************************** + * Name : AddListViewImageList + * Description: Creates an ImageList for the list view control. + * Parameters : hWnd - Handle of the list view control. + * Returns : Handle of the image list. + */ +static HIMAGELIST AddListViewImageList(HWND hWnd) +{ + HIMAGELIST hSmall; + HICON hDefaultIcon; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), + ILC_MASK, 1, 1); + + /* Add default icon to image list */ + hDefaultIcon = LoadIconW(hInst, MAKEINTRESOURCEW(ICO_MAIN)); + ImageList_AddIcon(hSmall, hDefaultIcon); + DestroyIcon(hDefaultIcon); + + (void) ListView_SetImageList(hWnd, hSmall, LVSIL_SMALL); + + return hSmall; +} + +/****************************************************************************** + * Name : ResetApplicationList + * Description: Empties the app list, if need be, and recreates it. + * Parameters : bFirstRun - TRUE if this is the first time this is run, FALSE otherwise + * hWnd - handle of the dialog box + * hImageList - handle of the image list + * Returns : New handle of the image list. + */ +static HIMAGELIST ResetApplicationList(BOOL bFirstRun, HWND hWnd, HIMAGELIST hImageList) +{ + HWND hWndListView; + + hWndListView = GetDlgItem(hWnd, IDL_PROGRAMS); + + /* if first run, create the image list and add the listview columns */ + if (bFirstRun) + { + if (!AddListViewColumns(hWndListView)) + return NULL; + } + else /* we need to remove the existing things first */ + { + RemoveItemsFromList(hWnd); + ImageList_Destroy(hImageList); + + /* reset the list, since it's probably changed if the uninstallation was + successful */ + EmptyList(); + } + + /* now create the image list and add the applications to the listview */ + hImageList = AddListViewImageList(hWndListView); + + ReadApplicationsFromRegistry(HKEY_LOCAL_MACHINE); + ReadApplicationsFromRegistry(HKEY_CURRENT_USER); + + AddApplicationsToList(hWndListView, hImageList); + UpdateButtons(hWnd); + + return(hImageList); +} + +/****************************************************************************** + * Name : MainDlgProc + * Description: Callback procedure for main tab + * Parameters : hWnd - hWnd of the window + * msg - reason for calling function + * wParam - additional parameter + * lParam - additional parameter + * Returns : Dependant on message + */ +static BOOL CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int selitem; + static HIMAGELIST hImageList; + LPNMHDR nmh; + LVITEMW lvItem; + + switch(msg) + { + case WM_INITDIALOG: + hImageList = ResetApplicationList(TRUE, hWnd, hImageList); + + if (!hImageList) + return FALSE; + + return TRUE; + + case WM_DESTROY: + RemoveItemsFromList(hWnd); + ImageList_Destroy(hImageList); + + EmptyList(); + + return 0; + + case WM_NOTIFY: + nmh = (LPNMHDR) lParam; + + switch (nmh->idFrom) + { + case IDL_PROGRAMS: + switch (nmh->code) + { + case LVN_ITEMCHANGED: + UpdateButtons(hWnd); + break; + } + break; + } + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_ADDREMOVE: + selitem = SendDlgItemMessageW(hWnd, IDL_PROGRAMS, + LVM_GETNEXTITEM, -1, LVNI_FOCUSED|LVNI_SELECTED); + + if (selitem != -1) + { + lvItem.iItem = selitem; + lvItem.mask = LVIF_PARAM; + + if (SendDlgItemMessageW(hWnd, IDL_PROGRAMS, LVM_GETITEMW, + 0, (LPARAM) &lvItem)) + UninstallProgram(lvItem.lParam); + } + + hImageList = ResetApplicationList(FALSE, hWnd, hImageList); + + break; + + case IDC_SUPPORT_INFO: + selitem = SendDlgItemMessageW(hWnd, IDL_PROGRAMS, + LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED); + + if (selitem != -1) + { + lvItem.iItem = selitem; + lvItem.mask = LVIF_PARAM; + + if (SendDlgItemMessageW(hWnd, IDL_PROGRAMS, LVM_GETITEMW, + 0, (LPARAM) &lvItem)) + SupportInfo(hWnd, lvItem.lParam); + } + + break; + } + + return TRUE; + } + + return FALSE; +} + +/****************************************************************************** + * Name : StartApplet + * Description: Main routine for applet + * Parameters : hWnd - hWnd of the Control Panel + */ +static void StartApplet(HWND hWnd) +{ + PROPSHEETPAGEW psp; + PROPSHEETHEADERW psh; + WCHAR tab_title[MAX_STRING_LEN], app_title[MAX_STRING_LEN]; + + /* Load the strings we will use */ + LoadStringW(hInst, IDS_TAB1_TITLE, tab_title, sizeof(tab_title) / sizeof(tab_title[0])); + LoadStringW(hInst, IDS_CPL_TITLE, app_title, sizeof(app_title) / sizeof(app_title[0])); + + /* Fill out the PROPSHEETPAGE */ + psp.dwSize = sizeof (PROPSHEETPAGEW); + psp.dwFlags = PSP_USETITLE; + psp.hInstance = hInst; + psp.pszTemplate = MAKEINTRESOURCEW (IDD_MAIN); + psp.pszIcon = NULL; + psp.pfnDlgProc = (DLGPROC) MainDlgProc; + psp.pszTitle = tab_title; + psp.lParam = 0; + + /* Fill out the PROPSHEETHEADER */ + psh.dwSize = sizeof (PROPSHEETHEADERW); + psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USEICONID; + psh.hwndParent = hWnd; + psh.hInstance = hInst; + psh.pszIcon = NULL; + psh.pszCaption = app_title; + psh.nPages = 1; + psh.ppsp = &psp; + psh.pfnCallback = NULL; + psh.nStartPage = 0; + + /* Display the property sheet */ + PropertySheetW (&psh); +} + +/****************************************************************************** + * Name : CPlApplet + * Description: Entry point for Control Panel applets + * Parameters : hwndCPL - hWnd of the Control Panel + * message - reason for calling function + * lParam1 - additional parameter + * lParam2 - additional parameter + * Returns : Dependant on message + */ +LONG CALLBACK CPlApplet(HWND hwndCPL, UINT message, LPARAM lParam1, LPARAM lParam2) +{ + INITCOMMONCONTROLSEX iccEx; + + switch (message) + { + case CPL_INIT: + iccEx.dwSize = sizeof(iccEx); + iccEx.dwICC = ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES; + + InitCommonControlsEx(&iccEx); + + return TRUE; + + case CPL_GETCOUNT: + return 1; + + case CPL_INQUIRE: + { + CPLINFO *appletInfo = (CPLINFO *) lParam2; + + appletInfo->idIcon = ICO_MAIN; + appletInfo->idName = IDS_CPL_TITLE; + appletInfo->idInfo = IDS_CPL_DESC; + appletInfo->lData = 0; + + break; + } + + case CPL_DBLCLK: + StartApplet(hwndCPL); + break; + } + + return FALSE; +} diff --git a/dlls/appwiz.cpl/appwiz.cpl.spec b/dlls/appwiz.cpl/appwiz.cpl.spec new file mode 100644 index 00000000000..7ae3a0104c6 --- /dev/null +++ b/dlls/appwiz.cpl/appwiz.cpl.spec @@ -0,0 +1 @@ +1 stdcall CPlApplet() diff --git a/dlls/appwiz.cpl/appwiz.ico b/dlls/appwiz.cpl/appwiz.ico new file mode 100644 index 0000000000000000000000000000000000000000..fcc5894c69cb0de40227d44089dedfd8b8cc579d GIT binary patch literal 766 zcwV)UJx;?w5QWEKBT8(^LZTwtxS+*O&nABKDYEBrj>ai`297|1w9Jp!u|-3}Sfky~ z@9p0VQNiDCSCYi%hUk&U7tS4L;4H|gMjM)=oW}HI<1h@AQj$M3jwAgwP^|(uF0lr% zavy7i8#;((DOXjAzMJBJg4rQ6f-vFaeb;*5fRqoD0ljf629Z1C&J4Woqt1zU1s5&kbry literal 0 HcwPel00001 diff --git a/dlls/appwiz.cpl/appwiz.rc b/dlls/appwiz.cpl/appwiz.rc new file mode 100644 index 00000000000..8b839be3af2 --- /dev/null +++ b/dlls/appwiz.cpl/appwiz.rc @@ -0,0 +1,32 @@ +/* +* Add/Remove Programs resources +* +* Copyright 2001-2002, 2008 Owen Rudge +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +* +*/ +#include +#include +#include +#include + +#include "res.h" + +#include "En.rc" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +ICO_MAIN ICON "appwiz.ico" diff --git a/dlls/appwiz.cpl/res.h b/dlls/appwiz.cpl/res.h new file mode 100644 index 00000000000..ea32be8bd9e --- /dev/null +++ b/dlls/appwiz.cpl/res.h @@ -0,0 +1,54 @@ +/* +* Add/Remove Programs resources +* +* Copyright 2001-2002, 2008 Owen Rudge +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +* +*/ + +/* Dialogs */ + +#define IDD_MAIN 1 +#define IDD_INFO 2 + +/* Dialog controls */ +#define IDC_INSTALL 1010 +#define IDL_PROGRAMS 1011 +#define IDC_ADDREMOVE 1012 +#define IDC_SUPPORT_INFO 1013 + +#define IDC_INFO_PUBLISHER 1100 +#define IDC_INFO_VERSION 1101 +#define IDC_INFO_CONTACT 1102 +#define IDC_INFO_SUPPORT 1103 +#define IDC_INFO_PHONE 1104 +#define IDC_INFO_README 1105 +#define IDC_INFO_UPDATES 1106 +#define IDC_INFO_COMMENTS 1107 +#define IDC_INFO_LABEL 1108 + +/* Icons */ + +#define ICO_MAIN 1 + +/* Strings */ +#define IDS_CPL_TITLE 1 +#define IDS_CPL_DESC 2 +#define IDS_TAB1_TITLE 3 +#define IDS_UNINSTALL_FAILED 4 +#define IDS_COLUMN_NAME 6 +#define IDS_COLUMN_PUBLISHER 7 +#define IDS_COLUMN_VERSION 8 diff --git a/dlls/avifil32/avifile.c b/dlls/avifil32/avifile.c index b0ef1cb769a..7a7b194479b 100644 --- a/dlls/avifil32/avifile.c +++ b/dlls/avifil32/avifile.c @@ -217,7 +217,7 @@ static HRESULT AVIFILE_LoadIndex(const IAVIFileImpl *This, DWORD size, DWORD off static HRESULT AVIFILE_ParseIndex(const IAVIFileImpl *This, AVIINDEXENTRY *lp, LONG count, DWORD pos, BOOL *bAbsolute); static HRESULT AVIFILE_ReadBlock(IAVIStreamImpl *This, DWORD start, - LPVOID buffer, LONG size); + LPVOID buffer, DWORD size); static void AVIFILE_SamplesToBlock(const IAVIStreamImpl *This, LPLONG pos, LPLONG offset); static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This); @@ -2008,7 +2008,7 @@ static HRESULT AVIFILE_ParseIndex(const IAVIFileImpl *This, AVIINDEXENTRY *lp, } static HRESULT AVIFILE_ReadBlock(IAVIStreamImpl *This, DWORD pos, - LPVOID buffer, LONG size) + LPVOID buffer, DWORD size) { /* pre-conditions */ assert(This != NULL); diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index 7ebe63cce6b..35810e3b659 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -338,7 +338,10 @@ HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName) return E_FAIL; if (GetFileAttributesA(dest->Destination) == INVALID_FILE_ATTRIBUTES) - return S_OK; + { + res = S_OK; + goto end; + } /* split the cabinet name into path + name */ str = HeapAlloc(GetProcessHeap(), 0, lstrlenA(szCabName)+1); diff --git a/dlls/comctl32/animate.c b/dlls/comctl32/animate.c index a567cb34858..0dd25f8208a 100644 --- a/dlls/comctl32/animate.c +++ b/dlls/comctl32/animate.c @@ -962,7 +962,7 @@ static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP return DefWindowProcW(hWnd, uMsg, wParam, lParam); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/comboex.c b/dlls/comctl32/comboex.c index afd4f824d6a..1c9b202aa8f 100644 --- a/dlls/comctl32/comboex.c +++ b/dlls/comctl32/comboex.c @@ -2310,7 +2310,7 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n",uMsg,wParam,lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); } diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index da9243f63bc..2c8e53816d6 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -149,6 +149,7 @@ VOID COMCTL32_RefreshSysColors(void); void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal); void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground); void COMCTL32_GetFontMetrics(HFONT hFont, TEXTMETRICW *ptm); +BOOL COMCTL32_IsReflectedMessage(UINT uMsg); INT Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen); INT Str_GetPtrAtoW (LPCSTR lpSrc, LPWSTR lpDest, INT nMaxLen); BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc); diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 1863dbf235c..050a018701f 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -1572,6 +1572,50 @@ void COMCTL32_GetFontMetrics(HFONT hFont, TEXTMETRICW *ptm) ReleaseDC(NULL, hdc); } +#ifndef OCM__BASE /* avoid including olectl.h */ +#define OCM__BASE (WM_USER+0x1c00) +#endif + +/*********************************************************************** + * COMCTL32_IsReflectedMessage [internal] + * + * Some parents reflect notify messages - for some messages sent by the child, + * they send it back with the message code increased by OCM__BASE (0x2000). + * This allows better subclassing of controls. We don't need to handle such + * messages but we don't want to print ERRs for them, so this helper function + * identifies them. + * + * Some of the codes are in the CCM_FIRST..CCM_LAST range, but there is no + * colision with defined CCM_ codes. + */ +BOOL COMCTL32_IsReflectedMessage(UINT uMsg) +{ + switch (uMsg) + { + case OCM__BASE + WM_COMMAND: + case OCM__BASE + WM_CTLCOLORBTN: + case OCM__BASE + WM_CTLCOLOREDIT: + case OCM__BASE + WM_CTLCOLORDLG: + case OCM__BASE + WM_CTLCOLORLISTBOX: + case OCM__BASE + WM_CTLCOLORMSGBOX: + case OCM__BASE + WM_CTLCOLORSCROLLBAR: + case OCM__BASE + WM_CTLCOLORSTATIC: + case OCM__BASE + WM_DRAWITEM: + case OCM__BASE + WM_MEASUREITEM: + case OCM__BASE + WM_DELETEITEM: + case OCM__BASE + WM_VKEYTOITEM: + case OCM__BASE + WM_CHARTOITEM: + case OCM__BASE + WM_COMPAREITEM: + case OCM__BASE + WM_HSCROLL: + case OCM__BASE + WM_VSCROLL: + case OCM__BASE + WM_PARENTNOTIFY: + case OCM__BASE + WM_NOTIFY: + return TRUE; + default: + return FALSE; + } +} + /*********************************************************************** * MirrorIcon [COMCTL32.414] * diff --git a/dlls/comctl32/datetime.c b/dlls/comctl32/datetime.c index b46c4956cb8..fddaf21b095 100644 --- a/dlls/comctl32/datetime.c +++ b/dlls/comctl32/datetime.c @@ -707,7 +707,7 @@ DATETIME_HitTest (const DATETIME_INFO *infoPtr, POINT pt) static LRESULT -DATETIME_LButtonDown (DATETIME_INFO *infoPtr, WORD wKey, INT x, INT y) +DATETIME_LButtonDown (DATETIME_INFO *infoPtr, INT x, INT y) { POINT pt; int old, new; @@ -769,7 +769,7 @@ DATETIME_LButtonDown (DATETIME_INFO *infoPtr, WORD wKey, INT x, INT y) static LRESULT -DATETIME_LButtonUp (DATETIME_INFO *infoPtr, WORD wKey) +DATETIME_LButtonUp (DATETIME_INFO *infoPtr) { if(infoPtr->bCalDepressed) { infoPtr->bCalDepressed = FALSE; @@ -865,7 +865,7 @@ DATETIME_EraseBackground (const DATETIME_INFO *infoPtr, HDC hdc) static LRESULT -DATETIME_Notify (DATETIME_INFO *infoPtr, int idCtrl, LPNMHDR lpnmh) +DATETIME_Notify (DATETIME_INFO *infoPtr, LPNMHDR lpnmh) { TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom); TRACE ("info: %p %p %p\n", infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hUpdown); @@ -890,7 +890,7 @@ DATETIME_Notify (DATETIME_INFO *infoPtr, int idCtrl, LPNMHDR lpnmh) static LRESULT -DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode, LPARAM flags) +DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode) { int fieldNum = infoPtr->select & DTHT_DATEFIELD; int wrap = 0; @@ -1138,7 +1138,7 @@ DATETIME_SendSimpleNotify (const DATETIME_INFO *infoPtr, UINT code) } static LRESULT -DATETIME_Size (DATETIME_INFO *infoPtr, WORD flags, INT width, INT height) +DATETIME_Size (DATETIME_INFO *infoPtr, INT width, INT height) { /* set size */ infoPtr->rcClient.bottom = height; @@ -1323,7 +1323,7 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return SendMessageW (infoPtr->hMonthCal, WM_GETFONT, wParam, lParam); case WM_NOTIFY: - return DATETIME_Notify (infoPtr, (int)wParam, (LPNMHDR)lParam); + return DATETIME_Notify (infoPtr, (LPNMHDR)lParam); case WM_ENABLE: return DATETIME_Enable (infoPtr, (BOOL)wParam); @@ -1339,7 +1339,7 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DATETIME_Paint (infoPtr, (HDC)wParam); case WM_KEYDOWN: - return DATETIME_KeyDown (infoPtr, wParam, lParam); + return DATETIME_KeyDown (infoPtr, wParam); case WM_KILLFOCUS: return DATETIME_KillFocus (infoPtr, (HWND)wParam); @@ -1351,13 +1351,13 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DATETIME_SetFocus (infoPtr, (HWND)wParam); case WM_SIZE: - return DATETIME_Size (infoPtr, wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); + return DATETIME_Size (infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_LBUTTONDOWN: - return DATETIME_LButtonDown (infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); + return DATETIME_LButtonDown (infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_LBUTTONUP: - return DATETIME_LButtonUp (infoPtr, (WORD)wParam); + return DATETIME_LButtonUp (infoPtr); case WM_VSCROLL: return DATETIME_VScroll (infoPtr, (WORD)wParam); @@ -1381,7 +1381,7 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return (LRESULT) infoPtr->hFont; default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/flatsb.c b/dlls/comctl32/flatsb.c index 080aff98e29..cabcdfcb8f4 100644 --- a/dlls/comctl32/flatsb.c +++ b/dlls/comctl32/flatsb.c @@ -257,7 +257,7 @@ FlatSB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return FlatSB_Destroy (hwnd, wParam, lParam); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c index af1923ce6e7..496df62b0f4 100644 --- a/dlls/comctl32/header.c +++ b/dlls/comctl32/header.c @@ -249,7 +249,7 @@ HEADER_SetItemBounds (HWND hwnd) } static LRESULT -HEADER_Size (HWND hwnd, WPARAM wParam) +HEADER_Size (HWND hwnd) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); @@ -577,7 +577,7 @@ HEADER_Refresh (HWND hwnd, HDC hdc) static void -HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem) +HEADER_RefreshItem (HWND hwnd, INT iItem) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); @@ -1073,7 +1073,7 @@ HEADER_DeleteItem (HWND hwnd, WPARAM wParam) HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd); INT iItem = (INT)wParam; INT iOrder; - INT i; + UINT i; TRACE("[iItem=%d]\n", iItem); @@ -1250,7 +1250,7 @@ HEADER_GetUnicodeFormat (HWND hwnd) static LRESULT -HEADER_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_HitTest (HWND hwnd, LPARAM lParam) { LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam; @@ -1332,7 +1332,7 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, const HDITEMW *phdi, BOOL bUnicode) static LRESULT -HEADER_Layout (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_Layout (HWND hwnd, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam; @@ -1447,7 +1447,7 @@ HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam) static LRESULT -HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_Create (HWND hwnd, LPARAM lParam) { HEADER_INFO *infoPtr; TEXTMETRICW tm; @@ -1490,7 +1490,7 @@ HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_Destroy (HWND hwnd) { HTHEME theme = GetWindowTheme(hwnd); CloseThemeData(theme); @@ -1498,7 +1498,7 @@ HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam) } static LRESULT -HEADER_NCDestroy (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_NCDestroy (HWND hwnd) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); HEADER_ITEM *lpItem; @@ -1544,7 +1544,7 @@ HEADER_IsDragDistance(const HEADER_INFO *infoPtr, const POINT *pt) } static LRESULT -HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_LButtonDblClk (HWND hwnd, LPARAM lParam) { POINT pt; UINT flags; @@ -1564,7 +1564,7 @@ HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_LButtonDown (HWND hwnd, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); @@ -1589,7 +1589,7 @@ HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) /* Send WM_CUSTOMDRAW */ hdc = GetDC (hwnd); - HEADER_RefreshItem (hwnd, hdc, nItem); + HEADER_RefreshItem (hwnd, nItem); ReleaseDC (hwnd, hdc); TRACE("Pressed item %d!\n", nItem); @@ -1620,7 +1620,7 @@ HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_LButtonUp (HWND hwnd, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); @@ -1670,7 +1670,7 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) { infoPtr->items[infoPtr->iMoveItem].bDown = FALSE; hdc = GetDC (hwnd); - HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem); + HEADER_RefreshItem (hwnd, infoPtr->iMoveItem); ReleaseDC (hwnd, hdc); HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCLICKW, infoPtr->iMoveItem, NULL); @@ -1735,7 +1735,7 @@ HEADER_NotifyFormat (HWND hwnd, WPARAM wParam, LPARAM lParam) } static LRESULT -HEADER_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_MouseLeave (HWND hwnd) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); /* Reset hot-tracked item when mouse leaves control. */ @@ -1743,7 +1743,7 @@ HEADER_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam) HDC hdc = GetDC (hwnd); infoPtr->iHotItem = -1; - if (oldHotItem != -1) HEADER_RefreshItem (hwnd, hdc, oldHotItem); + if (oldHotItem != -1) HEADER_RefreshItem (hwnd, oldHotItem); ReleaseDC (hwnd, hdc); return 0; @@ -1751,7 +1751,7 @@ HEADER_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_MouseMove (HWND hwnd, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); @@ -1814,7 +1814,7 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) infoPtr->items[infoPtr->iMoveItem].bDown = FALSE; if (oldState != infoPtr->items[infoPtr->iMoveItem].bDown) { hdc = GetDC (hwnd); - HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem); + HEADER_RefreshItem (hwnd, infoPtr->iMoveItem); ReleaseDC (hwnd, hdc); } @@ -1866,8 +1866,8 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) TRACKMOUSEEVENT tme; if (oldHotItem != infoPtr->iHotItem && !infoPtr->bDragging) { hdc = GetDC (hwnd); - if (oldHotItem != -1) HEADER_RefreshItem (hwnd, hdc, oldHotItem); - if (infoPtr->iHotItem != -1) HEADER_RefreshItem (hwnd, hdc, infoPtr->iHotItem); + if (oldHotItem != -1) HEADER_RefreshItem (hwnd, oldHotItem); + if (infoPtr->iHotItem != -1) HEADER_RefreshItem (hwnd, infoPtr->iHotItem); ReleaseDC (hwnd, hdc); } tme.cbSize = sizeof( tme ); @@ -1895,7 +1895,7 @@ HEADER_Paint (HWND hwnd, WPARAM wParam) static LRESULT -HEADER_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_RButtonUp (HWND hwnd, LPARAM lParam) { BOOL bRet; POINT pt; @@ -1917,7 +1917,7 @@ HEADER_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -HEADER_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam) +HEADER_SetCursor (HWND hwnd, LPARAM lParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); POINT pt; @@ -2033,14 +2033,14 @@ HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return HEADER_GetUnicodeFormat (hwnd); case HDM_HITTEST: - return HEADER_HitTest (hwnd, wParam, lParam); + return HEADER_HitTest (hwnd, lParam); case HDM_INSERTITEMA: case HDM_INSERTITEMW: return HEADER_InsertItemT (hwnd, (INT)wParam, (LPHDITEMW)lParam, msg == HDM_INSERTITEMW); case HDM_LAYOUT: - return HEADER_Layout (hwnd, wParam, lParam); + return HEADER_Layout (hwnd, lParam); case HDM_ORDERTOINDEX: return HEADER_OrderToIndex(hwnd, wParam); @@ -2067,13 +2067,13 @@ HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return HEADER_SetUnicodeFormat (hwnd, wParam); case WM_CREATE: - return HEADER_Create (hwnd, wParam, lParam); + return HEADER_Create (hwnd, lParam); case WM_DESTROY: - return HEADER_Destroy (hwnd, wParam, lParam); + return HEADER_Destroy (hwnd); case WM_NCDESTROY: - return HEADER_NCDestroy (hwnd, wParam, lParam); + return HEADER_NCDestroy (hwnd); case WM_ERASEBKGND: return 1; @@ -2085,25 +2085,25 @@ HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return HEADER_GetFont (hwnd); case WM_LBUTTONDBLCLK: - return HEADER_LButtonDblClk (hwnd, wParam, lParam); + return HEADER_LButtonDblClk (hwnd, lParam); case WM_LBUTTONDOWN: - return HEADER_LButtonDown (hwnd, wParam, lParam); + return HEADER_LButtonDown (hwnd, lParam); case WM_LBUTTONUP: - return HEADER_LButtonUp (hwnd, wParam, lParam); + return HEADER_LButtonUp (hwnd, lParam); case WM_MOUSELEAVE: - return HEADER_MouseLeave (hwnd, wParam, lParam); + return HEADER_MouseLeave (hwnd); case WM_MOUSEMOVE: - return HEADER_MouseMove (hwnd, wParam, lParam); + return HEADER_MouseMove (hwnd, lParam); case WM_NOTIFYFORMAT: return HEADER_NotifyFormat (hwnd, wParam, lParam); case WM_SIZE: - return HEADER_Size (hwnd, wParam); + return HEADER_Size (hwnd); case WM_THEMECHANGED: return HEADER_ThemeChanged (hwnd); @@ -2113,10 +2113,10 @@ HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return HEADER_Paint (hwnd, wParam); case WM_RBUTTONUP: - return HEADER_RButtonUp (hwnd, wParam, lParam); + return HEADER_RButtonUp (hwnd, lParam); case WM_SETCURSOR: - return HEADER_SetCursor (hwnd, wParam, lParam); + return HEADER_SetCursor (hwnd, lParam); case WM_SETFONT: return HEADER_SetFont (hwnd, wParam, lParam); @@ -2125,7 +2125,7 @@ HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return HEADER_SetRedraw(hwnd, wParam, lParam); default: - if ((msg >= WM_USER) && (msg < WM_APP)) + if ((msg >= WM_USER) && (msg < WM_APP) && !COMCTL32_IsReflectedMessage(msg)) ERR("unknown msg %04x wp=%04lx lp=%08lx\n", msg, wParam, lParam ); return DefWindowProcW(hwnd, msg, wParam, lParam); diff --git a/dlls/comctl32/hotkey.c b/dlls/comctl32/hotkey.c index 8a56fd38993..6e7591a509f 100644 --- a/dlls/comctl32/hotkey.c +++ b/dlls/comctl32/hotkey.c @@ -528,7 +528,7 @@ HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return HOTKEY_SetFont (infoPtr, (HFONT)wParam, LOWORD(lParam)); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/ipaddress.c b/dlls/comctl32/ipaddress.c index c29406fd186..0c02daf7090 100644 --- a/dlls/comctl32/ipaddress.c +++ b/dlls/comctl32/ipaddress.c @@ -590,7 +590,7 @@ IPADDRESS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return IPADDRESS_IsBlank (infoPtr); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); } diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 6b16a7bbab7..213b5697463 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -10033,7 +10033,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /* case WM_WININICHANGE: */ default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); fwd_msg: diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c index f3d54b182c8..9ca6fcc5e7f 100644 --- a/dlls/comctl32/monthcal.c +++ b/dlls/comctl32/monthcal.c @@ -2072,7 +2072,7 @@ MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return MONTHCAL_Destroy(infoPtr); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR( "unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW(hwnd, uMsg, wParam, lParam); } diff --git a/dlls/comctl32/nativefont.c b/dlls/comctl32/nativefont.c index a599a2aa984..22bf2dffb4a 100644 --- a/dlls/comctl32/nativefont.c +++ b/dlls/comctl32/nativefont.c @@ -101,7 +101,7 @@ NATIVEFONT_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DefWindowProcW (hwnd, uMsg, wParam, lParam); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/progress.c b/dlls/comctl32/progress.c index d3b7ded976c..d29fec5b18d 100644 --- a/dlls/comctl32/progress.c +++ b/dlls/comctl32/progress.c @@ -722,7 +722,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message, return infoPtr->Marquee; default: - if ((message >= WM_USER) && (message < WM_APP)) + if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message)) ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam ); return DefWindowProcW( hwnd, message, wParam, lParam ); } diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c index 16f6b9cc239..e2b8c4f44f7 100644 --- a/dlls/comctl32/rebar.c +++ b/dlls/comctl32/rebar.c @@ -3733,7 +3733,7 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return REBAR_WindowPosChanged (infoPtr, wParam, lParam); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/rsrc.rc b/dlls/comctl32/rsrc.rc index 9028df9444d..772248a4531 100644 --- a/dlls/comctl32/rsrc.rc +++ b/dlls/comctl32/rsrc.rc @@ -30,9 +30,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define WINE_FILEDESCRIPTION_STR "Wine Common Controls" #define WINE_FILENAME_STR "comctl32.dll" #define WINE_FILEVERSION COMCTL32_VERSION, COMCTL32_VERSION_MINOR, 4704, 1100 -#define WINE_FILEVERSIONSTR "5.81" +#define WINE_FILEVERSION_STR "5.81" #define WINE_PRODUCTVERSION WINE_FILEVERSION -#define WINE_PRODUCTVERSION_STR WINE_FILEVERSIONSTR +#define WINE_PRODUCTVERSION_STR WINE_FILEVERSION_STR #include "wine/wine_common_ver.rc" diff --git a/dlls/comctl32/status.c b/dlls/comctl32/status.c index 1b97b41bdc4..c1214bbea42 100644 --- a/dlls/comctl32/status.c +++ b/dlls/comctl32/status.c @@ -72,6 +72,7 @@ typedef struct HWND Notify; WORD numParts; UINT height; + UINT minHeight; /* at least MIN_PANE_HEIGHT, can be increased by SB_SETMINHEIGHT */ BOOL simple; HWND hwndToolTip; HFONT hFont; @@ -94,6 +95,7 @@ typedef struct #define HORZ_BORDER 0 #define VERT_BORDER 2 #define HORZ_GAP 2 +#define MIN_PANE_HEIGHT 18 static const WCHAR themeClass[] = { 'S','t','a','t','u','s',0 }; @@ -114,9 +116,11 @@ STATUSBAR_ComputeHeight(STATUS_INFO *infoPtr) HTHEME theme; UINT height; TEXTMETRICW tm; + int margin; COMCTL32_GetFontMetrics(infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont, &tm); - height = tm.tmHeight + 4 + infoPtr->verticalBorder; + margin = (tm.tmInternalLeading ? tm.tmInternalLeading : 2); + height = max(tm.tmHeight + margin + 2*GetSystemMetrics(SM_CYBORDER), infoPtr->minHeight) + infoPtr->verticalBorder; if ((theme = GetWindowTheme(infoPtr->Self))) { @@ -125,7 +129,7 @@ STATUSBAR_ComputeHeight(STATUS_INFO *infoPtr) HDC hdc = GetDC(infoPtr->Self); RECT r; memset (&r, 0, sizeof (r)); - r.bottom = tm.tmHeight; + r.bottom = max(infoPtr->minHeight, tm.tmHeight); if (SUCCEEDED(GetThemeBackgroundExtent(theme, hdc, SP_PANE, 0, &r, &r))) { height = r.bottom - r.top; @@ -248,15 +252,15 @@ static void STATUSBAR_RefreshPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPART *part, int itemID) { HBRUSH hbrBk; - HFONT hOldFont; HTHEME theme; TRACE("item %d\n", itemID); - if (!IsWindowVisible (infoPtr->Self)) - return; if (part->bound.right < part->bound.left) return; + if (!RectVisible(hdc, &part->bound)) + return; + if ((theme = GetWindowTheme (infoPtr->Self))) { RECT cr; @@ -274,18 +278,7 @@ STATUSBAR_RefreshPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPA DeleteObject (hbrBk); } - hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont); - - STATUSBAR_DrawPart (infoPtr, hdc, part, itemID); - - SelectObject (hdc, hOldFont); - - if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) { - RECT rect; - - GetClientRect (infoPtr->Self, &rect); - STATUSBAR_DrawSizeGrip (theme, hdc, &rect); - } + STATUSBAR_DrawPart (infoPtr, hdc, part, itemID); } @@ -656,40 +649,9 @@ STATUSBAR_SetIcon (STATUS_INFO *infoPtr, INT nPart, HICON hIcon) static BOOL STATUSBAR_SetMinHeight (STATUS_INFO *infoPtr, INT height) { - - TRACE("(height=%d)\n", height); - if (IsWindowVisible (infoPtr->Self)) { - INT width, x, y; - RECT parent_rect; - HTHEME theme; - - infoPtr->height = height + infoPtr->verticalBorder; - - if ((theme = GetWindowTheme (infoPtr->Self))) - { - /* Determine bar height from theme such that the content area is - * 'height' pixels large */ - HDC hdc = GetDC (infoPtr->Self); - RECT r; - memset (&r, 0, sizeof (r)); - r.bottom = height; - if (SUCCEEDED(GetThemeBackgroundExtent (theme, hdc, SP_PANE, 0, &r, &r))) - { - infoPtr->height = r.bottom - r.top; - } - ReleaseDC (infoPtr->Self, hdc); - } - - if (GetClientRect (infoPtr->Notify, &parent_rect)) - { - width = parent_rect.right - parent_rect.left; - x = parent_rect.left; - y = parent_rect.bottom - infoPtr->height; - MoveWindow (infoPtr->Self, x, y, width, infoPtr->height, TRUE); - STATUSBAR_SetPartBounds (infoPtr); - } - } - + infoPtr->minHeight = max(height, MIN_PANE_HEIGHT); + infoPtr->height = STATUSBAR_ComputeHeight(infoPtr); + /* like native, don't resize the control */ return TRUE; } @@ -959,6 +921,7 @@ STATUSBAR_WMCreate (HWND hwnd, const CREATESTRUCTA *lpCreate) infoPtr->horizontalBorder = HORZ_BORDER; infoPtr->verticalBorder = VERT_BORDER; infoPtr->horizontalGap = HORZ_GAP; + infoPtr->minHeight = MIN_PANE_HEIGHT; STATUSBAR_NotifyFormat(infoPtr, infoPtr->Notify, NF_REQUERY); @@ -1343,7 +1306,7 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return theme_changed (infoPtr); default: - if ((msg >= WM_USER) && (msg < WM_APP)) + if ((msg >= WM_USER) && (msg < WM_APP) && !COMCTL32_IsReflectedMessage(msg)) ERR("unknown msg %04x wp=%04lx lp=%08lx\n", msg, wParam, lParam); return DefWindowProcW (hwnd, msg, wParam, lParam); diff --git a/dlls/comctl32/syslink.c b/dlls/comctl32/syslink.c index a1b8aff1e3f..a78a00c60b7 100644 --- a/dlls/comctl32/syslink.c +++ b/dlls/comctl32/syslink.c @@ -1750,7 +1750,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message, default: HandleDefaultMessage: - if ((message >= WM_USER) && (message < WM_APP)) + if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message)) { ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam ); } diff --git a/dlls/comctl32/tab.c b/dlls/comctl32/tab.c index 62047e5a08f..725cc103f84 100644 --- a/dlls/comctl32/tab.c +++ b/dlls/comctl32/tab.c @@ -3269,7 +3269,7 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TAB_NCCalcSize(hwnd, wParam, lParam); default: - if (uMsg >= WM_USER && uMsg < WM_APP) + if (uMsg >= WM_USER && uMsg < WM_APP && !COMCTL32_IsReflectedMessage(uMsg)) WARN("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); break; diff --git a/dlls/comctl32/tests/comboex.c b/dlls/comctl32/tests/comboex.c index eca7ca4b6ee..57143657e21 100644 --- a/dlls/comctl32/tests/comboex.c +++ b/dlls/comctl32/tests/comboex.c @@ -205,7 +205,7 @@ static void test_WM_LBUTTONDOWN(void) hEdit = (HWND)SendMessage(hComboEx, CBEM_GETEDITCONTROL, 0, 0); cbInfo.cbSize = sizeof(COMBOBOXINFO); - result = SendMessage(hCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbInfo); + result = GetComboBoxInfo(hCombo, &cbInfo); ok(result, "Failed to get combobox info structure. LastError=%d\n", GetLastError()); hList = cbInfo.hwndList; diff --git a/dlls/comctl32/tests/mru.c b/dlls/comctl32/tests/mru.c index d5e1d8a9aef..1e5542539e6 100644 --- a/dlls/comctl32/tests/mru.c +++ b/dlls/comctl32/tests/mru.c @@ -353,15 +353,15 @@ static void test_MRUListA(void) /* NULL buffer = get list size */ iRet = pEnumMRUList(hMRU, 0, NULL, 0); - ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet); + ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ iRet = pEnumMRUList(hMRU, -1, NULL, 0); - ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet); + ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ iRet = pEnumMRUList(hMRU, -5, NULL, 0); - ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet); + ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ iRet = pEnumMRUList(hMRU, -1, buffer, 255); diff --git a/dlls/comctl32/tests/status.c b/dlls/comctl32/tests/status.c index b6c5b7bcb8b..0ca7a935b14 100644 --- a/dlls/comctl32/tests/status.c +++ b/dlls/comctl32/tests/status.c @@ -106,12 +106,56 @@ static void test_create() DestroyWindow(hwnd); } -static void test_setfont() +static int CALLBACK check_height_font_enumproc(ENUMLOGFONTEX *enumlf, NEWTEXTMETRICEX *ntm, DWORD type, LPARAM lParam) { - HFONT hFont; + HWND hwndStatus = (HWND)lParam; + HDC hdc = GetDC(NULL); + static const int sizes[] = {8, 9, 10, 12, 16, 22, 28, 36, 48, 72}; + int i; + + trace("Font %s\n", enumlf->elfFullName); + for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++) + { + HFONT hFont; + TEXTMETRIC tm; + HFONT hCtrlFont; + HFONT hOldFont; + RECT rcCtrl; + + enumlf->elfLogFont.lfHeight = sizes[i]; + hFont = CreateFontIndirect(&enumlf->elfLogFont); + hCtrlFont = (HFONT)SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFont, TRUE); + hOldFont = SelectObject(hdc, hFont); + + GetClientRect(hwndStatus, &rcCtrl); + GetTextMetrics(hdc, &tm); + expect(max(tm.tmHeight + (tm.tmInternalLeading ? tm.tmInternalLeading : 2) + 4, 20), rcCtrl.bottom); + + SelectObject(hdc, hOldFont); + SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hCtrlFont, TRUE); + DeleteObject(hFont); + } + ReleaseDC(NULL, hdc); + return 1; +} + +static int CALLBACK check_height_family_enumproc(ENUMLOGFONTEX *enumlf, NEWTEXTMETRICEX *ntm, DWORD type, LPARAM lParam) +{ + HDC hdc = GetDC(NULL); + enumlf->elfLogFont.lfHeight = 0; + EnumFontFamiliesEx(hdc, &enumlf->elfLogFont, (FONTENUMPROC)check_height_font_enumproc, lParam, 0); + ReleaseDC(NULL, hdc); + return 1; +} + +static void test_height(void) +{ + LOGFONT lf; + HFONT hFont, hFontSm; RECT rc1, rc2; HWND hwndStatus = CreateWindow(SUBCLASS_NAME, NULL, WS_CHILD|WS_VISIBLE, 0, 0, 300, 20, g_hMainWnd, NULL, NULL, NULL); + HDC hdc; GetClientRect(hwndStatus, &rc1); hFont = CreateFont(32, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, @@ -122,7 +166,7 @@ static void test_setfont() ok(g_wmsize_count > 0, "WM_SETFONT should issue WM_SIZE\n"); GetClientRect(hwndStatus, &rc2); - todo_wine expect_rect(0, 0, 672, 42, rc2); + todo_wine expect_rect(0, 0, 672, 42, rc2); /* GetTextMetrics returns invalid tmInternalLeading for this font */ g_wmsize_count = 0; SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFont, TRUE); @@ -131,8 +175,43 @@ static void test_setfont() GetClientRect(hwndStatus, &rc2); todo_wine expect_rect(0, 0, 672, 42, rc2); + /* minheight < fontsize - no effects*/ + SendMessage(hwndStatus, SB_SETMINHEIGHT, 12, 0); + SendMessage(hwndStatus, WM_SIZE, 0, 0); + GetClientRect(hwndStatus, &rc2); + todo_wine expect_rect(0, 0, 672, 42, rc2); + + /* minheight > fontsize - has an effect after WM_SIZE */ + SendMessage(hwndStatus, SB_SETMINHEIGHT, 60, 0); + GetClientRect(hwndStatus, &rc2); + todo_wine expect_rect(0, 0, 672, 42, rc2); + SendMessage(hwndStatus, WM_SIZE, 0, 0); + GetClientRect(hwndStatus, &rc2); + expect_rect(0, 0, 672, 62, rc2); + + /* font changed to smaller than minheight - has an effect */ + SendMessage(hwndStatus, SB_SETMINHEIGHT, 30, 0); + expect_rect(0, 0, 672, 62, rc2); + SendMessage(hwndStatus, WM_SIZE, 0, 0); + GetClientRect(hwndStatus, &rc2); + todo_wine expect_rect(0, 0, 672, 42, rc2); + hFontSm = CreateFont(9, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Tahoma"); + SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFontSm, TRUE); + GetClientRect(hwndStatus, &rc2); + expect_rect(0, 0, 672, 32, rc2); + + /* test the height formula */ + ZeroMemory(&lf, sizeof(lf)); + SendMessage(hwndStatus, SB_SETMINHEIGHT, 0, 0); + hdc = GetDC(NULL); + trace("dpi=%d\n", GetDeviceCaps(hdc, LOGPIXELSY)); + EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)check_height_family_enumproc, (LPARAM)hwndStatus, 0); + ReleaseDC(NULL, hdc); + DestroyWindow(hwndStatus); DeleteObject(hFont); + DeleteObject(hFontSm); } static void test_status_control(void) @@ -294,5 +373,5 @@ START_TEST(status) test_status_control(); test_create(); - test_setfont(); + test_height(); } diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c index 2693025b2e3..4b6d3c304d3 100644 --- a/dlls/comctl32/tests/toolbar.c +++ b/dlls/comctl32/tests/toolbar.c @@ -203,6 +203,13 @@ static void rebuild_toolbar_with_buttons(HWND *hToolbar) ok(SendMessage(*hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n"); } +static void add_128x15_bitmap(HWND hToolbar, int nCmds) +{ + TBADDBITMAP bmp128; + bmp128.hInst = GetModuleHandle(NULL); + bmp128.nID = IDB_BITMAP_128x15; + ok(SendMessageA(hToolbar, TB_ADDBITMAP, nCmds, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n"); +} #define CHECK_IMAGELIST(count, dx, dy) { \ int cx, cy; \ @@ -854,6 +861,18 @@ static void test_sizes(void) ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(16, 15)); ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 21), "Unexpected button size\n"); + /* -1 in TB_SETBITMAPSIZE is a special code meaning that the coordinate shouldn't be changed */ + add_128x15_bitmap(hToolbar, 16); + ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(14, -1)), "TB_SETBITMAPSIZE failed\n"); + compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(21, 21), "%x"); + ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(-1, 12)), "TB_SETBITMAPSIZE failed\n"); + compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(21, 18), "%x"); + ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(-1, -1)), "TB_SETBITMAPSIZE failed\n"); + compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(21, 18), "%x"); + /* check the imagelist */ + InvalidateRect(hToolbar, NULL, TRUE); + UpdateWindow(hToolbar); + CHECK_IMAGELIST(16, 14, 12); rebuild_toolbar(&hToolbar); SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"A\0MMMMMMMMMMMMM\0"); diff --git a/dlls/comctl32/theme_button.c b/dlls/comctl32/theme_button.c index 588f1a42a33..54955fa99ac 100644 --- a/dlls/comctl32/theme_button.c +++ b/dlls/comctl32/theme_button.c @@ -36,6 +36,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(themingbutton); #define BUTTON_TYPE 0x0f /* bit mask for the available button types */ +typedef void (*pfThemedPaint)(HTHEME theme, HWND hwnd, HDC hdc); + static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC) { RECT bgRect, textRect; @@ -71,21 +73,42 @@ static void GB_draw(HTHEME theme, HWND hwnd, HDC hDC) if (hPrevFont) SelectObject(hDC, hPrevFont); } +static const pfThemedPaint btnThemedPaintFunc[BUTTON_TYPE + 1] = +{ + NULL, /* BS_PUSHBUTTON */ + NULL, /* BS_DEFPUSHBUTTON */ + NULL, /* BS_CHECKBOX */ + NULL, /* BS_AUTOCHECKBOX */ + NULL, /* BS_RADIOBUTTON */ + NULL, /* BS_3STATE */ + NULL, /* BS_AUTO3STATE */ + GB_draw, /* BS_GROUPBOX */ + NULL, /* BS_USERBUTTON */ + NULL, /* BS_AUTORADIOBUTTON */ + NULL, /* Not defined */ + NULL, /* BS_OWNERDRAW */ + NULL, /* Not defined */ + NULL, /* Not defined */ + NULL, /* Not defined */ + NULL, /* Not defined */ +}; + static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC) { PAINTSTRUCT ps; HDC hDC; DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE); + pfThemedPaint paint = btnThemedPaintFunc[ dwStyle & BUTTON_TYPE ]; - if ((dwStyle & BUTTON_TYPE) == BS_GROUPBOX) + if (paint) { hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps); - GB_draw(theme, hwnd, hDC); + paint(theme, hwnd, hDC); if (!hParamDC) EndPaint(hwnd, &ps); + return TRUE; } - else return FALSE; /* Delegate drawing to the non-themed code. */ - return TRUE; + return FALSE; /* Delegate drawing to the non-themed code. */ } /********************************************************************** diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c index bd37e193aab..0beb2c6954b 100644 --- a/dlls/comctl32/toolbar.c +++ b/dlls/comctl32/toolbar.c @@ -4374,26 +4374,38 @@ TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam) { TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); HIMAGELIST himlDef = GETDEFIMAGELIST(infoPtr, 0); + short width = (short)LOWORD(lParam); + short height = (short)HIWORD(lParam); TRACE("hwnd=%p, wParam=%ld, lParam=%ld\n", hwnd, wParam, lParam); if (wParam != 0) FIXME("wParam is %ld. Perhaps image list index?\n", wParam); - if (LOWORD(lParam) == 0) - lParam = MAKELPARAM(1, HIWORD(lParam)); - - if (HIWORD(lParam)==0) - lParam = MAKELPARAM(LOWORD(lParam), 1); + /* 0 width or height is changed to 1 */ + if (width == 0) + width = 1; + if (height == 0) + height = 1; if (infoPtr->nNumButtons > 0) - WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n", - infoPtr->nNumButtons, - infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, - LOWORD(lParam), HIWORD(lParam)); + TRACE("%d buttons, undoc change to bitmap size : %d-%d -> %d-%d\n", + infoPtr->nNumButtons, + infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, width, height); + + if (width < -1 || height < -1) + { + /* Windows destroys the imagelist and seems to actually use negative + * values to compute button sizes */ + FIXME("Negative bitmap sizes not supported (%d, %d)\n", width, height); + return FALSE; + } - infoPtr->nBitmapWidth = (INT)LOWORD(lParam); - infoPtr->nBitmapHeight = (INT)HIWORD(lParam); + /* width or height of -1 means no change */ + if (width != -1) + infoPtr->nBitmapWidth = width; + if (height != -1) + infoPtr->nBitmapHeight = height; if ((himlDef == infoPtr->himlInt) && (ImageList_GetImageCount(infoPtr->himlInt) == 0)) @@ -7046,7 +7058,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DefWindowProcW (hwnd, uMsg, wParam, lParam); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index 5368835c476..f7e538b0f01 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c @@ -2843,7 +2843,7 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TOOLTIPS_WinIniChange (hwnd, wParam, lParam); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/trackbar.c b/dlls/comctl32/trackbar.c index 67cf32d4f40..d540f005669 100644 --- a/dlls/comctl32/trackbar.c +++ b/dlls/comctl32/trackbar.c @@ -1911,7 +1911,7 @@ TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TRACKBAR_InitializeThumb (infoPtr); default: - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam); } diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index f2f0eb91890..51e11bfe3ba 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -5705,7 +5705,7 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) default: /* This mostly catches MFC and Delphi messages. :( */ - if ((uMsg >= WM_USER) && (uMsg < WM_APP)) + if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) TRACE("Unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); def: return DefWindowProcW(hwnd, uMsg, wParam, lParam); diff --git a/dlls/comctl32/updown.c b/dlls/comctl32/updown.c index a62e22134bd..a971afa1c46 100644 --- a/dlls/comctl32/updown.c +++ b/dlls/comctl32/updown.c @@ -1082,7 +1082,7 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L return temp; default: - if ((message >= WM_USER) && (message < WM_APP)) + if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message)) ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam); return DefWindowProcW (hwnd, message, wParam, lParam); } diff --git a/dlls/crtdll/crtdll_main.c b/dlls/crtdll/crtdll_main.c index 8e5cc18a6c0..60c42647bc7 100644 --- a/dlls/crtdll/crtdll_main.c +++ b/dlls/crtdll/crtdll_main.c @@ -37,14 +37,14 @@ extern void CDECL __getmainargs( int *argc, char ***argv, char ***envp, int expand_wildcards, int *new_mode ); /* The following data items are not exported from msvcrt */ -unsigned int CRTDLL__basemajor_dll; -unsigned int CRTDLL__baseminor_dll; -unsigned int CRTDLL__baseversion_dll; -unsigned int CRTDLL__cpumode_dll; -unsigned int CRTDLL__osmajor_dll; -unsigned int CRTDLL__osminor_dll; -unsigned int CRTDLL__osmode_dll; -unsigned int CRTDLL__osversion_dll; +unsigned int CRTDLL__basemajor_dll = 0; +unsigned int CRTDLL__baseminor_dll = 0; +unsigned int CRTDLL__baseversion_dll = 0; +unsigned int CRTDLL__cpumode_dll = 0; +unsigned int CRTDLL__osmajor_dll = 0; +unsigned int CRTDLL__osminor_dll = 0; +unsigned int CRTDLL__osmode_dll = 0; +unsigned int CRTDLL__osversion_dll = 0; /* dev_t is a short in crtdll but an unsigned int in msvcrt */ typedef short crtdll_dev_t; diff --git a/dlls/crypt32/sip.c b/dlls/crypt32/sip.c index 869e2a95ca8..f8e8be45612 100644 --- a/dlls/crypt32/sip.c +++ b/dlls/crypt32/sip.c @@ -283,6 +283,8 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid IMAGE_DOS_HEADER *dos; /* FIXME, find out if there is a name for this GUID */ static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; + static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }}; + static const BYTE cabHdr[] = { 'M','S','C','F' }; TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject); @@ -330,10 +332,17 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid bRet = TRUE; goto cleanup1; } + /* Quick-n-dirty check for a cab file. FIXME: use FDIIsCabinet instead? */ + if (!memcmp(pMapped, cabHdr, sizeof(cabHdr))) + { + *pgSubject = cabGUID; + SetLastError(S_OK); + bRet = TRUE; + goto cleanup1; + } /* FIXME * There is a lot more to be checked: - * - Check for MSFC in the header * - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2 * under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are * functions listed that need check if a SIP Provider can deal with the diff --git a/dlls/crypt32/tests/base64.c b/dlls/crypt32/tests/base64.c index 4dd7c5f092f..965b3f8a5eb 100644 --- a/dlls/crypt32/tests/base64.c +++ b/dlls/crypt32/tests/base64.c @@ -280,7 +280,7 @@ static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header, ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); else ok(!ret && GetLastError() == ERROR_INVALID_DATA, - "Expected ERROR_INVALID_DATA, got %d\n", GetLastError()); + "Expected !ret and last error ERROR_INVALID_DATA, got ret=%d, error=%d\n", ret, GetLastError()); if (ret) { buf = HeapAlloc(GetProcessHeap(), 0, bufLen); @@ -291,8 +291,8 @@ static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header, ret = pCryptStringToBinaryA(str, 0, useFormat, buf, &bufLen, &skipped, &usedFormat); ok(skipped == strlen(garbage), - "Expected %d characters skipped, got %d\n", lstrlenA(garbage), - skipped); + "Expected %d characters of \"%s\" skipped when trying format %08x, got %d (used format is %08x)\n", + lstrlenA(garbage), str, useFormat, skipped, usedFormat); HeapFree(GetProcessHeap(), 0, buf); } } diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c index e88d382e389..592b59e2a96 100644 --- a/dlls/crypt32/tests/msg.c +++ b/dlls/crypt32/tests/msg.c @@ -27,8 +27,11 @@ #include "wine/test.h" +static BOOL have_nt; static char oid_rsa_md5[] = szOID_RSA_MD5; +static BOOL (WINAPI * pCryptAcquireContextA) + (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); static BOOL (WINAPI * pCryptAcquireContextW) (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD); @@ -41,6 +44,7 @@ static void init_function_pointers(void) if(!p ## func) \ trace("GetProcAddress(%s) failed\n", #func); + GET_PROC(hAdvapi32, CryptAcquireContextA) GET_PROC(hAdvapi32, CryptAcquireContextW) #undef GET_PROC @@ -379,8 +383,10 @@ static void test_data_msg_update(void) /* Can't update a message with no data */ SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, NULL, 0, TRUE); - ok(!ret && GetLastError() == E_INVALIDARG, - "Expected E_INVALIDARG, got %x\n", GetLastError()); + /* NT: E_INVALIDARG, 9x: unchanged */ + ok(!ret && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef), + "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError()); + /* Curiously, a valid update will now fail as well, presumably because of * the last (invalid, but final) update. */ @@ -803,8 +809,11 @@ static void test_hash_msg_get_param(void) /* By getting the hash, further updates are not allowed */ SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); - ok(!ret && GetLastError() == NTE_BAD_HASH_STATE, - "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError()); + /* NT: NTE_BAD_HASH_STATE, 9x: NTE_BAD_ALGID */ + ok(!ret && + (GetLastError() == NTE_BAD_HASH_STATE || GetLastError() == NTE_BAD_ALGID), + "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got 0x%x\n", GetLastError()); + /* Even after a final update, the hash data aren't available */ SetLastError(0xdeadbeef); ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size); @@ -848,8 +857,11 @@ static void test_hash_msg_get_param(void) */ SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); - ok(!ret && GetLastError() == NTE_BAD_HASH_STATE, - "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError()); + /* NT: NTE_BAD_HASH_STATE, 9x: NTE_BAD_ALGID */ + ok(!ret && + (GetLastError() == NTE_BAD_HASH_STATE || GetLastError() == NTE_BAD_ALGID), + "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID, got 0x%x\n", GetLastError()); + CryptMsgClose(msg); } @@ -995,6 +1007,8 @@ static void test_hash_msg(void) test_hash_msg_encoding(); } +static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e', + 'm','p',0 }; static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e', 'm','p',0 }; static BYTE serialNum[] = { 1 }; @@ -1030,15 +1044,19 @@ static void test_signed_msg_open(void) SetLastError(0xdeadbeef); msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, NULL, NULL); - ok(!msg && GetLastError() == E_INVALIDARG, - "Expected E_INVALIDARG, got %x\n", GetLastError()); + /* NT: E_INVALIDARG, 9x: unchanged */ + ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef), + "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError()); + certInfo.SerialNumber.cbData = sizeof(serialNum); certInfo.SerialNumber.pbData = serialNum; SetLastError(0xdeadbeef); msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, NULL, NULL); - ok(!msg && GetLastError() == E_INVALIDARG, - "Expected E_INVALIDARG, got %x\n", GetLastError()); + /* NT: E_INVALIDARG, 9x: unchanged */ + ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef), + "Expected E_INVALIDARG or 0xdeadbeef, got 0x%x\n", GetLastError()); + certInfo.Issuer.cbData = sizeof(encodedCommonName); certInfo.Issuer.pbData = encodedCommonName; SetLastError(0xdeadbeef); @@ -1068,19 +1086,23 @@ static void test_signed_msg_open(void) "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); } /* The signer's hCryptProv must also be valid. */ - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, CRYPT_NEWKEYSET); - if (!ret && GetLastError() == NTE_EXISTS) - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, 0); - ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError()); - msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, - NULL, NULL); - ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); - CryptMsgClose(msg); + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, CRYPT_NEWKEYSET); + if (!ret && GetLastError() == NTE_EXISTS) { + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, 0); + } + ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); + + if (ret) { + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, + NULL, NULL); + ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); + CryptMsgClose(msg); + } CryptReleaseContext(signer.hCryptProv, 0); - pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W, + pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_DELETEKEYSET); } @@ -1133,12 +1155,20 @@ static void test_signed_msg_update(void) signer.HashAlgorithm.pszObjId = oid_rsa_md5; signInfo.cSigners = 1; signInfo.rgSigners = &signer; - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, CRYPT_NEWKEYSET); - if (!ret && GetLastError() == NTE_EXISTS) - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, 0); - ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError()); + + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, CRYPT_NEWKEYSET); + if (!ret && GetLastError() == NTE_EXISTS) { + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, 0); + } + ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); + + if (!ret) { + skip("No context for tests\n"); + return; + } + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL); ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); @@ -1215,7 +1245,7 @@ static void test_signed_msg_update(void) CryptDestroyKey(key); CryptReleaseContext(signer.hCryptProv, 0); - pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL, + pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET); } @@ -1555,12 +1585,20 @@ static void test_signed_msg_encoding(void) signer.HashAlgorithm.pszObjId = oid_rsa_md5; signInfo.cSigners = 1; signInfo.rgSigners = &signer; - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, CRYPT_NEWKEYSET); - if (!ret && GetLastError() == NTE_EXISTS) - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, 0); - ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError()); + + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, CRYPT_NEWKEYSET); + if (!ret && GetLastError() == NTE_EXISTS) { + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, 0); + } + ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); + + if (!ret) { + skip("No context for tests\n"); + return; + } + ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key); ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); @@ -1699,7 +1737,7 @@ static void test_signed_msg_encoding(void) CryptDestroyKey(key); CryptReleaseContext(signer.hCryptProv, 0); - pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL, + pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET); } @@ -1758,12 +1796,20 @@ static void test_signed_msg_get_param(void) signer.HashAlgorithm.pszObjId = oid_rsa_md5; signInfo.cSigners = 1; signInfo.rgSigners = &signer; - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, CRYPT_NEWKEYSET); - if (!ret && GetLastError() == NTE_EXISTS) - ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, - PROV_RSA_FULL, 0); - ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError()); + + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, CRYPT_NEWKEYSET); + if (!ret && GetLastError() == NTE_EXISTS) { + ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, + PROV_RSA_FULL, 0); + } + ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); + + if (!ret) { + skip("No context for tests\n"); + return; + } + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, NULL, NULL); ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); @@ -1793,7 +1839,7 @@ static void test_signed_msg_get_param(void) CryptMsgClose(msg); CryptReleaseContext(signer.hCryptProv, 0); - pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W, + pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_DELETEKEYSET); } @@ -2248,7 +2294,7 @@ static void test_msg_control(void) msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, NULL); /* either with no prior update.. */ - for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++) + for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { SetLastError(0xdeadbeef); ret = CryptMsgControl(msg, 0, i, NULL); @@ -2256,7 +2302,7 @@ static void test_msg_control(void) "Expected E_INVALIDARG, got %08x\n", GetLastError()); } /* or after an update. */ - for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++) + for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { SetLastError(0xdeadbeef); ret = CryptMsgControl(msg, 0, i, NULL); @@ -2271,7 +2317,7 @@ static void test_msg_control(void) msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, NULL, NULL); /* either with no prior update.. */ - for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++) + for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { SetLastError(0xdeadbeef); ret = CryptMsgControl(msg, 0, i, NULL); @@ -2280,7 +2326,7 @@ static void test_msg_control(void) } ret = CryptMsgUpdate(msg, NULL, 0, TRUE); /* or after an update. */ - for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++) + for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { SetLastError(0xdeadbeef); ret = CryptMsgControl(msg, 0, i, NULL); @@ -2294,7 +2340,7 @@ static void test_msg_control(void) msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, NULL, NULL); /* either before an update.. */ - for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++) + for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { SetLastError(0xdeadbeef); ret = CryptMsgControl(msg, 0, i, NULL); @@ -2303,7 +2349,7 @@ static void test_msg_control(void) } ret = CryptMsgUpdate(msg, NULL, 0, TRUE); /* or after an update. */ - for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++) + for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { SetLastError(0xdeadbeef); ret = CryptMsgControl(msg, 0, i, NULL); @@ -2644,9 +2690,44 @@ static void test_verify_message_signature(void) ok(!ret, "Expected failure\n"); } +/* win9x has much less parameter checks and will crash on many tests + * this code is from test_signed_msg_update() + */ +static BOOL detect_nt(void) +{ + BOOL ret; + CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 }; + CERT_INFO certInfo = { 0 }; + + + certInfo.SerialNumber.cbData = sizeof(serialNum); + certInfo.SerialNumber.pbData = serialNum; + certInfo.Issuer.cbData = sizeof(encodedCommonName); + certInfo.Issuer.pbData = encodedCommonName; + signer.pCertInfo = &certInfo; + signer.HashAlgorithm.pszObjId = oid_rsa_md5; + + ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, + PROV_RSA_FULL, CRYPT_NEWKEYSET); + if (!ret && GetLastError() == NTE_EXISTS) { + ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, + PROV_RSA_FULL, 0); + } + + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE; + + /* cleanup */ + CryptReleaseContext(signer.hCryptProv, 0); + pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL, + CRYPT_DELETEKEYSET); + + return TRUE; +} + START_TEST(msg) { - init_function_pointers(); + init_function_pointers(); + have_nt = detect_nt(); /* Basic parameter checking tests */ test_msg_open_to_encode(); diff --git a/dlls/crypt32/tests/protectdata.c b/dlls/crypt32/tests/protectdata.c index b77b81b0e99..30b55b4b942 100644 --- a/dlls/crypt32/tests/protectdata.c +++ b/dlls/crypt32/tests/protectdata.c @@ -82,10 +82,6 @@ static void test_cryptprotectdata(void) SetLastError(0xDEADBEEF); protected = pCryptProtectData(&plain,desc,&entropy,NULL,NULL,0,&cipher_entropy); ok(protected, "Encrypting with entropy.\n"); - r = GetLastError(); - ok(r == ERROR_SUCCESS || - r == ERROR_IO_PENDING, /* win2k */ - "Expected ERROR_SUCCESS or ERROR_IO_PENDING, got %d\n",r); cipher_no_desc.pbData=NULL; cipher_no_desc.cbData=0; @@ -95,16 +91,11 @@ static void test_cryptprotectdata(void) plain.cbData=strlen(secret2)+1; SetLastError(0xDEADBEEF); protected = pCryptProtectData(&plain,NULL,&entropy,NULL,NULL,0,&cipher_no_desc); - r = GetLastError(); - if (protected) - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - } - else + if (!protected) { /* fails in win2k */ - ok(r == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", r); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); } } @@ -158,8 +149,6 @@ static void test_cryptunprotectdata(void) SetLastError(0xDEADBEEF); okay = pCryptUnprotectData(&cipher,&data_desc,NULL,NULL,NULL,0,&plain); ok(okay,"Decrypting without entropy\n"); - r = GetLastError(); - ok(r == ERROR_SUCCESS, "Wrong (%u) GetLastError seen\n",r); ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); ok(plain.cbData==strlen(secret)+1,"Plain DATA_BLOB wrong length\n"); @@ -185,8 +174,6 @@ static void test_cryptunprotectdata(void) SetLastError(0xDEADBEEF); okay = pCryptUnprotectData(&cipher_entropy,&data_desc,&entropy,NULL,NULL,0,&plain); ok(okay,"Decrypting with entropy\n"); - r = GetLastError(); - ok(r == ERROR_SUCCESS, "Wrong (%u) GetLastError seen\n",r); ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); ok(plain.cbData==strlen(secret)+1,"Plain DATA_BLOB wrong length\n"); @@ -205,8 +192,6 @@ static void test_cryptunprotectdata(void) SetLastError(0xDEADBEEF); okay = pCryptUnprotectData(&cipher_no_desc,&data_desc,&entropy,NULL,NULL,0,&plain); ok(okay,"Decrypting with entropy and no description\n"); - r = GetLastError(); - ok(r == ERROR_SUCCESS, "Wrong (%u) GetLastError seen\n",r); ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); ok(plain.cbData==strlen(secret2)+1,"Plain DATA_BLOB wrong length\n"); diff --git a/dlls/crypt32/tests/sip.c b/dlls/crypt32/tests/sip.c index d47b6fca575..b01229c0ce4 100644 --- a/dlls/crypt32/tests/sip.c +++ b/dlls/crypt32/tests/sip.c @@ -2,6 +2,7 @@ * Subject Interface Package tests * * Copyright 2006 Paul Vriens + * Copyright 2008 Juan Lang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,17 +36,15 @@ static BOOL (WINAPI * funcCryptSIPCreateIndirectData)(SIP_SUBJECTINFO *,DWORD *, static BOOL (WINAPI * funcCryptSIPVerifyIndirectData)(SIP_SUBJECTINFO *,SIP_INDIRECT_DATA *); static BOOL (WINAPI * funcCryptSIPRemoveSignedDataMsg)(SIP_SUBJECTINFO *,DWORD); -static char *show_guid(const GUID *guid) +static char *show_guid(const GUID *guid, char *buf) { - static char guidstring[39]; - - sprintf(guidstring, + sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); - return guidstring; + return buf; } static void test_AddRemoveProvider(void) @@ -131,6 +130,14 @@ static void test_AddRemoveProvider(void) ok ( ret, "CryptSIPRemoveProvider should have succeeded\n"); } +static const BYTE cabFileData[] = { +0x4d,0x53,0x43,0x46,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x01,0x00,0x01,0x00,0x00,0x00, +0xef,0xbe,0xff,0xff,0x42,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xf7,0x38,0x4b,0xac,0x00,0x00,0x61,0x2e,0x74,0x78, +0x74,0x00,0x6d,0x5a,0x72,0x78,0x06,0x00,0x06,0x00,0x61,0x2e,0x74,0x78,0x74,0x0a, +}; + static void test_SIPRetrieveSubjectGUID(void) { BOOL ret; @@ -142,11 +149,13 @@ static void test_SIPRetrieveSubjectGUID(void) static const WCHAR deadbeef[] = { 'c',':','\\','d','e','a','d','b','e','e','f','.','d','b','f',0 }; /* Couldn't find a name for this GUID, it's the one used for 95% of the files */ static const GUID unknownGUID = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; + static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }}; static CHAR regeditPath[MAX_PATH]; static WCHAR regeditPathW[MAX_PATH]; static CHAR path[MAX_PATH]; static CHAR tempfile[MAX_PATH]; static WCHAR tempfileW[MAX_PATH]; + static char guid1[39], guid2[39]; DWORD written; /* NULL check */ @@ -165,7 +174,7 @@ static void test_SIPRetrieveSubjectGUID(void) ok (GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d.\n", GetLastError()); ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject)); + "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject, guid1)); /* Now with an executable that should exist * @@ -184,7 +193,7 @@ static void test_SIPRetrieveSubjectGUID(void) ret = CryptSIPRetrieveSubjectGuid(regeditPathW, NULL, &subject); ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), - "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); + "Expected (%s), got (%s).\n", show_guid(&unknownGUID, guid1), show_guid(&subject, guid2)); /* The same thing but now with a handle instead of a filename */ file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -193,7 +202,7 @@ static void test_SIPRetrieveSubjectGUID(void) ret = CryptSIPRetrieveSubjectGuid(NULL, file, &subject); ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), - "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); + "Expected (%s), got (%s).\n", show_guid(&unknownGUID, guid1), show_guid(&subject, guid2)); CloseHandle(file); /* And both */ @@ -203,7 +212,7 @@ static void test_SIPRetrieveSubjectGUID(void) ret = CryptSIPRetrieveSubjectGuid(regeditPathW, file, &subject); ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), - "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); + "Expected (%s), got (%s).\n", show_guid(&unknownGUID, guid1), show_guid(&subject, guid2)); CloseHandle(file); /* Now with an empty file */ @@ -222,7 +231,7 @@ static void test_SIPRetrieveSubjectGUID(void) GetLastError() == ERROR_SUCCESS /* Win98 */, "Expected ERROR_FILE_INVALID, ERROR_INVALID_PARAMETER or ERROR_SUCCESS, got 0x%08x\n", GetLastError()); ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); + "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject, guid1)); /* Use a file with a size of 3 (at least < 4) */ file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -237,7 +246,7 @@ static void test_SIPRetrieveSubjectGUID(void) GetLastError() == ERROR_SUCCESS /* Win98 */, "Expected ERROR_INVALID_PARAMETER or ERROR_SUCCESS, got 0x%08x\n", GetLastError()); ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); + "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject, guid1)); /* And now >= 4 */ file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -252,10 +261,25 @@ static void test_SIPRetrieveSubjectGUID(void) GetLastError() == ERROR_SUCCESS /* Win98 */, "Expected TRUST_E_SUBJECT_FORM_UNKNOWN or ERROR_SUCCESS, got 0x%08x\n", GetLastError()); ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); + "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject, guid1)); /* Clean up */ DeleteFileA(tempfile); + + /* Create a .cab file */ + file = CreateFileW(tempfileW, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); + WriteFile(file, cabFileData, sizeof(cabFileData), &written, NULL); + CloseHandle(file); + + SetLastError(0xdeadbeef); + memset(&subject, 1, sizeof(GUID)); + ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); + ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n", + GetLastError(), GetLastError() ); + ok ( !memcmp(&subject, &cabGUID, sizeof(GUID)), + "Expected GUID %s for cabinet file, not %s\n", show_guid(&cabGUID, guid1), show_guid(&subject, guid2)); + /* Clean up */ + DeleteFileW(tempfileW); } static void test_SIPLoad(void) diff --git a/dlls/cryptnet/tests/cryptnet.c b/dlls/cryptnet/tests/cryptnet.c index 25edaa6963a..0907a53aa28 100644 --- a/dlls/cryptnet/tests/cryptnet.c +++ b/dlls/cryptnet/tests/cryptnet.c @@ -263,10 +263,11 @@ static void test_retrieveObjectByUrl(void) FILETIME ft = { 0 }; SetLastError(0xdeadbeef); - ret = CryptRetrieveObjectByUrlA(NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, - NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + ret = CryptRetrieveObjectByUrlA(NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL); + ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == E_INVALIDARG), + "got 0x%x/%u (expected ERROR_INVALID_PARAMETER or E_INVALIDARG)\n", + GetLastError(), GetLastError()); make_tmp_file(tmpfile); ptr = strchr(tmpfile, ':'); @@ -305,9 +306,21 @@ static void test_retrieveObjectByUrl(void) SetLastError(0xdeadbeef); ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CRL, 0, 0, (void **)&crl, NULL, NULL, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, - "Expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); - ok(crl == NULL, "Expected CRL to be NULL\n"); + /* vista: ERROR_NOT_SUPPORTED, w2k3,XP, newer w2k: CRYPT_E_NO_MATCH, + 95: OSS_DATA_ERROR */ + ok(!ret && (GetLastError() == ERROR_NOT_SUPPORTED || + GetLastError() == CRYPT_E_NO_MATCH || + GetLastError() == CRYPT_E_ASN1_BADTAG || + GetLastError() == OSS_DATA_ERROR), + "got 0x%x/%u (expected CRYPT_E_NO_MATCH or CRYPT_E_ASN1_BADTAG or " + "OSS_DATA_ERROR)\n", GetLastError(), GetLastError()); + + /* only newer versions of cryptnet do the cleanup */ + if(!ret && GetLastError() != CRYPT_E_ASN1_BADTAG && + GetLastError() != OSS_DATA_ERROR) { + ok(crl == NULL, "Expected CRL to be NULL\n"); + } + if (crl && crl != (PCCRL_CONTEXT)0xdeadbeef) CertFreeCRLContext(crl); store = (HCERTSTORE)0xdeadbeef; @@ -328,20 +341,38 @@ static void test_retrieveObjectByUrl(void) CertCloseStore(store, 0); } /* Are file URLs cached? */ + cert = (PCCERT_CONTEXT)0xdeadbeef; ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, CRYPT_CACHE_ONLY_RETRIEVAL, 0, (void **)&cert, NULL, NULL, NULL, NULL); ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError()); if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef) CertFreeCertificateContext(cert); + + cert = (PCCERT_CONTEXT)0xdeadbeef; ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0, (void **)&cert, NULL, NULL, NULL, &aux); - ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError()); + /* w2k: success, 9x: fail with E_INVALIDARG */ + ok(ret || (GetLastError() == E_INVALIDARG), + "got %u with 0x%x/%u (expected '!=0' or '0' with E_INVALIDARG)\n", + ret, GetLastError(), GetLastError()); if (cert && cert != (PCCERT_CONTEXT)0xdeadbeef) CertFreeCertificateContext(cert); + + cert = (PCCERT_CONTEXT)0xdeadbeef; aux.cbSize = sizeof(aux); ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0, (void **)&cert, NULL, NULL, NULL, &aux); - ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError()); + /* w2k: success, 9x: fail with E_INVALIDARG */ + ok(ret || (GetLastError() == E_INVALIDARG), + "got %u with 0x%x/%u (expected '!=0' or '0' with E_INVALIDARG)\n", + ret, GetLastError(), GetLastError()); + if (!ret) { + /* no more tests useful */ + DeleteFileA(tmpfile); + skip("no usable CertificateContext\n"); + return; + } + aux.pLastSyncTime = &ft; ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0, (void **)&cert, NULL, NULL, NULL, &aux); diff --git a/dlls/d3d9/tests/vertexdeclaration.c b/dlls/d3d9/tests/vertexdeclaration.c index 292087f5cbc..ad7b8737b7f 100644 --- a/dlls/d3d9/tests/vertexdeclaration.c +++ b/dlls/d3d9/tests/vertexdeclaration.c @@ -786,6 +786,60 @@ static void test_vertex_declaration_alignment( } } +static void test_unused_type( + IDirect3DDevice9* device) { + + HRESULT hr; + IDirect3DVertexDeclaration9* result_decl = NULL; + int i; + + static const D3DVERTEXELEMENT9 test_elements[][3] = + { + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR , 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12}, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12}, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL, 0 }, + D3DDECL_END() + }, + }; + + for(i = 0; i < sizeof(test_elements) / sizeof(test_elements[0]); i++) { + result_decl = NULL; + hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &result_decl); + ok(hr == E_FAIL, "CreateVertexDeclaration for declaration %d returned %#x, expected E_FAIL(%#x)\n", + i, hr, E_FAIL); + if(result_decl) IDirect3DVertexDeclaration9_Release(result_decl); + } +} START_TEST(vertexdeclaration) { static D3DVERTEXELEMENT9 simple_decl[] = { @@ -821,4 +875,5 @@ START_TEST(vertexdeclaration) test_fvf_decl_conversion(device_ptr); test_fvf_decl_management(device_ptr); test_vertex_declaration_alignment(device_ptr); + test_unused_type(device_ptr); } diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index a63d5e3af4a..60b1fad9c83 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -1,5 +1,5 @@ /* - * Copyright 2005, 2007 Henri Verbeet + * Copyright 2005, 2007-2008 Henri Verbeet * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers) * Copyright (C) 2008 Jason Green(for TransGaming) * @@ -5919,7 +5919,7 @@ void test_vshader_input(IDirect3DDevice9 *device) }; IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader; HRESULT hr; - DWORD color, r, g, b; + DWORD color; float quad1[] = { -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0, 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0, @@ -6094,7 +6094,7 @@ void test_vshader_input(IDirect3DDevice9 *device) if(i == 3 || i == 2) { color = getPixelColor(device, 160, 360); - ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1), "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color); /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */ @@ -6103,20 +6103,20 @@ void test_vshader_input(IDirect3DDevice9 *device) "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color); color = getPixelColor(device, 160, 120); /* Same as above, accept both the last used value and 0.0 for the undefined streams */ - ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color); color = getPixelColor(device, 480, 160); ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color); } else if(i == 1) { color = getPixelColor(device, 160, 360); - ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1), "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color); color = getPixelColor(device, 480, 360); /* Accept the clear color as well in this case, since SW VP returns an error */ ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color); color = getPixelColor(device, 160, 120); - ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color); color = getPixelColor(device, 480, 160); ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color); @@ -6252,28 +6252,16 @@ void test_vshader_input(IDirect3DDevice9 *device) ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr); color = getPixelColor(device, 160, 360); - r = (color & 0x00ff0000) >> 16; - g = (color & 0x0000ff00) >> 8; - b = (color & 0x000000ff) >> 0; - ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1), "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color); color = getPixelColor(device, 480, 360); - r = (color & 0x00ff0000) >> 16; - g = (color & 0x0000ff00) >> 8; - b = (color & 0x000000ff) >> 0; - ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1), "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color); color = getPixelColor(device, 160, 120); - r = (color & 0x00ff0000) >> 16; - g = (color & 0x0000ff00) >> 8; - b = (color & 0x000000ff) >> 0; - ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1), "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color); color = getPixelColor(device, 480, 160); - r = (color & 0x00ff0000) >> 16; - g = (color & 0x0000ff00) >> 8; - b = (color & 0x000000ff) >> 0; - ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01, + ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1), "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color); IDirect3DVertexShader9_Release(texcoord_color_shader); @@ -8723,7 +8711,7 @@ static void stream_test(IDirect3DDevice9 *device) BYTE *data; DWORD color; DWORD ind; - int i; + unsigned i; const DWORD shader_code[] = { @@ -9065,7 +9053,7 @@ static void texop_test(IDirect3DDevice9 *device) D3DCOLOR color; D3DCAPS9 caps; HRESULT hr; - int i; + unsigned i; static const struct { float x, y, z; diff --git a/dlls/d3dx8/Makefile.in b/dlls/d3dx8/Makefile.in index 4e45b53272c..0f61ee293a3 100644 --- a/dlls/d3dx8/Makefile.in +++ b/dlls/d3dx8/Makefile.in @@ -9,7 +9,8 @@ IMPORTS = dxguid uuid kernel32 C_SRCS = \ d3dx8_main.c \ d3dxbuffer.c \ - math.c + math.c \ + mesh.c @MAKE_DLL_RULES@ diff --git a/dlls/d3dx8/d3dx8.spec b/dlls/d3dx8/d3dx8.spec index 0ccfdf26e55..b7c8577654a 100644 --- a/dlls/d3dx8/d3dx8.spec +++ b/dlls/d3dx8/d3dx8.spec @@ -108,7 +108,7 @@ @ stub D3DXFVFFromDeclarator @ stub D3DXWeldVertices @ stub D3DXIntersect -@ stub D3DXSphereBoundProbe +@ stdcall D3DXSphereBoundProbe(ptr long ptr ptr) @ stub D3DXBoxBoundProbe @ stub D3DXCreatePolygon @ stub D3DXCreateBox diff --git a/dlls/d3dx8/math.c b/dlls/d3dx8/math.c index a65a934bb40..93a0b49131e 100644 --- a/dlls/d3dx8/math.c +++ b/dlls/d3dx8/math.c @@ -202,15 +202,17 @@ D3DXMATRIX* WINAPI D3DXMatrixLookAtRH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, D3DXMATRIX* WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2) { + D3DXMATRIX out; int i,j; for (i=0; i<4; i++) { for (j=0; j<4; j++) { - pout->u.m[i][j] = pm1->u.m[i][0] * pm2->u.m[0][j] + pm1->u.m[i][1] * pm2->u.m[1][j] + pm1->u.m[i][2] * pm2->u.m[2][j] + pm1->u.m[i][3] * pm2->u.m[3][j]; + out.u.m[i][j] = pm1->u.m[i][0] * pm2->u.m[0][j] + pm1->u.m[i][1] * pm2->u.m[1][j] + pm1->u.m[i][2] * pm2->u.m[2][j] + pm1->u.m[i][3] * pm2->u.m[3][j]; } } + *pout = out; return pout; } @@ -566,13 +568,14 @@ D3DXMATRIX* WINAPI D3DXMatrixTranslation(D3DXMATRIX *pout, FLOAT x, FLOAT y, FLO D3DXMATRIX* WINAPI D3DXMatrixTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm) { + CONST D3DXMATRIX m = *pm; int i,j; for (i=0; i<4; i++) { for (j=0; j<4; j++) { - pout->u.m[i][j] = pm->u.m[j][i]; + pout->u.m[i][j] = m.u.m[j][i]; } } return pout; @@ -824,10 +827,11 @@ D3DXPLANE* WINAPI D3DXPlaneNormalize(D3DXPLANE *pout, CONST D3DXPLANE *pp) D3DXPLANE* WINAPI D3DXPlaneTransform(D3DXPLANE *pout, CONST D3DXPLANE *pplane, CONST D3DXMATRIX *pm) { - pout->a = pm->u.m[0][0] * pplane->a + pm->u.m[1][0] * pplane->b + pm->u.m[2][0] * pplane->c + pm->u.m[3][0] * pplane->d; - pout->b = pm->u.m[0][1] * pplane->a + pm->u.m[1][1] * pplane->b + pm->u.m[2][1] * pplane->c + pm->u.m[3][1] * pplane->d; - pout->c = pm->u.m[0][2] * pplane->a + pm->u.m[1][2] * pplane->b + pm->u.m[2][2] * pplane->c + pm->u.m[3][2] * pplane->d; - pout->d = pm->u.m[0][3] * pplane->a + pm->u.m[1][3] * pplane->b + pm->u.m[2][3] * pplane->c + pm->u.m[3][3] * pplane->d; + CONST D3DXPLANE plane = *pplane; + pout->a = pm->u.m[0][0] * plane.a + pm->u.m[1][0] * plane.b + pm->u.m[2][0] * plane.c + pm->u.m[3][0] * plane.d; + pout->b = pm->u.m[0][1] * plane.a + pm->u.m[1][1] * plane.b + pm->u.m[2][1] * plane.c + pm->u.m[3][1] * plane.d; + pout->c = pm->u.m[0][2] * plane.a + pm->u.m[1][2] * plane.b + pm->u.m[2][2] * plane.c + pm->u.m[3][2] * plane.d; + pout->d = pm->u.m[0][3] * plane.a + pm->u.m[1][3] * plane.b + pm->u.m[2][3] * plane.c + pm->u.m[3][3] * plane.d; return pout; } @@ -921,10 +925,12 @@ D3DXQUATERNION* WINAPI D3DXQuaternionLn(D3DXQUATERNION *pout, CONST D3DXQUATERNI D3DXQUATERNION* WINAPI D3DXQuaternionMultiply(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2) { - pout->x = pq2->w * pq1->x + pq2->x * pq1->w + pq2->y * pq1->z - pq2->z * pq1->y; - pout->y = pq2->w * pq1->y - pq2->x * pq1->z + pq2->y * pq1->w + pq2->z * pq1->x; - pout->z = pq2->w * pq1->z + pq2->x * pq1->y - pq2->y * pq1->x + pq2->z * pq1->w; - pout->w = pq2->w * pq1->w - pq2->x * pq1->x - pq2->y * pq1->y - pq2->z * pq1->z; + D3DXQUATERNION out; + out.x = pq2->w * pq1->x + pq2->x * pq1->w + pq2->y * pq1->z - pq2->z * pq1->y; + out.y = pq2->w * pq1->y - pq2->x * pq1->z + pq2->y * pq1->w + pq2->z * pq1->x; + out.z = pq2->w * pq1->z + pq2->x * pq1->y - pq2->y * pq1->x + pq2->z * pq1->w; + out.w = pq2->w * pq1->w - pq2->x * pq1->x - pq2->y * pq1->y - pq2->z * pq1->z; + *pout = out; return pout; } @@ -1129,8 +1135,9 @@ D3DXVECTOR2* WINAPI D3DXVec2TransformCoord(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 norm = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[3][3]; if ( norm ) { - pout->x = (pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[3][0]) / norm; - pout->y = (pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[3][1]) / norm; + CONST D3DXVECTOR2 v = *pv; + pout->x = (pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[3][0]) / norm; + pout->y = (pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[3][1]) / norm; } else { @@ -1142,8 +1149,9 @@ D3DXVECTOR2* WINAPI D3DXVec2TransformCoord(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 D3DXVECTOR2* WINAPI D3DXVec2TransformNormal(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm) { - pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y; - pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y; + CONST D3DXVECTOR2 v = *pv; + pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y; + pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y; return pout; } @@ -1231,9 +1239,10 @@ D3DXVECTOR3* WINAPI D3DXVec3TransformCoord(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 if ( norm ) { - pout->x = (pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0]) / norm; - pout->y = (pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1]) / norm; - pout->z = (pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2]) / norm; + CONST D3DXVECTOR3 v = *pv; + pout->x = (pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[2][0] * v.z + pm->u.m[3][0]) / norm; + pout->y = (pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[2][1] * v.z + pm->u.m[3][1]) / norm; + pout->z = (pm->u.m[0][2] * v.x + pm->u.m[1][2] * v.y + pm->u.m[2][2] * v.z + pm->u.m[3][2]) / norm; } else { @@ -1246,9 +1255,10 @@ D3DXVECTOR3* WINAPI D3DXVec3TransformCoord(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 D3DXVECTOR3* WINAPI D3DXVec3TransformNormal(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm) { - pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z; - pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z; - pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z; + CONST D3DXVECTOR3 v = *pv; + pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[2][0] * v.z; + pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[2][1] * v.z; + pout->z = pm->u.m[0][2] * v.x + pm->u.m[1][2] * v.y + pm->u.m[2][2] * v.z; return pout; } @@ -1290,10 +1300,12 @@ D3DXVECTOR4* WINAPI D3DXVec4CatmullRom(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv0 D3DXVECTOR4* WINAPI D3DXVec4Cross(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3) { - pout->x = pv1->y * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->y * pv3->w - pv3->y * pv2->w) + pv1->w * (pv2->y * pv3->z - pv2->z *pv3->y); - pout->y = -(pv1->x * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->x * pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->z - pv3->x * pv2->z)); - pout->z = pv1->x * (pv2->y * pv3->w - pv3->y * pv2->w) - pv1->y * (pv2->x *pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->y - pv3->x * pv2->y); - pout->w = -(pv1->x * (pv2->y * pv3->z - pv3->y * pv2->z) - pv1->y * (pv2->x * pv3->z - pv3->x *pv2->z) + pv1->z * (pv2->x * pv3->y - pv3->x * pv2->y)); + D3DXVECTOR4 out; + out.x = pv1->y * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->y * pv3->w - pv3->y * pv2->w) + pv1->w * (pv2->y * pv3->z - pv2->z *pv3->y); + out.y = -(pv1->x * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->x * pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->z - pv3->x * pv2->z)); + out.z = pv1->x * (pv2->y * pv3->w - pv3->y * pv2->w) - pv1->y * (pv2->x *pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->y - pv3->x * pv2->y); + out.w = -(pv1->x * (pv2->y * pv3->z - pv3->y * pv2->z) - pv1->y * (pv2->x * pv3->z - pv3->x *pv2->z) + pv1->z * (pv2->x * pv3->y - pv3->x * pv2->y)); + *pout = out; return pout; } @@ -1337,9 +1349,11 @@ D3DXVECTOR4* WINAPI D3DXVec4Normalize(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv) D3DXVECTOR4* WINAPI D3DXVec4Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv, CONST D3DXMATRIX *pm) { - pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0] * pv->w; - pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1] * pv->w; - pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2] * pv->w; - pout->w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] * pv->z + pm->u.m[3][3] * pv->w; + D3DXVECTOR4 out; + out.x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0] * pv->w; + out.y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1] * pv->w; + out.z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2] * pv->w; + out.w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] * pv->z + pm->u.m[3][3] * pv->w; + *pout = out; return pout; } diff --git a/dlls/mstask/mstask_main.c b/dlls/d3dx8/mesh.c similarity index 59% copy from dlls/mstask/mstask_main.c copy to dlls/d3dx8/mesh.c index c373d663dcd..db490d44bf5 100644 --- a/dlls/mstask/mstask_main.c +++ b/dlls/d3dx8/mesh.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Google (Roy Shea) + * Copyright 2008 David Adam * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,28 +16,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include - #include "windef.h" -#include "winbase.h" +#include "wingdi.h" +#include "d3dx8.h" + #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(mstask); +WINE_DEFAULT_DEBUG_CHANNEL(d3dx); -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection) { - TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + D3DXVECTOR3 difference; + FLOAT a, b, c; - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - case DLL_PROCESS_DETACH: - break; - } + a = D3DXVec3LengthSq(praydirection); + if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE; + b = D3DXVec3Dot(&difference, praydirection); + c = D3DXVec3LengthSq(&difference) - radius * radius; + if ( b * b - a * c <= 0.0f ) return FALSE; return TRUE; } diff --git a/dlls/d3dx8/tests/Makefile.in b/dlls/d3dx8/tests/Makefile.in index 79dce65d756..8869d711d58 100644 --- a/dlls/d3dx8/tests/Makefile.in +++ b/dlls/d3dx8/tests/Makefile.in @@ -5,7 +5,9 @@ VPATH = @srcdir@ TESTDLL = d3dx8.dll IMPORTS = d3dx8 kernel32 -CTESTS = math.c +CTESTS = \ + math.c \ + mesh.c @MAKE_TEST_RULES@ diff --git a/dlls/d3dx8/tests/mesh.c b/dlls/d3dx8/tests/mesh.c new file mode 100644 index 00000000000..8f07b079d8f --- /dev/null +++ b/dlls/d3dx8/tests/mesh.c @@ -0,0 +1,51 @@ +/* + * Copyright 2008 David Adam + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "d3dx8.h" + +#include "wine/test.h" + +static void D3DXBoundProbeTest(void) +{ +/*____________Test the Sphere case________________________*/ + + BOOL result; + D3DXVECTOR3 center, raydirection, rayposition; + FLOAT radius; + + radius = sqrt(77.0f); + center.x = 1.0f; center.y = 2.0f; center.z = 3.0f; + raydirection.x = 2.0f; raydirection.y = -4.0f; raydirection.z = 2.0f; + + rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 9.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == TRUE, "expected TRUE, received FALSE\n"); + + rayposition.x = 5.0f; rayposition.y = 7.0f; rayposition.z = 9.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == FALSE, "expected FALSE, received TRUE\n"); + + rayposition.x = 5.0f; rayposition.y = 11.0f; rayposition.z = 9.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == FALSE, "expected FALSE, received TRUE\n"); +} + +START_TEST(mesh) +{ + D3DXBoundProbeTest(); +} diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index 93ba1329961..319303387ba 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -163,7 +163,7 @@ @ stub D3DXGetShaderOutputSemantics @ stub D3DXGetShaderSamplers @ stdcall D3DXGetShaderSize(ptr) -@ stub D3DXGetShaderVersion +@ stdcall D3DXGetShaderVersion(ptr) @ stub D3DXGetVertexShaderProfile @ stdcall D3DXIntersect(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) d3dx8.D3DXIntersect @ stdcall D3DXIntersectSubset(ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr) d3dx8.D3DXIntersectSubset @@ -235,7 +235,7 @@ @ stdcall D3DXPlaneIntersectLine(ptr ptr ptr ptr) d3dx8.D3DXPlaneIntersectLine @ stdcall D3DXPlaneNormalize(ptr ptr) d3dx8.D3DXPlaneNormalize @ stdcall D3DXPlaneTransform(ptr ptr ptr) d3dx8.D3DXPlaneTransform -@ stub D3DXPlaneTransformArray +@ stdcall D3DXPlaneTransformArray(ptr long ptr long ptr long) @ stub D3DXPreprocessShader @ stub D3DXPreprocessShaderFromFileA @ stub D3DXPreprocessShaderFromFileW diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c index 3a959519568..deb52d2dd66 100644 --- a/dlls/d3dx9_36/math.c +++ b/dlls/d3dx9_36/math.c @@ -27,6 +27,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); /************************************************************************* + * D3DXPlaneTransformArray + */ +D3DXPLANE* WINAPI D3DXPlaneTransformArray( + D3DXPLANE* out, UINT outstride, CONST D3DXPLANE* in, UINT instride, + CONST D3DXMATRIX* matrix, UINT elements) +{ + UINT i; + TRACE("\n"); + for (i = 0; i < elements; ++i) { + D3DXPlaneTransform( + (D3DXPLANE*)((char*)out + outstride * i), + (CONST D3DXPLANE*)((const char*)in + instride * i), + matrix); + } + return out; +} + +/************************************************************************* * D3DXVec2TransformArray * * Transform an array of vectors by a matrix. @@ -35,7 +53,7 @@ D3DXVECTOR4* WINAPI D3DXVec2TransformArray( D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec2Transform( @@ -53,7 +71,7 @@ D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray( D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec2TransformCoord( @@ -71,7 +89,7 @@ D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray( D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2 *in, UINT instride, CONST D3DXMATRIX *matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec2TransformNormal( @@ -92,7 +110,7 @@ D3DXVECTOR3* WINAPI D3DXVec3ProjectArray( CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec3Project( @@ -110,7 +128,7 @@ D3DXVECTOR4* WINAPI D3DXVec3TransformArray( D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec3Transform( @@ -128,7 +146,7 @@ D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray( D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec3TransformCoord( @@ -146,7 +164,7 @@ D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray( D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec3TransformNormal( @@ -165,7 +183,7 @@ D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray( CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec3Unproject( @@ -183,7 +201,7 @@ D3DXVECTOR4* WINAPI D3DXVec4TransformArray( D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR4* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements) { - unsigned int i; + UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec4Transform( diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index bbda961c489..326331c4588 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -47,3 +47,10 @@ UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code) /* Return the shader size in bytes */ return (ptr - byte_code) * sizeof(*ptr); } + +DWORD WINAPI D3DXGetShaderVersion(const DWORD *byte_code) +{ + TRACE("byte_code %p\n", byte_code); + + return byte_code ? *byte_code : 0; +} diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c index 8c760edd985..511fc3bc782 100644 --- a/dlls/d3dx9_36/tests/math.c +++ b/dlls/d3dx9_36/tests/math.c @@ -34,6 +34,17 @@ exp[i].x, exp[i].y, exp[i].z, exp[i].w, \ i); \ } +#define compare_planes(exp, out) \ + for (i = 0; i < ARRAY_SIZE + 2; ++i) { \ + ok(relative_error(exp[i].a, out[i].a) < admitted_error && \ + relative_error(exp[i].b, out[i].b) < admitted_error && \ + relative_error(exp[i].c, out[i].c) < admitted_error && \ + relative_error(exp[i].d, out[i].d) < admitted_error, \ + "Got (%f, %f, %f, %f), expected (%f, %f, %f, %f) for index %d.\n", \ + out[i].a, out[i].b, out[i].c, out[i].d, \ + exp[i].a, exp[i].b, exp[i].c, exp[i].d, \ + i); \ + } /* The mathematical properties are checked in the d3dx8 testsuite. * @@ -56,6 +67,9 @@ static void test_D3DXVec_Array(void) D3DXVECTOR4 inp_vec[ARRAY_SIZE]; D3DXVECTOR4 out_vec[ARRAY_SIZE + 2]; D3DXVECTOR4 exp_vec[ARRAY_SIZE + 2]; + D3DXPLANE inp_plane[ARRAY_SIZE]; + D3DXPLANE out_plane[ARRAY_SIZE + 2]; + D3DXPLANE exp_plane[ARRAY_SIZE + 2]; viewport.Width = 800; viewport.MinZ = 0.2f; viewport.X = 10; viewport.Height = 680; viewport.MaxZ = 0.9f; viewport.Y = 5; @@ -63,11 +77,13 @@ static void test_D3DXVec_Array(void) for (i = 0; i < ARRAY_SIZE + 2; ++i) { out_vec[i].x = out_vec[i].y = out_vec[i].z = out_vec[i].w = 0.0f; exp_vec[i].x = exp_vec[i].y = exp_vec[i].z = exp_vec[i].w = 0.0f; + out_plane[i].a = out_plane[i].b = out_plane[i].c = out_plane[i].d = 0.0f; + exp_plane[i].a = exp_plane[i].b = exp_plane[i].c = exp_plane[i].d = 0.0f; } for (i = 0; i < ARRAY_SIZE; ++i) { - inp_vec[i].x = inp_vec[i].z = i; - inp_vec[i].y = inp_vec[i].w = ARRAY_SIZE - i; + inp_plane[i].a = inp_plane[i].c = inp_vec[i].x = inp_vec[i].z = i; + inp_plane[i].b = inp_plane[i].d = inp_vec[i].y = inp_vec[i].w = ARRAY_SIZE - i; } U(mat).m[0][0] = 1.0f; U(mat).m[0][1] = 2.0f; U(mat).m[0][2] = 3.0f; U(mat).m[0][3] = 4.0f; @@ -169,6 +185,15 @@ static void test_D3DXVec_Array(void) exp_vec[5].x = 58.0f; exp_vec[5].y = 68.0f; exp_vec[5].z = 78.0f; exp_vec[5].w = 88.0f; D3DXVec4TransformArray(out_vec + 1, sizeof(D3DXVECTOR4), inp_vec, sizeof(D3DXVECTOR4), &mat, ARRAY_SIZE); compare_vectors(exp_vec, out_vec); + + /* D3DXPlaneTransformArray */ + exp_plane[1].a = 90.0f; exp_plane[1].b = 100.0f; exp_plane[1].c = 110.0f; exp_plane[1].d = 120.0f; + exp_plane[2].a = 82.0f; exp_plane[2].b = 92.0f; exp_plane[2].c = 102.0f; exp_plane[2].d = 112.0f; + exp_plane[3].a = 74.0f; exp_plane[3].b = 84.0f; exp_plane[3].c = 94.0f; exp_plane[3].d = 104.0f; + exp_plane[4].a = 66.0f; exp_plane[4].b = 76.0f; exp_plane[4].c = 86.0f; exp_plane[4].d = 96.0f; + exp_plane[5].a = 58.0f; exp_plane[5].b = 68.0f; exp_plane[5].c = 78.0f; exp_plane[5].d = 88.0f; + D3DXPlaneTransformArray(out_plane + 1, sizeof(D3DXPLANE), inp_plane, sizeof(D3DXPLANE), &mat, ARRAY_SIZE); + compare_planes(exp_plane, out_plane); } START_TEST(math) diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index b08285d96fb..b13fed16c01 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -54,7 +54,24 @@ static void test_get_shader_size(void) ok(shader_size == 0, "Got shader size %u, expected 0\n", shader_size); } +static void test_get_shader_version(void) +{ + DWORD shader_version; + + shader_version = D3DXGetShaderVersion(simple_vs); + ok(shader_version == D3DVS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n", + shader_version, D3DVS_VERSION(1, 1)); + + shader_version = D3DXGetShaderVersion(simple_ps); + ok(shader_version == D3DPS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n", + shader_version, D3DPS_VERSION(1, 1)); + + shader_version = D3DXGetShaderVersion(NULL); + ok(shader_version == 0, "Got shader version 0x%08x, expected 0\n", shader_version); +} + START_TEST(shader) { test_get_shader_size(); + test_get_shader_version(); } diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 15bb6ca48c1..6a3ecfcffae 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -6244,6 +6244,39 @@ static void copy_mipmap_chain(IDirect3DDeviceImpl *device, IDirectDrawPalette *pal = NULL, *pal_src = NULL; DWORD ckeyflag; DDCOLORKEY ddckey; + BOOL palette_missing = FALSE; + + /* Copy palette, if possible. */ + IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src); + IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal); + + if (pal_src != NULL && pal != NULL) + { + PALETTEENTRY palent[256]; + + IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent); + IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent); + } + + if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | + DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal) + { + palette_missing = TRUE; + } + + if (pal) IDirectDrawPalette_Release(pal); + if (pal_src) IDirectDrawPalette_Release(pal_src); + + /* Copy colorkeys, if present. */ + for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1) + { + hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey); + + if (SUCCEEDED(hr)) + { + IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey); + } + } src_level = src; dest_level = dest; @@ -6256,10 +6289,14 @@ static void copy_mipmap_chain(IDirect3DDeviceImpl *device, if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth && src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight) { - /* Try UpdateSurface that may perform a more direct opengl loading. */ - hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface, + /* Try UpdateSurface that may perform a more direct opengl loading. But skip this is destination is paletted texture and has no palette. + * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates + * warnings in wined3d. */ + if (!palette_missing) + hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface, &point); - if (FAILED(hr)) + + if (palette_missing || FAILED(hr)) { /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */ IWineD3DSurface_BltFast(dest_level->WineD3DSurface, @@ -6295,32 +6332,6 @@ static void copy_mipmap_chain(IDirect3DDeviceImpl *device, if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7)); if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7)); - - /* Copy palette, if possible. */ - IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src); - IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal); - - if (pal_src != NULL && pal != NULL) - { - PALETTEENTRY palent[256]; - - IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent); - IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent); - } - - if (pal) IDirectDrawPalette_Release(pal); - if (pal_src) IDirectDrawPalette_Release(pal_src); - - /* Copy colorkeys, if present. */ - for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1) - { - hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey); - - if (SUCCEEDED(hr)) - { - IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey); - } - } } /***************************************************************************** diff --git a/dlls/dnsapi/record.c b/dlls/dnsapi/record.c index 958403172d8..9755a3d1a9f 100644 --- a/dlls/dnsapi/record.c +++ b/dlls/dnsapi/record.c @@ -680,7 +680,7 @@ BOOL WINAPI DnsRecordSetCompare( PDNS_RECORD set1, PDNS_RECORD set2, DNS_RRSET_ADD( rr1, u ); ret = FALSE; } - else heap_free( u ); + else DnsRecordListFree( u, DnsFreeRecordList ); } } @@ -696,7 +696,7 @@ BOOL WINAPI DnsRecordSetCompare( PDNS_RECORD set1, PDNS_RECORD set2, DNS_RRSET_ADD( rr2, u ); ret = FALSE; } - else heap_free( u ); + else DnsRecordListFree( u, DnsFreeRecordList ); } } @@ -704,7 +704,10 @@ BOOL WINAPI DnsRecordSetCompare( PDNS_RECORD set1, PDNS_RECORD set2, DNS_RRSET_TERMINATE( rr2 ); if (diff1) *diff1 = rr1.pFirstRR; + else DnsRecordListFree( rr1.pFirstRR, DnsFreeRecordList ); + if (diff2) *diff2 = rr2.pFirstRR; + else DnsRecordListFree( rr2.pFirstRR, DnsFreeRecordList ); return ret; diff --git a/dlls/dnsapi/tests/record.c b/dlls/dnsapi/tests/record.c index 5d68bd41872..8ce0f3dd179 100644 --- a/dlls/dnsapi/tests/record.c +++ b/dlls/dnsapi/tests/record.c @@ -89,9 +89,11 @@ static void test_DnsRecordSetCompare( void ) ok( DnsRecordSetCompare( rr1.pFirstRR, NULL, &diff1, &diff2 ) == FALSE, "succeeded unexpectedly\n" ); ok( diff1 != NULL && diff2 == NULL, "unexpected result: %p, %p\n", diff1, diff2 ); + DnsRecordListFree( diff1, DnsFreeRecordList ); ok( DnsRecordSetCompare( NULL, rr2.pFirstRR, &diff1, &diff2 ) == FALSE, "succeeded unexpectedly\n" ); ok( diff1 == NULL && diff2 != NULL, "unexpected result: %p, %p\n", diff1, diff2 ); + DnsRecordListFree( diff2, DnsFreeRecordList ); ok( DnsRecordSetCompare( rr1.pFirstRR, rr2.pFirstRR, NULL, &diff2 ) == TRUE, "failed unexpectedly\n" ); ok( diff2 == NULL, "unexpected result: %p\n", diff2 ); @@ -105,8 +107,14 @@ static void test_DnsRecordSetCompare( void ) r2.Data.A.IpAddress = 0; ok( DnsRecordSetCompare( rr1.pFirstRR, rr2.pFirstRR, NULL, &diff2 ) == FALSE, "succeeded unexpectedly\n" ); + DnsRecordListFree( diff2, DnsFreeRecordList ); + ok( DnsRecordSetCompare( rr1.pFirstRR, rr2.pFirstRR, &diff1, NULL ) == FALSE, "succeeded unexpectedly\n" ); + DnsRecordListFree( diff1, DnsFreeRecordList ); + ok( DnsRecordSetCompare( rr1.pFirstRR, rr2.pFirstRR, &diff1, &diff2 ) == FALSE, "succeeded unexpectedly\n" ); + DnsRecordListFree( diff1, DnsFreeRecordList ); + DnsRecordListFree( diff2, DnsFreeRecordList ); } static void test_DnsRecordSetDetach( void ) diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 362345380ae..829a21c3ffa 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -38,7 +38,7 @@ #include "dplayx_global.h" #include "name_server.h" #include "dplayx_queue.h" -#include "dplaysp.h" +#include "wine/dplaysp.h" #include "dplay_global.h" WINE_DEFAULT_DEBUG_CHANNEL(dplay); diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index 095374d28bb..3537c757052 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -23,7 +23,7 @@ #include "windef.h" #include "winbase.h" -#include "dplaysp.h" +#include "wine/dplaysp.h" #include "lobbysp.h" #include "dplayx_queue.h" diff --git a/dlls/dplayx/dplaysp.c b/dlls/dplayx/dplaysp.c index 33cfedd3a9b..5d2ba9f452f 100644 --- a/dlls/dplayx/dplaysp.c +++ b/dlls/dplayx/dplaysp.c @@ -23,7 +23,7 @@ #include "wine/debug.h" #include "dpinit.h" -#include "dplaysp.h" +#include "wine/dplaysp.h" #include "dplay_global.h" #include "name_server.h" #include "dplayx_messages.h" diff --git a/dlls/dplayx/name_server.c b/dlls/dplayx/name_server.c index ca73bd0f316..3527877ed21 100644 --- a/dlls/dplayx/name_server.c +++ b/dlls/dplayx/name_server.c @@ -33,7 +33,7 @@ #include "dplayx_global.h" #include "name_server.h" -#include "dplaysp.h" +#include "wine/dplaysp.h" #include "dplayx_messages.h" #include "dplayx_queue.h" diff --git a/dlls/dplayx/name_server.h b/dlls/dplayx/name_server.h index 2df4a3bf7ea..a1d3dd7311e 100644 --- a/dlls/dplayx/name_server.h +++ b/dlls/dplayx/name_server.h @@ -24,7 +24,7 @@ #include "windef.h" #include "winbase.h" #include "dplay.h" -#include "dplaysp.h" +#include "wine/dplaysp.h" #include "dplayx_messages.h" #include "dplay_global.h" diff --git a/dlls/dpnet/regsvr.c b/dlls/dpnet/regsvr.c index 12b52f82e68..578d1ea0371 100644 --- a/dlls/dpnet/regsvr.c +++ b/dlls/dpnet/regsvr.c @@ -491,6 +491,16 @@ static struct regsvr_coclass const coclass_list[] = { "DirectPlay8.LobbiedApplication", NULL }, + { + &CLSID_DirectPlay8ThreadPool, + "DirectPlay8 Thread Pool Object", + NULL, + "dpnet.dll", + "Both", + "DirectPlay8.ThreadPool.1", + "DirectPlay8.ThreadPool", + NULL + }, { NULL } /* list terminator */ }; diff --git a/dlls/mstask/Makefile.in b/dlls/dpwsockx/Makefile.in similarity index 83% copy from dlls/mstask/Makefile.in copy to dlls/dpwsockx/Makefile.in index 2fd0a66e8e6..cebac287a2b 100644 --- a/dlls/mstask/Makefile.in +++ b/dlls/dpwsockx/Makefile.in @@ -2,11 +2,11 @@ TOPSRCDIR = @top_srcdir@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ -MODULE = mstask.dll +MODULE = dpwsockx.dll IMPORTS = kernel32 C_SRCS = \ - mstask_main.c + dpwsockx_main.c @MAKE_DLL_RULES@ diff --git a/dlls/dpwsockx/dpwsockx.spec b/dlls/dpwsockx/dpwsockx.spec new file mode 100644 index 00000000000..5f84adcc8da --- /dev/null +++ b/dlls/dpwsockx/dpwsockx.spec @@ -0,0 +1,3 @@ +1 stdcall SPInit(ptr) +3 stub DPWS_GetEnumPort +4 stub DPWS_BuildIPMessageHeader diff --git a/include/d3dx9shader.h b/dlls/dpwsockx/dpwsockx_dll.h similarity index 74% copy from include/d3dx9shader.h copy to dlls/dpwsockx/dpwsockx_dll.h index 5eb4fe67587..08ae11c1960 100644 --- a/include/d3dx9shader.h +++ b/dlls/dpwsockx/dpwsockx_dll.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Luis Busquets + * Copyright 2008 Ismael Barros Barros * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,19 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __D3DX9SHADER_H__ -#define __D3DX9SHADER_H__ +#ifndef __WINE_DPWSOCKX_DLL_H +#define __WINE_DPWSOCKX_DLL_H -#include "d3dx9.h" +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "wine/dplaysp.h" -#ifdef __cplusplus -extern "C" { -#endif -UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code); +HRESULT WINAPI SPInit( LPSPINITDATA ); -#ifdef __cplusplus -} -#endif - -#endif /* __D3DX9SHADER_H__ */ +#endif /* __WINE_DPWSOCKX_DLL_H */ diff --git a/dlls/mstask/mstask_main.c b/dlls/dpwsockx/dpwsockx_main.c similarity index 54% copy from dlls/mstask/mstask_main.c copy to dlls/dpwsockx/dpwsockx_main.c index c373d663dcd..271915a5a56 100644 --- a/dlls/mstask/mstask_main.c +++ b/dlls/dpwsockx/dpwsockx_main.c @@ -1,5 +1,6 @@ -/* - * Copyright (C) 2008 Google (Roy Shea) +/* Internet TCP/IP and IPX Connection For DirectPlay + * + * Copyright 2008 Ismael Barros Barros * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,28 +17,47 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + #include #include "windef.h" #include "winbase.h" +#include "dpwsockx_dll.h" #include "wine/debug.h" +#include "dplay.h" +#include "wine/dplaysp.h" -WINE_DEFAULT_DEBUG_CHANNEL(mstask); + +WINE_DEFAULT_DEBUG_CHANNEL(dplay); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); switch (fdwReason) { - case DLL_WINE_PREATTACH: - return FALSE; - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - case DLL_PROCESS_DETACH: - break; + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + /* TODO: Initialization */ + DisableThreadLibraryCalls(hinstDLL); + break; + case DLL_PROCESS_DETACH: + break; + default: + break; } return TRUE; } + + +/****************************************************************** + * SPInit (DPWSOCKX.1) + */ +HRESULT WINAPI SPInit( LPSPINITDATA lpspData ) +{ + /* TODO: Initialize callbacks and needed fields in lpspData */ + return DPERR_UNSUPPORTED; +} diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 7ac6e6705fd..7fe94239f12 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -240,6 +240,8 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len i, offset, event->hEventNotify); /* DSBPN_OFFSETSTOP has to be the last element. So this is */ /* OK. [Inside DirectX, p274] */ + /* Windows does not seem to enforce this, and some apps rely */ + /* on that, so we can't stop there. */ /* */ /* This also means we can't sort the entries by offset, */ /* because DSBPN_OFFSETSTOP == -1 */ @@ -247,9 +249,8 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len if (dsb->state == STATE_STOPPED) { SetEvent(event->hEventNotify); TRACE("signalled event %p (%d)\n", event->hEventNotify, i); - return; - } else - return; + } + continue; } if ((playpos + len) >= dsb->buflen) { if ((offset < ((playpos + len) % dsb->buflen)) || diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 801a3fdc081..8e4601ddf7f 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -315,9 +315,8 @@ void DC_UpdateXforms( DC *dc ) /* Reselect the font and pen back into the dc so that the size gets updated. */ - if ((oldworld2vport.eM11 != dc->xformWorld2Vport.eM11 || - oldworld2vport.eM22 != dc->xformWorld2Vport.eM22) && - !GdiIsMetaFileDC(dc->hSelf)) + if (memcmp(&oldworld2vport, &dc->xformWorld2Vport, sizeof(oldworld2vport)) && + !GdiIsMetaFileDC(dc->hSelf)) { SelectObject(dc->hSelf, GetCurrentObject(dc->hSelf, OBJ_FONT)); SelectObject(dc->hSelf, GetCurrentObject(dc->hSelf, OBJ_PEN)); diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 677cda5eb2c..440857dc243 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -1118,7 +1118,14 @@ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header, if (handle) { - if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse ); + if (init == CBM_INIT) + { + if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0) + { + DeleteObject( handle ); + handle = 0; + } + } else if (hdc && ((dc = get_dc_ptr( hdc )) != NULL) ) { diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 62db9fee1bb..a2110ab9700 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -4300,6 +4300,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; double widthRatio = 1.0; FT_Matrix transMat = identityMat; + FT_Matrix transMatUnrotated; BOOL needsTransform = FALSE; BOOL tategaki = (font->GSUB_Table != NULL); UINT original_index; @@ -4404,6 +4405,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, } /* Rotation transform */ + transMatUnrotated = transMat; if(font->orientation && !tategaki) { FT_Matrix rotationMat; FT_Vector vecAngle; @@ -4427,6 +4429,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, worldMat.yx = FT_FixedFromFloat(font->font_desc.matrix.eM12); worldMat.yy = FT_FixedFromFloat(font->font_desc.matrix.eM22); pFT_Matrix_Multiply(&worldMat, &transMat); + pFT_Matrix_Multiply(&worldMat, &transMatUnrotated); needsTransform = TRUE; } @@ -4439,6 +4442,7 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, extraMat.yx = FT_FixedFromFIXED(lpmat->eM12); extraMat.yy = FT_FixedFromFIXED(lpmat->eM22); pFT_Matrix_Multiply(&extraMat, &transMat); + pFT_Matrix_Multiply(&extraMat, &transMatUnrotated); needsTransform = TRUE; } @@ -4479,8 +4483,13 @@ DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format, vec.x = ft_face->glyph->metrics.horiAdvance; vec.y = 0; pFT_Vector_Transform(&vec, &transMat); - adv = lpgm->gmCellIncX = (vec.x+63) >> 6; + lpgm->gmCellIncX = (vec.x+63) >> 6; lpgm->gmCellIncY = -((vec.y+63) >> 6); + + vec.x = ft_face->glyph->metrics.horiAdvance; + vec.y = 0; + pFT_Vector_Transform(&vec, &transMatUnrotated); + adv = (vec.x+63) >> 6; } lpgm->gmBlackBoxX = (right - left) >> 6; lpgm->gmBlackBoxY = (top - bottom) >> 6; diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index d1439495087..9e8f408764f 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -514,7 +514,7 @@ static void test_outline_font(void) pt.x = width_orig; pt.y = 0; LPtoDP(hdc, &pt, 1); ok(gm.gmCellIncX == pt.x/2, "incX %d != %d\n", gm.gmCellIncX, pt.x/2); - ok(gm.gmCellIncX == 10 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig); + ok(near_match(gm.gmCellIncX, 10 * width_orig), "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig); ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY); SelectObject(hdc, old_hfont); @@ -2395,6 +2395,35 @@ static void test_GetTextFace(void) ReleaseDC(NULL, dc); } +static void test_orientation(void) +{ + static const char test_str[11] = "Test String"; + HDC hdc; + LOGFONTA lf; + HFONT hfont, old_hfont; + SIZE size; + + if (!is_truetype_font_installed("Arial")) + { + skip("Arial is not installed\n"); + return; + } + + hdc = CreateCompatibleDC(0); + memset(&lf, 0, sizeof(lf)); + lstrcpyA(lf.lfFaceName, "Arial"); + lf.lfHeight = 72; + lf.lfOrientation = lf.lfEscapement = 900; + hfont = create_font("orientation", &lf); + old_hfont = SelectObject(hdc, hfont); + ok(GetTextExtentExPointA(hdc, test_str, sizeof(test_str), 32767, NULL, NULL, &size), "GetTextExtentExPointA failed\n"); + ok(near_match(311, size.cx), "cx should be about 311, got %d\n", size.cx); + ok(near_match(75, size.cy), "cy should be about 75, got %d\n", size.cy); + SelectObject(hdc, old_hfont); + DeleteObject(hfont); + DeleteDC(hdc); +} + START_TEST(font) { init(); @@ -2413,6 +2442,7 @@ START_TEST(font) test_font_charset(); test_GetFontUnicodeRanges(); test_nonexistent_font(); + test_orientation(); /* On Windows Arial has a lot of default charset aliases such as Arial Cyr, * I'd like to avoid them in this test. diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index ba7663e3b8e..13cd3abdf05 100644 --- a/dlls/gdiplus/brush.c +++ b/dlls/gdiplus/brush.c @@ -75,6 +75,24 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) memcpy(dest->pathdata.Points, src->pathdata.Points, count * sizeof(PointF)); memcpy(dest->pathdata.Types, src->pathdata.Types, count); + /* blending */ + count = src->blendcount; + dest->blendcount = count; + dest->blendfac = GdipAlloc(count * sizeof(REAL)); + dest->blendpos = GdipAlloc(count * sizeof(REAL)); + + if(!dest->blendfac || !dest->blendpos){ + GdipFree(dest->pathdata.Points); + GdipFree(dest->pathdata.Types); + GdipFree(dest->blendfac); + GdipFree(dest->blendpos); + GdipFree(dest); + return OutOfMemory; + } + + memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); + memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); + break; } case BrushTypeLinearGradient: @@ -213,6 +231,15 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points, *grad = GdipAlloc(sizeof(GpPathGradient)); if (!*grad) return OutOfMemory; + (*grad)->blendfac = GdipAlloc(sizeof(REAL)); + if(!(*grad)->blendfac){ + GdipFree(*grad); + return OutOfMemory; + } + (*grad)->blendfac[0] = 1.0; + (*grad)->blendpos = NULL; + (*grad)->blendcount = 1; + (*grad)->pathdata.Count = count; (*grad)->pathdata.Points = GdipAlloc(count * sizeof(PointF)); (*grad)->pathdata.Types = GdipAlloc(count); @@ -284,6 +311,15 @@ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path, *grad = GdipAlloc(sizeof(GpPathGradient)); if (!*grad) return OutOfMemory; + (*grad)->blendfac = GdipAlloc(sizeof(REAL)); + if(!(*grad)->blendfac){ + GdipFree(*grad); + return OutOfMemory; + } + (*grad)->blendfac[0] = 1.0; + (*grad)->blendpos = NULL; + (*grad)->blendcount = 1; + (*grad)->pathdata.Count = path->pathdata.Count; (*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF)); (*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count); @@ -476,6 +512,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) case BrushTypePathGradient: GdipFree(((GpPathGradient*) brush)->pathdata.Points); GdipFree(((GpPathGradient*) brush)->pathdata.Types); + GdipFree(((GpPathGradient*) brush)->blendfac); + GdipFree(((GpPathGradient*) brush)->blendpos); break; case BrushTypeSolidColor: case BrushTypeLinearGradient: @@ -511,6 +549,33 @@ GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapm return Ok; } +GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend, + REAL *positions, INT count) +{ + if(!brush || !blend || !positions || count <= 0) + return InvalidParameter; + + if(count < brush->blendcount) + return InsufficientBuffer; + + memcpy(blend, brush->blendfac, count*sizeof(REAL)); + if(brush->blendcount > 1){ + memcpy(positions, brush->blendpos, count*sizeof(REAL)); + } + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count) +{ + if(!brush || !count) + return InvalidParameter; + + *count = brush->blendcount; + + return Ok; +} + GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad, GpPointF *point) { @@ -576,6 +641,51 @@ GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad, return Ok; } +GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect) +{ + GpRectF r; + GpPath* path; + GpStatus stat; + + if(!brush || !rect) + return InvalidParameter; + + stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types, + brush->pathdata.Count, FillModeAlternate, &path); + if(stat != Ok) return stat; + + stat = GdipGetPathWorldBounds(path, &r, NULL, NULL); + if(stat != Ok){ + GdipDeletePath(path); + return stat; + } + + memcpy(rect, &r, sizeof(GpRectF)); + + GdipDeletePath(path); + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect) +{ + GpRectF rectf; + GpStatus stat; + + if(!brush || !rect) + return InvalidParameter; + + stat = GdipGetPathGradientRect(brush, &rectf); + if(stat != Ok) return stat; + + rect->X = roundr(rectf.X); + rect->Y = roundr(rectf.Y); + rect->Width = roundr(rectf.Width); + rect->Height = roundr(rectf.Height); + + return Ok; +} + GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient *grad, ARGB *argb, INT *count) { diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index 3526b2e62b5..4e756e5313e 100644 --- a/dlls/gdiplus/font.c +++ b/dlls/gdiplus/font.c @@ -569,6 +569,17 @@ GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family, return NotImplemented; } +GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily* family, + INT style, BOOL* IsStyleAvailable) +{ + FIXME("%p %d %p stub!\n", family, style, IsStyleAvailable); + + if (!(family && IsStyleAvailable)) + return InvalidParameter; + + return NotImplemented; +} + /***************************************************************************** * GdipGetGenericFontFamilyMonospace [GDIPLUS.@] * @@ -633,3 +644,58 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamil return GdipCreateFontFamilyFromName(MSSansSerif, NULL, nativeFamily); } + +GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection** fontCollection) +{ + FIXME("stub %p\n", fontCollection); + + if (!fontCollection) + return InvalidParameter; + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection **fontCollection) +{ + FIXME("stub %p\n", fontCollection); + + if (!fontCollection) + return InvalidParameter; + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection* fontCollection, + GDIPCONST WCHAR* filename) +{ + FIXME("stub: %p, %s\n", fontCollection, debugstr_w(filename)); + + if (!(fontCollection && filename)) + return InvalidParameter; + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipGetFontCollectionFamilyCount( + GpFontCollection* fontCollection, INT* numFound) +{ + FIXME("stub: %p, %p\n", fontCollection, numFound); + + if (!(fontCollection && numFound)) + return InvalidParameter; + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList( + GpFontCollection* fontCollection, INT numSought, + GpFontFamily* gpfamilies[], INT* numFound) +{ + FIXME("stub: %p, %d, %p, %p\n", fontCollection, numSought, gpfamilies, + numFound); + + if (!(fontCollection && gpfamilies && numFound)) + return InvalidParameter; + + return NotImplemented; +} diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 07bd6edd07c..b55b4b1dc69 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -147,7 +147,7 @@ @ stdcall GdipDeletePath(ptr) @ stdcall GdipDeletePathIter(ptr) @ stdcall GdipDeletePen(ptr) -@ stub GdipDeletePrivateFontCollection +@ stdcall GdipDeletePrivateFontCollection(ptr) @ stdcall GdipDeleteRegion(ptr) @ stdcall GdipDeleteStringFormat(ptr) @ stdcall GdipDisposeImage(ptr) @@ -265,8 +265,8 @@ @ stub GdipGetEncoderParameterListSize @ stub GdipGetFamily @ stdcall GdipGetFamilyName(ptr ptr long) -@ stub GdipGetFontCollectionFamilyCount -@ stub GdipGetFontCollectionFamilyList +@ stdcall GdipGetFontCollectionFamilyCount(ptr ptr) +@ stdcall GdipGetFontCollectionFamilyList(ptr long ptr ptr) @ stub GdipGetFontHeight @ stdcall GdipGetFontHeightGivenDPI(ptr long ptr) @ stdcall GdipGetFontSize(ptr ptr) @@ -325,8 +325,8 @@ @ stdcall GdipGetPageUnit(ptr ptr) @ stdcall GdipGetPathData(ptr ptr) @ stdcall GdipGetPathFillMode(ptr ptr) -@ stub GdipGetPathGradientBlend -@ stub GdipGetPathGradientBlendCount +@ stdcall GdipGetPathGradientBlend(ptr ptr ptr long) +@ stdcall GdipGetPathGradientBlendCount(ptr ptr) @ stub GdipGetPathGradientCenterColor @ stdcall GdipGetPathGradientCenterPoint(ptr ptr) @ stdcall GdipGetPathGradientCenterPointI(ptr ptr) @@ -336,8 +336,8 @@ @ stdcall GdipGetPathGradientPointCount(ptr ptr) @ stub GdipGetPathGradientPresetBlend @ stub GdipGetPathGradientPresetBlendCount -@ stub GdipGetPathGradientRect -@ stub GdipGetPathGradientRectI +@ stdcall GdipGetPathGradientRect(ptr ptr) +@ stdcall GdipGetPathGradientRectI(ptr ptr) @ stub GdipGetPathGradientSurroundColorCount @ stdcall GdipGetPathGradientSurroundColorsWithCount(ptr ptr ptr) @ stub GdipGetPathGradientTransform @@ -423,7 +423,7 @@ @ stdcall GdipIsMatrixInvertible(ptr ptr) @ stdcall GdipIsOutlineVisiblePathPoint(ptr long long ptr ptr ptr) @ stdcall GdipIsOutlineVisiblePathPointI(ptr long long ptr ptr ptr) -@ stub GdipIsStyleAvailable +@ stdcall GdipIsStyleAvailable(ptr long ptr) @ stub GdipIsVisibleClipEmpty @ stdcall GdipIsVisiblePathPoint(ptr long long ptr ptr) @ stdcall GdipIsVisiblePathPointI(ptr long long ptr ptr) @@ -449,7 +449,7 @@ @ stub GdipMultiplyTextureTransform @ stdcall GdipMultiplyWorldTransform(ptr ptr long) @ stub GdipNewInstalledFontCollection -@ stub GdipNewPrivateFontCollection +@ stdcall GdipNewPrivateFontCollection(ptr) @ stdcall GdipPathIterCopyData(ptr ptr ptr ptr long long) @ stdcall GdipPathIterEnumerate(ptr ptr ptr ptr long) @ stdcall GdipPathIterGetCount(ptr ptr) @@ -464,7 +464,7 @@ @ stdcall GdipPathIterRewind(ptr) @ stub GdipPlayMetafileRecord @ stub GdipPlayTSClientRecord -@ stub GdipPrivateAddFontFile +@ stdcall GdipPrivateAddFontFile(ptr wstr) @ stub GdipPrivateAddMemoryFont @ stub GdipRecordMetafile @ stub GdipRecordMetafileFileName diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index e7ca8742174..620f82269bc 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -37,6 +37,8 @@ #define MAX_DASHLEN (16) /* this is a limitation of gdi */ #define INCH_HIMETRIC (2540) +#define VERSION_MAGIC 0xdbc01001 + COLORREF ARGB2COLORREF(ARGB color); extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle); @@ -105,6 +107,9 @@ struct GpPathGradient{ BOOL gamma; GpPointF center; GpPointF focus; + REAL* blendfac; /* blend factors */ + REAL* blendpos; /* blend positions */ + INT blendcount; }; struct GpLineGradient{ @@ -196,4 +201,40 @@ struct GpFontFamily{ WCHAR FamilyName[LF_FACESIZE]; }; +typedef struct region_element +{ + DWORD type; /* Rectangle, Path, SpecialRectangle, or CombineMode */ + union + { + GpRectF rect; + struct + { + GpPath* path; + struct + { + DWORD size; + DWORD magic; + DWORD count; + DWORD flags; + } pathheader; + } pathdata; + struct + { + struct region_element *left; /* the original region */ + struct region_element *right; /* what *left was combined with */ + } combine; + } elementdata; +} region_element; + +struct GpRegion{ + struct + { + DWORD size; + DWORD checksum; + DWORD magic; + DWORD num_children; + } header; + region_element node; +}; + #endif diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index fc53c86b212..6c52623f771 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -73,6 +73,75 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); * */ +typedef enum RegionType +{ + RegionDataRect = 0x10000000, + RegionDataPath = 0x10000001, + RegionDataEmptyRect = 0x10000002, + RegionDataInfiniteRect = 0x10000003, +} RegionType; + +/* Header size as far as header->size is concerned. This doesn't include + * header->size or header->checksum + */ +static const INT sizeheader_size = sizeof(DWORD) * 2; + +static inline INT get_element_size(const region_element* element) +{ + INT needed = sizeof(DWORD); /* DWORD for the type */ + switch(element->type) + { + case RegionDataRect: + return needed + sizeof(GpRect); + case RegionDataPath: + needed += element->elementdata.pathdata.pathheader.size; + needed += sizeof(DWORD); /* Extra DWORD for pathheader.size */ + return needed; + case RegionDataEmptyRect: + case RegionDataInfiniteRect: + return needed; + default: + needed += get_element_size(element->elementdata.combine.left); + needed += get_element_size(element->elementdata.combine.right); + return needed; + } + + return 0; +} + +/* Does not check parameters, caller must do that */ +static inline GpStatus init_region(GpRegion* region, const RegionType type) +{ + region->node.type = type; + region->header.checksum = 0xdeadbeef; + region->header.magic = VERSION_MAGIC; + region->header.num_children = 0; + region->header.size = sizeheader_size + get_element_size(®ion->node); + + return Ok; +} + +static inline void delete_element(region_element* element) +{ + switch(element->type) + { + case RegionDataRect: + break; + case RegionDataPath: + GdipDeletePath(element->elementdata.pathdata.path); + break; + case RegionDataEmptyRect: + case RegionDataInfiniteRect: + break; + default: + delete_element(element->elementdata.combine.left); + delete_element(element->elementdata.combine.right); + GdipFree(element->elementdata.combine.left); + GdipFree(element->elementdata.combine.right); + break; + } +} + GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone) { FIXME("(%p %p): stub\n", region, clone); @@ -110,10 +179,16 @@ GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2 GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region) { - FIXME("(%p): stub\n", region); + if(!region) + return InvalidParameter; - *region = NULL; - return NotImplemented; + TRACE("%p\n", region); + + *region = GdipAlloc(sizeof(GpRegion)); + if(!*region) + return OutOfMemory; + + return init_region(*region, RegionDataInfiniteRect); } GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region) @@ -158,8 +233,15 @@ GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region) GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region) { - FIXME("(%p): stub\n", region); - return NotImplemented; + TRACE("%p\n", region); + + if (!region) + return InvalidParameter; + + delete_element(®ion->node); + GdipFree(region); + + return Ok; } GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect) @@ -185,9 +267,15 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size, GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed) { - FIXME("(%p, %p): stub\n", region, needed); + if (!(region && needed)) + return InvalidParameter; - return NotImplemented; + TRACE("%p, %p\n", region, needed); + + /* header.size doesn't count header.size and header.checksum */ + *needed = region->header.size + sizeof(DWORD) * 2; + + return Ok; } GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn) @@ -222,22 +310,32 @@ GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics, GpStatus WINGDIPAPI GdipSetEmpty(GpRegion *region) { - static int calls; + GpStatus stat; - if(!(calls++)) - FIXME("not implemented\n"); + TRACE("%p\n", region); - return NotImplemented; + if (!region) + return InvalidParameter; + + delete_element(®ion->node); + stat = init_region(region, RegionDataEmptyRect); + + return stat; } GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *region) { - static int calls; + GpStatus stat; - if(!(calls++)) - FIXME("not implemented\n"); + if (!region) + return InvalidParameter; - return NotImplemented; + TRACE("%p", region); + + delete_element(®ion->node); + stat = init_region(region, RegionDataInfiniteRect); + + return stat; } GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix) diff --git a/dlls/gdiplus/tests/brush.c b/dlls/gdiplus/tests/brush.c index 70eac03ef8d..6711fe48c47 100644 --- a/dlls/gdiplus/tests/brush.c +++ b/dlls/gdiplus/tests/brush.c @@ -21,8 +21,10 @@ #include "windows.h" #include "gdiplus.h" #include "wine/test.h" +#include #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) +#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got) static void test_constructor_destructor(void) { @@ -49,8 +51,96 @@ static void test_type(void) GdipCreateSolidFill((ARGB)0xdeadbeef, &brush); status = GdipGetBrushType((GpBrush*)brush, &bt); - expect(status, Ok); - expect(bt, BrushTypeSolidColor); + expect(Ok, status); + expect(BrushTypeSolidColor, bt); + + GdipDeleteBrush((GpBrush*) brush); +} +static GpPointF blendcount_ptf[] = {{0.0, 0.0}, + {50.0, 50.0}}; +static void test_gradientblendcount(void) +{ + GpStatus status; + GpPathGradient *brush; + INT count; + + status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &brush); + expect(Ok, status); + + status = GdipGetPathGradientBlendCount(NULL, NULL); + expect(InvalidParameter, status); + status = GdipGetPathGradientBlendCount(NULL, &count); + expect(InvalidParameter, status); + status = GdipGetPathGradientBlendCount(brush, NULL); + expect(InvalidParameter, status); + + status = GdipGetPathGradientBlendCount(brush, &count); + expect(Ok, status); + expect(1, count); + + GdipDeleteBrush((GpBrush*) brush); +} + +static GpPointF getblend_ptf[] = {{0.0, 0.0}, + {50.0, 50.0}}; +static void test_getblend(void) +{ + GpStatus status; + GpPathGradient *brush; + REAL blends[4]; + REAL pos[4]; + + status = GdipCreatePathGradient(getblend_ptf, 2, WrapModeClamp, &brush); + expect(Ok, status); + + /* check some invalid parameters combinations */ + status = GdipGetPathGradientBlend(NULL, NULL, NULL, -1); + expect(InvalidParameter, status); + status = GdipGetPathGradientBlend(brush,NULL, NULL, -1); + expect(InvalidParameter, status); + status = GdipGetPathGradientBlend(NULL, blends,NULL, -1); + expect(InvalidParameter, status); + status = GdipGetPathGradientBlend(NULL, NULL, pos, -1); + expect(InvalidParameter, status); + status = GdipGetPathGradientBlend(NULL, NULL, NULL, 1); + expect(InvalidParameter, status); + + blends[0] = (REAL)0xdeadbeef; + pos[0] = (REAL)0xdeadbeef; + status = GdipGetPathGradientBlend(brush, blends, pos, 1); + expect(Ok, status); + expectf(1.0, blends[0]); + expectf((REAL)0xdeadbeef, pos[0]); + + GdipDeleteBrush((GpBrush*) brush); +} + +static GpPointF getbounds_ptf[] = {{0.0, 20.0}, + {50.0, 50.0}, + {21.0, 25.0}, + {25.0, 46.0}}; +static void test_getbounds(void) +{ + GpStatus status; + GpPathGradient *brush; + GpRectF bounds; + + status = GdipCreatePathGradient(getbounds_ptf, 4, WrapModeClamp, &brush); + expect(Ok, status); + + status = GdipGetPathGradientRect(NULL, NULL); + expect(InvalidParameter, status); + status = GdipGetPathGradientRect(brush, NULL); + expect(InvalidParameter, status); + status = GdipGetPathGradientRect(NULL, &bounds); + expect(InvalidParameter, status); + + status = GdipGetPathGradientRect(brush, &bounds); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(20.0, bounds.Y); + expectf(50.0, bounds.Width); + expectf(30.0, bounds.Height); GdipDeleteBrush((GpBrush*) brush); } @@ -69,6 +159,9 @@ START_TEST(brush) test_constructor_destructor(); test_type(); + test_gradientblendcount(); + test_getblend(); + test_getbounds(); GdiplusShutdown(gdiplusToken); } diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c index 5f6494bd4ed..ab0f814fa62 100644 --- a/dlls/gdiplus/tests/font.c +++ b/dlls/gdiplus/tests/font.c @@ -168,8 +168,6 @@ static void test_fontfamily (void) */ stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family); expect (FontFamilyNotFound, stat); - ok ((lstrcmpiW(itsName, nonexistent) != 0), - "Expected a non-zero value for nonexistent font!\n"); /* Bitmap fonts are not found */ todo_wine diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 38a58b9c689..49d1e5eec79 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -73,6 +73,20 @@ static void test_Scan0(void) stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm); expect(InvalidParameter, stat); expect(0xdeadbeef, bm); + + bm = NULL; + stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm); + todo_wine{ + expect(Ok, stat); + ok(NULL != bm, "Expected bitmap to be initialized\n"); + } + if (stat == Ok) + GdipDisposeImage((GpImage*)bm); + + bm = (GpBitmap*)0xdeadbeef; + stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm); + expect(InvalidParameter, stat); + expect(NULL, bm); } static void test_GetImageDimension(void) diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c index 6b1c5f04ee2..8c3badac93a 100644 --- a/dlls/gdiplus/tests/region.c +++ b/dlls/gdiplus/tests/region.c @@ -62,18 +62,22 @@ static void test_getregiondata(void) GpRect rect; GpPath *path; + memset(buf, 0xee, sizeof(buf)); + status = GdipCreateRegion(®ion); -todo_wine ok(status == Ok, "status %08x\n", status); - if(status != Ok) return; - status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); +todo_wine +{ status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); +} + expect(20, needed); +todo_wine +{ expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -81,32 +85,44 @@ todo_wine expect_dword(buf + 4, RGNDATA_INFINITE_RECT); status = GdipSetEmpty(region); +} ok(status == Ok, "status %08x\n", status); +todo_wine +{ status = GdipGetRegionDataSize(region, &needed); +} ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); +todo_wine ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); +todo_wine +{ expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); expect_dword(buf + 3, 0); expect_dword(buf + 4, RGNDATA_EMPTY_RECT); +} status = GdipSetInfinite(region); ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); +todo_wine ok(status == Ok, "status %08x\n", status); - ok(needed == 20, "got %d\n", needed); + expect(20, needed); +todo_wine +{ expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); expect_dword(buf + 3, 0); expect_dword(buf + 4, RGNDATA_INFINITE_RECT); +} status = GdipDeleteRegion(region); ok(status == Ok, "status %08x\n", status); @@ -115,14 +131,16 @@ todo_wine rect.Y = 20; rect.Width = 100; rect.Height = 200; +todo_wine +{ status = GdipCreateRegionRectI(&rect, ®ion); ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); expect_dword(buf, 28); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -171,10 +189,10 @@ todo_wine status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 156, "got %d\n", needed); + expect(156, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 156, "got %d\n", needed); + expect(156, needed); expect_dword(buf, 148); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -215,26 +233,28 @@ todo_wine expect_float(buf + 37, 22.0); expect_float(buf + 38, 55.0); - status = GdipDeleteRegion(region2); ok(status == Ok, "status %08x\n", status); status = GdipDeleteRegion(region); ok(status == Ok, "status %08x\n", status); +} /* Try some paths */ status = GdipCreatePath(FillModeAlternate, &path); ok(status == Ok, "status %08x\n", status); +todo_wine +{ GdipAddPathRectangle(path, 12.5, 13.0, 14.0, 15.0); status = GdipCreateRegionPath(path, ®ion); ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 72, "got %d\n", needed); + expect(72, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 72, "got %d\n", needed); + expect(72, needed); expect_dword(buf, 64); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -263,10 +283,10 @@ todo_wine ok(status == Ok, "status %08x\n", status); status = GdipGetRegionDataSize(region, &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 96, "got %d\n", needed); + expect(96, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); ok(status == Ok, "status %08x\n", status); - ok(needed == 96, "got %d\n", needed); + expect(96, needed); expect_dword(buf, 88); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -294,20 +314,23 @@ todo_wine status = GdipDeleteRegion(region); ok(status == Ok, "status %08x\n", status); +} status = GdipDeletePath(path); ok(status == Ok, "status %08x\n", status); /* Test an empty path */ status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); +todo_wine +{ status = GdipCreateRegionPath(path, ®ion); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); - ok(needed == 36, "got %d\n", needed); + expect(36, needed); expect_dword(buf, 28); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -322,23 +345,25 @@ todo_wine status = GdipDeleteRegion(region); expect(Ok, status); +} /* Test a simple triangle of INTs */ status = GdipAddPathLine(path, 5, 6, 7, 8); expect(Ok, status); - status = GdipAddPathLine(path, 7, 8, 8, 1); - expect(Ok, status); status = GdipAddPathLine(path, 8, 1, 5, 6); expect(Ok, status); status = GdipClosePathFigure(path); expect(Ok, status); +todo_wine +{ status = GdipCreateRegionPath(path, ®ion); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); - ok(needed == 56, "Expected 56, got %d\n", needed); + expect(56, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); + expect(56, needed); expect_dword(buf, 48); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -360,9 +385,11 @@ todo_wine expect(5, point[3].X); /* buf + 12 */ expect(6, point[3].Y); expect_dword(buf + 13, 0x81010100); /* 0x01010100 if we don't close the path */ +} status = GdipDeletePath(path); expect(Ok, status); status = GdipDeleteRegion(region); +todo_wine expect(Ok, status); /* Test a floating-point triangle */ @@ -370,17 +397,18 @@ todo_wine expect(Ok, status); status = GdipAddPathLine(path, 5.6, 6.2, 7.2, 8.9); expect(Ok, status); - status = GdipAddPathLine(path, 7.2, 8.9, 8.1, 1.6); - expect(Ok, status); status = GdipAddPathLine(path, 8.1, 1.6, 5.6, 6.2); expect(Ok, status); +todo_wine +{ status = GdipCreateRegionPath(path, ®ion); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); - ok(needed == 72, "Expected 72, got %d\n", needed); + expect(72, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); + expect(72, needed); expect_dword(buf, 64); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); @@ -399,8 +427,12 @@ todo_wine expect_float(buf + 14, 1.6); expect_float(buf + 15, 5.6); expect_float(buf + 16, 6.2); +} + status = GdipDeletePath(path); + expect(Ok, status); status = GdipDeleteRegion(region); +todo_wine expect(Ok, status); } diff --git a/dlls/hhctrl.ocx/webbrowser.c b/dlls/hhctrl.ocx/webbrowser.c index 4f17136ed0f..c9caa38f1fa 100644 --- a/dlls/hhctrl.ocx/webbrowser.c +++ b/dlls/hhctrl.ocx/webbrowser.c @@ -20,6 +20,10 @@ #include "hhctrl.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp); + #define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) typedef struct IOleClientSiteImpl @@ -37,45 +41,62 @@ typedef struct IOleClientSiteImpl HWND hwndWindow; } IOleClientSiteImpl; +#define CLIENTSITE(x) ((IOleClientSite*) &(x)->lpVtbl) +#define DOCHOSTUI(x) ((IDocHostUIHandler*) &(x)->lpvtblDocHostUIHandler) +#define INPLACESITE(x) ((IOleInPlaceSite*) &(x)->lpvtblOleInPlaceSite) +#define INPLACEFRAME(x) ((IOleInPlaceFrame*) &(x)->lpvtblOleInPlaceFrame) + static HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppvObj) { ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface); + *ppvObj = NULL; - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleClientSite)) - { - *ppvObj = This; - } - else if (IsEqualIID(riid, &IID_IOleInPlaceSite)) - { + if (IsEqualIID(riid, &IID_IUnknown)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObj); + *ppvObj = CLIENTSITE(This); + }else if(IsEqualIID(riid, &IID_IOleClientSite)) { + TRACE("(%p)->(IID_IOleClientSite %p)\n", This, ppvObj); + *ppvObj = CLIENTSITE(This); + }else if (IsEqualIID(riid, &IID_IOleInPlaceSite)) { + TRACE("(%p)->(IID_IOleInPlaceSite %p)\n", This, ppvObj); *ppvObj = &(This->lpvtblOleInPlaceSite); - } - else if (IsEqualIID(riid, &IID_IDocHostUIHandler)) - { + }else if (IsEqualIID(riid, &IID_IOleInPlaceFrame)) { + TRACE("(%p)->(IID_IOleInPlaceFrame %p)\n", This, ppvObj); + *ppvObj = &(This->lpvtblOleInPlaceSite); + }else if (IsEqualIID(riid, &IID_IDocHostUIHandler)) { + TRACE("(%p)->(IID_IDocHostUIHandler %p)\n", This, ppvObj); *ppvObj = &(This->lpvtblDocHostUIHandler); - } - else + }else { + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObj); return E_NOINTERFACE; + } + IUnknown_AddRef((IUnknown*)*ppvObj); return S_OK; } static ULONG STDMETHODCALLTYPE Site_AddRef(IOleClientSite *iface) { ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface); - return InterlockedIncrement(&This->ref); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; } static ULONG STDMETHODCALLTYPE Site_Release(IOleClientSite *iface) { ICOM_THIS_MULTI(IOleClientSiteImpl, lpVtbl, iface); - LONG refCount = InterlockedDecrement(&This->ref); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); - if (refCount) - return refCount; + if(!ref) + heap_free(This); - heap_free(This); - return 0; + return ref; } static HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite *iface) @@ -126,17 +147,22 @@ static const IOleClientSiteVtbl MyIOleClientSiteTable = static HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler *iface, REFIID riid, LPVOID *ppvObj) { ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblDocHostUIHandler, iface); - return Site_QueryInterface((IOleClientSite *)This, riid, ppvObj); + + return IOleClientSite_QueryInterface(CLIENTSITE(This), riid, ppvObj); } static ULONG STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler *iface) { - return 1; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblDocHostUIHandler, iface); + + return IOleClientSite_AddRef(CLIENTSITE(This)); } static ULONG STDMETHODCALLTYPE UI_Release(IDocHostUIHandler * iface) { - return 2; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblDocHostUIHandler, iface); + + return IOleClientSite_Release(CLIENTSITE(This)); } static HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler *iface, DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved) @@ -246,17 +272,22 @@ static const IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable = static HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite *iface, REFIID riid, LPVOID *ppvObj) { ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface); - return Site_QueryInterface((IOleClientSite *)This, riid, ppvObj); + + return IOleClientSite_QueryInterface(CLIENTSITE(This), riid, ppvObj); } static ULONG STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite *iface) { - return 1; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface); + + return IOleClientSite_AddRef(CLIENTSITE(This)); } static ULONG STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite *iface) { - return 2; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface); + + return IOleClientSite_Release(CLIENTSITE(This)); } static HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite *iface, HWND *lphwnd) @@ -290,7 +321,10 @@ static HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite *iface) static HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite *iface, LPOLEINPLACEFRAME *lplpFrame, LPOLEINPLACEUIWINDOW *lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) { ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceSite, iface); - *lplpFrame = (LPOLEINPLACEFRAME)&This->lpvtblOleInPlaceFrame; + + *lplpFrame = INPLACEFRAME(This); + IOleInPlaceFrame_AddRef(INPLACEFRAME(This)); + *lplpDoc = NULL; lpFrameInfo->fMDIApp = FALSE; @@ -358,17 +392,23 @@ static const IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable = static HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, LPVOID *ppvObj) { - return E_NOTIMPL; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceFrame, iface); + + return IOleClientSite_QueryInterface(CLIENTSITE(This), riid, ppvObj); } static ULONG STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame *iface) { - return 1; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceFrame, iface); + + return IOleClientSite_AddRef(CLIENTSITE(This)); } static ULONG STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame *iface) { - return 2; + ICOM_THIS_MULTI(IOleClientSiteImpl, lpvtblOleInPlaceFrame, iface); + + return IOleClientSite_Release(CLIENTSITE(This)); } static HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame *iface, HWND *lphwnd) diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c index 09b408c252e..e5b44ce5595 100644 --- a/dlls/inetmib1/main.c +++ b/dlls/inetmib1/main.c @@ -107,9 +107,12 @@ static void mib2IfNumberInit(void) if (ret == ERROR_INSUFFICIENT_BUFFER) { - ifTable = HeapAlloc(GetProcessHeap(), 0, size); - if (ifTable) - GetIfTable(ifTable, &size, FALSE); + MIB_IFTABLE *table = HeapAlloc(GetProcessHeap(), 0, size); + if (table) + { + if (!GetIfTable(table, &size, FALSE)) ifTable = table; + else HeapFree(GetProcessHeap(), 0, table ); + } } } @@ -633,9 +636,12 @@ static void mib2IpAddrInit(void) if (ret == ERROR_INSUFFICIENT_BUFFER) { - ipAddrTable = HeapAlloc(GetProcessHeap(), 0, size); - if (ipAddrTable) - GetIpAddrTable(ipAddrTable, &size, TRUE); + MIB_IPADDRTABLE *table = HeapAlloc(GetProcessHeap(), 0, size); + if (table) + { + if (!GetIpAddrTable(table, &size, TRUE)) ipAddrTable = table; + else HeapFree(GetProcessHeap(), 0, table ); + } } } @@ -721,9 +727,12 @@ static void mib2IpRouteInit(void) if (ret == ERROR_INSUFFICIENT_BUFFER) { - ipRouteTable = HeapAlloc(GetProcessHeap(), 0, size); - if (ipRouteTable) - GetIpForwardTable(ipRouteTable, &size, TRUE); + MIB_IPFORWARDTABLE *table = HeapAlloc(GetProcessHeap(), 0, size); + if (table) + { + if (!GetIpForwardTable(ipRouteTable, &size, TRUE)) ipRouteTable = table; + else HeapFree(GetProcessHeap(), 0, table ); + } } } @@ -801,9 +810,12 @@ static void mib2IpNetInit(void) if (ret == ERROR_INSUFFICIENT_BUFFER) { - ipNetTable = HeapAlloc(GetProcessHeap(), 0, size); - if (ipNetTable) - GetIpNetTable(ipNetTable, &size, FALSE); + MIB_IPNETTABLE *table = HeapAlloc(GetProcessHeap(), 0, size); + if (table) + { + if (!GetIpNetTable(ipNetTable, &size, FALSE)) ipNetTable = table; + else HeapFree(GetProcessHeap(), 0, table ); + } } } @@ -1047,9 +1059,12 @@ static void mib2UdpEntryInit(void) if (ret == ERROR_INSUFFICIENT_BUFFER) { - udpTable = HeapAlloc(GetProcessHeap(), 0, size); - if (udpTable) - GetUdpTable(udpTable, &size, TRUE); + MIB_UDPTABLE *table = HeapAlloc(GetProcessHeap(), 0, size); + if (table) + { + if (!GetUdpTable(table, &size, TRUE)) udpTable = table; + else HeapFree(GetProcessHeap(), 0, table); + } } } diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 6a24e333fc2..3f0784545c6 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -179,7 +179,7 @@ @ stdcall CancelIo(long) # @ stub CancelTimerQueueTimer @ stdcall CancelWaitableTimer(long) -@ stub ChangeTimerQueueTimer +@ stdcall ChangeTimerQueueTimer(ptr ptr long long) # @ stub CheckNameLegalDOS8Dot3A # @ stub CheckNameLegalDOS8Dot3W @ stdcall CheckRemoteDebuggerPresent(long ptr) @@ -224,8 +224,8 @@ @ stdcall CreateFileMappingA(long ptr long long long str) @ stdcall CreateFileMappingW(long ptr long long long wstr) @ stdcall CreateFileW(wstr long long ptr long long long) -# @ stub CreateHardLinkA -# @ stub CreateHardLinkW +@ stdcall CreateHardLinkA(str str ptr) +@ stdcall CreateHardLinkW(wstr wstr ptr) @ stdcall CreateIoCompletionPort(long long long long) @ stdcall CreateJobObjectA(ptr str) @ stdcall CreateJobObjectW(ptr wstr) diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c index aad260f9c4b..fca12ccd60f 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c @@ -1193,6 +1193,32 @@ BOOL WINAPI MoveFileA( LPCSTR source, LPCSTR dest ) } +/************************************************************************* + * CreateHardLinkW (KERNEL32.@) + */ +BOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + FIXME("(%s, %s, %p): stub\n", debugstr_w(lpFileName), + debugstr_w(lpExistingFileName), lpSecurityAttributes); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + + +/************************************************************************* + * CreateHardLinkA (KERNEL32.@) + */ +BOOL WINAPI CreateHardLinkA(LPCSTR lpFileName, LPCSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + FIXME("(%s, %s, %p): stub\n", debugstr_a(lpFileName), + debugstr_a(lpExistingFileName), lpSecurityAttributes); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + + /*********************************************************************** * CreateDirectoryW (KERNEL32.@) * RETURNS: diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index da558fd63d3..52919042111 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -1047,9 +1047,16 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle ) */ HANDLE WINAPI CreateTimerQueue(void) { - FIXME("stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return NULL; + HANDLE q; + NTSTATUS status = RtlCreateTimerQueue(&q); + + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return NULL; + } + + return q; } @@ -1058,9 +1065,15 @@ HANDLE WINAPI CreateTimerQueue(void) */ BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) { - FIXME("(%p, %p): stub\n", TimerQueue, CompletionEvent); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + NTSTATUS status = RtlDeleteTimerQueueEx(TimerQueue, CompletionEvent); + + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + return TRUE; } /*********************************************************************** @@ -1072,16 +1085,42 @@ BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) * * RETURNS * nonzero on success or zero on failure - * - * BUGS - * Unimplemented */ BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue, WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags ) { - FIXME("stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + NTSTATUS status = RtlCreateTimer(phNewTimer, TimerQueue, Callback, + Parameter, DueTime, Period, Flags); + + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + return TRUE; +} + +/*********************************************************************** + * ChangeTimerQueueTimer (KERNEL32.@) + * + * Changes the times at which the timer expires. + * + * RETURNS + * nonzero on success or zero on failure + */ +BOOL WINAPI ChangeTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer, + ULONG DueTime, ULONG Period ) +{ + NTSTATUS status = RtlUpdateTimer(TimerQueue, Timer, DueTime, Period); + + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + return TRUE; } @@ -1092,15 +1131,16 @@ BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue, * * RETURNS * nonzero on success or zero on failure - * - * BUGS - * Unimplemented */ BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent ) { - FIXME("stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + NTSTATUS status = RtlDeleteTimer(TimerQueue, Timer, CompletionEvent); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } return TRUE; } diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index c234921d405..59d02cf57ae 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -840,7 +840,7 @@ static void test_CompareStringA(void) /* test for CompareStringA flags */ SetLastError(0xdeadbeef); - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0x10, "NULL", -1, "NULL", -1); + ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0x8, "NULL", -1, "NULL", -1); ok(GetLastError() == ERROR_INVALID_FLAGS, "unexpected error code %d\n", GetLastError()); ok(!ret, "CompareStringA must fail with invalid flag\n"); diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index b01498b2db7..c7a949c4ee4 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -27,7 +27,13 @@ #include "wine/test.h" +static BOOL (WINAPI *pChangeTimerQueueTimer)(HANDLE, HANDLE, ULONG, ULONG); +static HANDLE (WINAPI *pCreateTimerQueue)(void); +static BOOL (WINAPI *pCreateTimerQueueTimer)(PHANDLE, HANDLE, WAITORTIMERCALLBACK, + PVOID, DWORD, DWORD, ULONG); static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR); +static BOOL (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE); +static BOOL (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE); static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR); static void test_signalandwait(void) @@ -542,106 +548,293 @@ static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut) ++*pn; } +struct timer_queue_data1 +{ + int num_calls; + int max_calls; + HANDLE q, t; +}; + +static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut) +{ + struct timer_queue_data1 *d = p; + ok(timedOut, "Timer callbacks should always time out\n"); + if (d->t && ++d->num_calls == d->max_calls) + { + BOOL ret; + SetLastError(0xdeadbeef); + /* Note, XP SP2 does *not* do any deadlock checking, so passing + INVALID_HANDLE_VALUE here will just hang. */ + ret = pDeleteTimerQueueTimer(d->q, d->t, NULL); + ok(!ret, "DeleteTimerQueueTimer\n"); + ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n"); + } +} + +static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut) +{ + struct timer_queue_data1 *d = p; + ok(timedOut, "Timer callbacks should always time out\n"); + if (d->t && ++d->num_calls == d->max_calls) + { + /* Basically kill the timer since it won't have time to run + again. */ + BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0); + ok(ret, "ChangeTimerQueueTimer\n"); + } +} + +static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut) +{ + struct timer_queue_data1 *d = p; + ok(timedOut, "Timer callbacks should always time out\n"); + if (d->t) + { + /* This tests whether a timer gets flagged for deletion before + or after the callback runs. If we start this timer with a + period of zero (run once), then ChangeTimerQueueTimer will + fail if the timer is already flagged. Hence we really run + only once. Otherwise we will run multiple times. */ + BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50); + ok(ret, "ChangeTimerQueueTimer\n"); + ++d->num_calls; + } +} + +static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut) +{ + DWORD delay = (DWORD) p; + ok(timedOut, "Timer callbacks should always time out\n"); + if (delay) + Sleep(delay); +} + static void test_timer_queue(void) { HANDLE q, t1, t2, t3, t4, t5; int n1, n2, n3, n4, n5; - HANDLE e; + struct timer_queue_data1 d2, d3, d4; + HANDLE e, et1, et2; BOOL ret; - /* Test asyncronous deletion of the queue. */ - q = CreateTimerQueue(); - todo_wine + if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer + || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer) + { + skip("TimerQueue API not present\n"); + return; + } + + /* Test asynchronous deletion of the queue. */ + q = pCreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); SetLastError(0xdeadbeef); - ret = DeleteTimerQueueEx(q, NULL); + ret = pDeleteTimerQueueEx(q, NULL); ok(!ret, "DeleteTimerQueueEx\n"); - todo_wine ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n"); - /* Test syncronous deletion of the queue and running timers. */ - q = CreateTimerQueue(); - todo_wine + /* Test synchronous deletion of the queue and running timers. */ + q = pCreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); /* Called once. */ t1 = NULL; n1 = 0; - ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, - 0, 0); + ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, + 0, 0); ok(ret, "CreateTimerQueueTimer\n"); + ok(t1 != NULL, "CreateTimerQueueTimer\n"); /* A slow one. */ t2 = NULL; n2 = 0; - ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, - 100, 0); + ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, + 100, 0); ok(ret, "CreateTimerQueueTimer\n"); + ok(t2 != NULL, "CreateTimerQueueTimer\n"); /* A fast one. */ t3 = NULL; n3 = 0; - ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, - 10, 0); + ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, + 10, 0); ok(ret, "CreateTimerQueueTimer\n"); + ok(t3 != NULL, "CreateTimerQueueTimer\n"); /* Start really late (it won't start). */ t4 = NULL; n4 = 0; - ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, - 10, 0); + ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, + 10, 0); ok(ret, "CreateTimerQueueTimer\n"); + ok(t4 != NULL, "CreateTimerQueueTimer\n"); /* Start soon, but delay so long it won't run again. */ t5 = NULL; n5 = 0; - ret = CreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, - 10000, 0); + ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, + 10000, 0); ok(ret, "CreateTimerQueueTimer\n"); + ok(t5 != NULL, "CreateTimerQueueTimer\n"); /* Give them a chance to do some work. */ Sleep(500); - ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); - todo_wine - { + /* Test deleting a once-only timer. */ + ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE); + ok(ret, "DeleteTimerQueueTimer\n"); + + /* A periodic timer. */ + ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE); + ok(ret, "DeleteTimerQueueTimer\n"); + + ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueEx\n"); ok(n1 == 1, "Timer callback 1\n"); ok(n2 < n3, "Timer callback 2 should be much slower than 3\n"); - } ok(n4 == 0, "Timer callback 4\n"); - todo_wine ok(n5 == 1, "Timer callback 5\n"); - /* Test syncronous deletion of the queue with event trigger. */ + /* Test synchronous deletion of the timer/queue with event trigger. */ e = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!e) + et1 = CreateEvent(NULL, TRUE, FALSE, NULL); + et2 = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!e || !et1 || !et2) { skip("Failed to create timer queue descruction event\n"); return; } - q = CreateTimerQueue(); - todo_wine + q = pCreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); + /* Run once and finish quickly (should be done when we delete it). */ + t1 = NULL; + ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, (PVOID) 0, 0, + 0, 0); + ok(ret, "CreateTimerQueueTimer\n"); + ok(t1 != NULL, "CreateTimerQueueTimer\n"); + + /* Run once and finish slowly (shouldn't be done when we delete it). */ + t2 = NULL; + ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, + 0, 0); + ok(ret, "CreateTimerQueueTimer\n"); + ok(t2 != NULL, "CreateTimerQueueTimer\n"); + + /* Run once and finish quickly (should be done when we delete it). */ + t3 = NULL; + ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, (PVOID) 0, 0, + 0, 0); + ok(ret, "CreateTimerQueueTimer\n"); + ok(t3 != NULL, "CreateTimerQueueTimer\n"); + + /* Run once and finish slowly (shouldn't be done when we delete it). */ + t4 = NULL; + ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, + 0, 0); + ok(ret, "CreateTimerQueueTimer\n"); + ok(t4 != NULL, "CreateTimerQueueTimer\n"); + + /* Give them a chance to start. */ + Sleep(400); + + /* DeleteTimerQueueTimer always returns PENDING with a NULL event, + even if the timer is finished. */ + SetLastError(0xdeadbeef); + ret = pDeleteTimerQueueTimer(q, t1, NULL); + ok(!ret, "DeleteTimerQueueTimer\n"); + ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n"); + + SetLastError(0xdeadbeef); + ret = pDeleteTimerQueueTimer(q, t2, NULL); + ok(!ret, "DeleteTimerQueueTimer\n"); + ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n"); + + SetLastError(0xdeadbeef); + ret = pDeleteTimerQueueTimer(q, t3, et1); + ok(ret, "DeleteTimerQueueTimer\n"); + ok(GetLastError() == 0xdeadbeef, "DeleteTimerQueueTimer\n"); + ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0, + "Timer destruction event not triggered\n"); + SetLastError(0xdeadbeef); - ret = DeleteTimerQueueEx(q, e); + ret = pDeleteTimerQueueTimer(q, t4, et2); + ok(!ret, "DeleteTimerQueueTimer\n"); + ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n"); + ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0, + "Timer destruction event not triggered\n"); + + SetLastError(0xdeadbeef); + ret = pDeleteTimerQueueEx(q, e); ok(!ret, "DeleteTimerQueueEx\n"); - todo_wine - { ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n"); ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0, - "Timer destruction event not triggered\n"); - } + "Queue destruction event not triggered\n"); CloseHandle(e); + + /* Test deleting/changing a timer in execution. */ + q = pCreateTimerQueue(); + ok(q != NULL, "CreateTimerQueue\n"); + + /* Test changing a once-only timer before it fires (this is allowed, + whereas after it fires you cannot). */ + n1 = 0; + ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, + 0, 0); + ok(ret, "CreateTimerQueueTimer\n"); + ok(t1 != NULL, "CreateTimerQueueTimer\n"); + ret = pChangeTimerQueueTimer(q, t1, 0, 0); + ok(ret, "ChangeTimerQueueTimer\n"); + + d2.t = t2 = NULL; + d2.num_calls = 0; + d2.max_calls = 3; + d2.q = q; + ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, + 10, 0); + d2.t = t2; + ok(ret, "CreateTimerQueueTimer\n"); + ok(t2 != NULL, "CreateTimerQueueTimer\n"); + + d3.t = t3 = NULL; + d3.num_calls = 0; + d3.max_calls = 4; + d3.q = q; + ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, + 10, 0); + d3.t = t3; + ok(ret, "CreateTimerQueueTimer\n"); + ok(t3 != NULL, "CreateTimerQueueTimer\n"); + + d4.t = t4 = NULL; + d4.num_calls = 0; + d4.q = q; + ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, + 0, 0); + d4.t = t4; + ok(ret, "CreateTimerQueueTimer\n"); + ok(t4 != NULL, "CreateTimerQueueTimer\n"); + + Sleep(200); + + ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); + ok(ret, "DeleteTimerQueueEx\n"); + ok(n1 == 1, "ChangeTimerQueueTimer\n"); + ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n"); + ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n"); + ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n"); } START_TEST(sync) { HMODULE hdll = GetModuleHandle("kernel32"); + pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer"); + pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue"); + pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer"); pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA"); + pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx"); + pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer"); pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA"); test_signalandwait(); diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index d1ac61795e1..5c3d99e99a7 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -450,6 +450,7 @@ static VOID test_CreateThread_suspended(void) { HANDLE thread; DWORD threadId; + DWORD suspend_count; int error; thread = CreateThread(NULL,0,threadFunc2,NULL, @@ -471,6 +472,13 @@ static VOID test_CreateThread_suspended(void) if(error!=WAIT_OBJECT_0) { TerminateThread(thread,1); } + + suspend_count = SuspendThread(thread); + ok(suspend_count == -1, "SuspendThread returned %d, expected -1\n", suspend_count); + + suspend_count = ResumeThread(thread); + ok(suspend_count == 0, "ResumeThread returned %d, expected 0\n", suspend_count); + ok(CloseHandle(thread)!=0,"CloseHandle failed\n"); } diff --git a/dlls/mlang/mlang.c b/dlls/mlang/mlang.c index 0920178c6ad..412427e4149 100644 --- a/dlls/mlang/mlang.c +++ b/dlls/mlang/mlang.c @@ -258,16 +258,46 @@ static const MIME_CP_INFO hebrew_cp[] = }; static const MIME_CP_INFO japanese_cp[] = { + { "Japanese (Auto-Select)", + 50932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | + MIMECONTF_IMPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS | + MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, + "_autodetect", "_autodetect", "_autodetect" }, + { "Japanese (EUC)", + 51932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | + MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | + MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | + MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, + "euc-jp", "euc-jp", "euc-jp" }, + { "Japanese (JIS)", + 50220, MIMECONTF_IMPORT | MIMECONTF_MAILNEWS | MIMECONTF_EXPORT | + MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID_NLS | + MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST | + MIMECONTF_MIME_IE4, + "iso-2022-jp","iso-2022-jp","iso-2022-jp"}, + { "Japanese (JIS 0208-1990 and 0212-1990)", + 20932, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | + MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, + "EUC-JP","EUC-JP","EUC-JP"}, + { "Japanese (JIS-Allow 1 byte Kana)", + 50221, MIMECONTF_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_SAVABLE_BROWSER | + MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID_NLS | + MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, + "csISO2022JP","iso-2022-jp","iso-2022-jp"}, + { "Japanese (JIS-Allow 1 byte Kana - SO/SI)", + 50222, MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_VALID | + MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, + "iso-2022-jp","iso-2022-jp","iso-2022-jp"}, + { "Japanese (Mac)", + 10001, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | + MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST, + "x-mac-japanese","x-mac-japanese","x-mac-japanese"}, { "Japanese (Shift-JIS)", 932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | - MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | - MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, - "shift_jis", "iso-2022-jp", "iso-2022-jp" }, - { "Japanese (JIS 0208-1990 and 0212-1990)", - 20932, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | - MIMECONTF_MIME_LATEST, - "euc-jp", "euc-jp", "euc-jp" } + MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID | + MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST, + "shift_jis", "iso-2022-jp", "iso-2022-jp" } }; static const MIME_CP_INFO korean_cp[] = { @@ -439,7 +469,7 @@ static const struct mlang_data { "Hebrew",1255,sizeof(hebrew_cp)/sizeof(hebrew_cp[0]),hebrew_cp, "Courier","Arial" }, /* FIXME */ { "Japanese",932,sizeof(japanese_cp)/sizeof(japanese_cp[0]),japanese_cp, - "Courier","Arial" }, /* FIXME */ + "MS Gothic","MS PGothic" }, { "Korean",949,sizeof(korean_cp)/sizeof(korean_cp[0]),korean_cp, "Courier","Arial" }, /* FIXME */ { "Thai",874,sizeof(thai_cp)/sizeof(thai_cp[0]),thai_cp, @@ -459,6 +489,371 @@ static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINF static LONG dll_count; /* + * Japanese Detection and Converstion Functions + */ + +#define HANKATA(A) ((A >= 161) && (A <= 223)) +#define ISEUC(A) ((A >= 161) && (A <= 254)) +#define NOTEUC(A,B) (((A >= 129) && (A <= 159)) && ((B >= 64) && (B <= 160))) +#define SJIS1(A) (((A >= 129) && (A <= 159)) || ((A >= 224) && (A <= 239))) +#define SJIS2(A) ((A >= 64) && (A <= 252)) +#define ISMARU(A) ((A >= 202) && (A <= 206)) +#define ISNIGORI(A) (((A >= 182) && (A <= 196)) || ((A >= 202) && (A <= 206))) + +static UINT DetectJapaneseCode(LPCSTR input, DWORD count) +{ + UINT code = 0; + int i = 0; + unsigned char c1,c2; + + while ((code == 0 || code == 51932) && i < count) + { + c1 = input[i]; + if (c1 == 0x1b /* ESC */) + { + i++; + if (i >= count) + return code; + c1 = input[i]; + if (c1 == '$') + { + i++; + if (i >= count) + return code; + c1 = input[i]; + if (c1 =='B' || c1 == '@') + code = 50220; + } + if (c1 == 'K') + code = 50220; + } + else if (c1 >= 129) + { + i++; + if (i >= count) + return code; + c2 = input[i]; + if NOTEUC(c1,c2) + code = 932; + else if (ISEUC(c1) && ISEUC(c2)) + code = 51932; + else if (((c1 == 142)) && HANKATA(c2)) + code = 51932; + } + i++; + } + return code; +} + +static inline void jis2sjis(unsigned char *p1, unsigned char *p2) +{ + unsigned char c1 = *p1; + unsigned char c2 = *p2; + int row = c1 < 95 ? 112 : 176; + int cell = c1 % 2 ? 31 + (c2 > 95) : 126; + + *p1 = ((c1 + 1) >> 1) + row; + *p2 = c2 + cell; +} + +static inline void sjis2jis(unsigned char *p1, unsigned char *p2) +{ + unsigned char c1 = *p1; + unsigned char c2 = *p2; + int shift = c2 < 159; + int row = c1 < 160 ? 112 : 176; + int cell = shift ? (31 + (c2 > 127)): 126; + + *p1 = ((c1 - row) << 1) - shift; + *p2 -= cell; +} + +static int han2zen(unsigned char *p1, unsigned char *p2) +{ + int maru = FALSE; + int nigori = FALSE; + static const unsigned char char1[] = {129,129,129,129,129,131,131,131,131, + 131,131,131,131,131,131,129,131,131,131,131,131,131,131,131,131,131, + 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, + 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, + 131,129,129 }; + static const unsigned char char2[] = {66,117,118,65,69,146,64,66,68,70, + 72,131,133,135,98,91,65,67,69,71,73,74,76,78,80,82,84,86,88,90,92,94, + 96,99,101,103,105,106,107,108,109,110,113,116,119,122,125,126,128, + 129,130,132,134,136,137,138,139,140,141,143,147,74,75}; + + if (( *p2 == 222) && ((ISNIGORI(*p1) || (*p1 == 179)))) + nigori = TRUE; + else if ((*p2 == 223) && (ISMARU(*p1))) + maru = TRUE; + + if (*p1 >= 161 && *p1 <= 223) + { + unsigned char index = *p1 - 161; + *p1 = char1[index]; + *p2 = char2[index]; + } + + if (maru || nigori) + { + if (nigori) + { + if (((*p2 >= 74) && (*p2 <= 103)) || ((*p2 >= 110) && (*p2 <= 122))) + (*p2)++; + else if ((*p1 == 131) && (*p2 == 69)) + *p2 = 148; + } + else if ((maru) && ((*p2 >= 110) && (*p2 <= 122))) + *p2+= 2; + + return 1; + } + + return 0; +} + + +static UINT ConvertJIS2SJIS(LPCSTR input, DWORD count, LPSTR output) +{ + int i = 0; + int j = 0; + unsigned char p2,p; + int shifted = FALSE; + + while (i < count) + { + p = input[i]; + if (p == 0x1b /* ESC */) + { + i++; + if (i >= count) + return 0; + p2 = input[i]; + if (p2 == '$' || p2 =='(') + i++; + if (p2 == 'K' || p2 =='$') + shifted = TRUE; + else + shifted = FALSE; + } + else + { + if (shifted) + { + i++; + if (i >= count) + return 0; + p2 = input[i]; + jis2sjis(&p,&p2); + output[j++]=p; + output[j++]=p2; + } + else + { + output[j++] = p; + } + } + i++; + } + return j; +} + +static inline int exit_shift(LPSTR out, int c) +{ + if (out) + { + out[c] = 0x1b; + out[c+1] = '('; + out[c+2] = 'B'; + } + return 3; +} + +static inline int enter_shift(LPSTR out, int c) +{ + if (out) + { + out[c] = 0x1b; + out[c+1] = '$'; + out[c+2] = 'B'; + } + return 3; +} + + +static UINT ConvertSJIS2JIS(LPCSTR input, DWORD count, LPSTR output) +{ + int i = 0; + int j = 0; + unsigned char p2,p; + int shifted = FALSE; + + while (i < count) + { + p = input[i] & 0xff; + if (p == 10 || p == 13) /* NL and CR */ + { + if (shifted) + { + shifted = FALSE; + j += exit_shift(output,j); + } + if (output) + output[j++] = p; + else + j++; + } + else + { + if (SJIS1(p)) + { + i++; + if (i >= count) + return 0; + p2 = input[i] & 0xff; + if (SJIS2(p2)) + { + sjis2jis(&p,&p2); + if (!shifted) + { + shifted = TRUE; + j+=enter_shift(output,j); + } + } + + if (output) + { + output[j++]=p; + output[j++]=p2; + } + else + j+=2; + } + else + { + if (HANKATA(p)) + { + if ((i+1) >= count) + return 0; + p2 = input[i+1] & 0xff; + i+=han2zen(&p,&p2); + sjis2jis(&p,&p2); + if (!shifted) + { + shifted = TRUE; + j+=enter_shift(output,j); + } + if (output) + { + output[j++]=p; + output[j++]=p2; + } + else + j+=2; + } + else + { + if (shifted) + { + shifted = FALSE; + j += exit_shift(output,j); + } + if (output) + output[j++]=p; + else + j++; + } + } + } + i++; + } + if (shifted) + j += exit_shift(output,j); + return j; +} + +static UINT ConvertJISJapaneseToUnicode(LPCSTR input, DWORD count, + LPWSTR output, DWORD out_count) +{ + CHAR *sjis_string; + UINT rc = 0; + sjis_string = HeapAlloc(GetProcessHeap(),0,count); + rc = ConvertJIS2SJIS(input,count,sjis_string); + if (rc) + { + TRACE("%s\n",debugstr_an(sjis_string,rc)); + if (output) + rc = MultiByteToWideChar(932,0,sjis_string,rc,output,out_count); + else + rc = MultiByteToWideChar(932,0,sjis_string,rc,0,0); + } + HeapFree(GetProcessHeap(),0,sjis_string); + return rc; + +} + +static UINT ConvertUnknownJapaneseToUnicode(LPCSTR input, DWORD count, + LPWSTR output, DWORD out_count) +{ + CHAR *sjis_string; + UINT rc = 0; + int code = DetectJapaneseCode(input,count); + TRACE("Japanese code %i\n",code); + + if (code == 932) + { + if (output) + rc = MultiByteToWideChar(932,0,input,count,output,out_count); + else + rc = MultiByteToWideChar(932,0,input,count,0,0); + } + else if (code == 51932) + { + if (output) + rc = MultiByteToWideChar(20932,0,input,count,output,out_count); + else + rc = MultiByteToWideChar(20932,0,input,count,0,0); + } + else if (code == 50220) + { + sjis_string = HeapAlloc(GetProcessHeap(),0,count); + rc = ConvertJIS2SJIS(input,count,sjis_string); + if (rc) + { + TRACE("%s\n",debugstr_an(sjis_string,rc)); + if (output) + rc = MultiByteToWideChar(932,0,sjis_string,rc,output,out_count); + else + rc = MultiByteToWideChar(932,0,sjis_string,rc,0,0); + } + HeapFree(GetProcessHeap(),0,sjis_string); + } + return rc; +} + +static UINT ConvertJapaneseUnicodeToJIS(LPCWSTR input, DWORD count, + LPSTR output, DWORD out_count) +{ + CHAR *sjis_string; + INT len; + UINT rc = 0; + + len = WideCharToMultiByte(932,0,input,count,0,0,NULL,NULL); + sjis_string = HeapAlloc(GetProcessHeap(),0,len); + WideCharToMultiByte(932,0,input,count,sjis_string,len,NULL,NULL); + TRACE("%s\n",debugstr_an(sjis_string,len)); + + rc = ConvertSJIS2JIS(sjis_string, len, NULL); + if (out_count >= rc) + { + ConvertSJIS2JIS(sjis_string, len, output); + } + HeapFree(GetProcessHeap(),0,sjis_string); + return rc; + +} + +/* * Dll lifetime tracking declaration */ static void LockModule(void) @@ -510,6 +905,10 @@ HRESULT WINAPI ConvertINetMultiByteToUnicode( return S_OK; } + /* forwarding euc-jp to EUC-JP */ + if (dwEncoding == 51932) + dwEncoding = 20932; + switch (dwEncoding) { case CP_UNICODE: @@ -521,6 +920,15 @@ HRESULT WINAPI ConvertINetMultiByteToUnicode( memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR)); break; + case 50220: + case 50221: + case 50222: + *pcDstSize = ConvertJISJapaneseToUnicode(pSrcStr,*pcSrcSize,pDstStr,*pcDstSize); + break; + case 50932: + *pcDstSize = ConvertUnknownJapaneseToUnicode(pSrcStr,*pcSrcSize,pDstStr,*pcDstSize); + break; + default: if (*pcSrcSize == -1) *pcSrcSize = lstrlenA(pSrcStr); @@ -567,6 +975,10 @@ HRESULT WINAPI ConvertINetUnicodeToMultiByte( if (*pcSrcSize == -1) *pcSrcSize = lstrlenW(pSrcStr); + /* forwarding euc-jp to EUC-JP */ + if (dwEncoding == 51932) + dwEncoding = 20932; + if (dwEncoding == CP_UNICODE) { if (*pcSrcSize == -1) @@ -579,6 +991,22 @@ HRESULT WINAPI ConvertINetUnicodeToMultiByte( if (size >= destsz) goto fail; } + else if (dwEncoding == 50220 || dwEncoding == 50221 || dwEncoding == 50222) + { + size = ConvertJapaneseUnicodeToJIS(pSrcStr, *pcSrcSize, NULL, 0); + if (!size) + goto fail; + + if (pDstStr) + { + size = min(size, destsz); + size = ConvertJapaneseUnicodeToJIS(pSrcStr, *pcSrcSize, pDstStr, + destsz); + if (!size) + goto fail; + } + + } else { size = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, @@ -962,6 +1390,7 @@ typedef struct tagMLang_impl const IMultiLanguageVtbl *vtbl_IMultiLanguage; const IMultiLanguage3Vtbl *vtbl_IMultiLanguage3; const IMLangFontLink2Vtbl *vtbl_IMLangFontLink2; + const IMLangLineBreakConsoleVtbl *vtbl_IMLangLineBreakConsole; LONG ref; DWORD total_cp, total_scripts; } MLang_impl; @@ -1035,6 +1464,15 @@ static HRESULT WINAPI MLang_QueryInterface( return S_OK; } + if (IsEqualGUID(riid, &IID_IMLangLineBreakConsole)) + { + MLang_AddRef(This); + TRACE("Returning IID_IMLangLineBreakConsole %p ref = %d\n", This, This->ref); + *ppvObject = &(This->vtbl_IMLangLineBreakConsole); + return S_OK; + } + + WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); return E_NOINTERFACE; } @@ -2696,6 +3134,87 @@ static const IMLangFontLink2Vtbl IMLangFontLink2_vtbl = fnIMLangFontLink2_CodePageToScriptID }; +/******************************************************************************/ + +static HRESULT WINAPI fnIMLangLineBreakConsole_QueryInterface( + IMLangLineBreakConsole* iface, + REFIID riid, + void** ppvObject) +{ + ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangLineBreakConsole, iface); + return MLang_QueryInterface( This, riid, ppvObject ); +} + +static ULONG WINAPI fnIMLangLineBreakConsole_AddRef( + IMLangLineBreakConsole* iface ) +{ + ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangLineBreakConsole, iface); + return MLang_AddRef( This ); +} + +static ULONG WINAPI fnIMLangLineBreakConsole_Release( + IMLangLineBreakConsole* iface ) +{ + ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangLineBreakConsole, iface); + return MLang_Release( This ); +} + +static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineML( + IMLangLineBreakConsole* iface, + IMLangString* pSrcMLStr, + long lSrcPos, + long lSrcLen, + long cMinColumns, + long cMaxColumns, + long* plLineLen, + long* plSkipLen) +{ + FIXME("(%p)->%p %li %li %li %li %p %p\n", iface, pSrcMLStr, lSrcPos, lSrcLen, cMinColumns, cMaxColumns, plLineLen, plSkipLen); + return E_NOTIMPL; +} + +static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineW( + IMLangLineBreakConsole* iface, + LCID locale, + const WCHAR* pszSrc, + long cchSrc, + long cMaxColumns, + long* pcchLine, + long* pcchSkip ) +{ + FIXME("(%p)->%i %s %li %li %p %p\n", iface, locale, debugstr_wn(pszSrc,cchSrc), cchSrc, cMaxColumns, pcchLine, pcchSkip); + + *pcchLine = cchSrc; + *pcchSkip = 0; + return S_OK; +} + +static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineA( + IMLangLineBreakConsole* iface, + LCID locale, + UINT uCodePage, + const CHAR* pszSrc, + long cchSrc, + long cMaxColumns, + long* pcchLine, + long* pcchSkip) +{ + FIXME("(%p)->%i %i %s %li %li %p %p\n", iface, locale, uCodePage, debugstr_an(pszSrc,cchSrc), cchSrc, cMaxColumns, pcchLine, pcchSkip); + + *pcchLine = cchSrc; + *pcchSkip = 0; + return S_OK; +} + +static const IMLangLineBreakConsoleVtbl IMLangLineBreakConsole_vtbl = +{ + fnIMLangLineBreakConsole_QueryInterface, + fnIMLangLineBreakConsole_AddRef, + fnIMLangLineBreakConsole_Release, + fnIMLangLineBreakConsole_BreakLineML, + fnIMLangLineBreakConsole_BreakLineW, + fnIMLangLineBreakConsole_BreakLineA +}; static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj) { @@ -2712,6 +3231,7 @@ static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj) mlang->vtbl_IMultiLanguage = &IMultiLanguage_vtbl; mlang->vtbl_IMultiLanguage3 = &IMultiLanguage3_vtbl; mlang->vtbl_IMLangFontLink2 = &IMLangFontLink2_vtbl; + mlang->vtbl_IMLangLineBreakConsole = &IMLangLineBreakConsole_vtbl; mlang->total_cp = 0; for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++) diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index b77d69e4378..b1f063f0360 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -381,15 +381,70 @@ static HRESULT WINAPI HTMLDocument_get_anchors(IHTMLDocument2 *iface, IHTMLEleme static HRESULT WINAPI HTMLDocument_put_title(IHTMLDocument2 *iface, BSTR v) { HTMLDocument *This = HTMLDOC_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsIDOMHTMLDocument *nshtmldoc; + nsIDOMDocument *nsdoc; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + if(!This->nscontainer) + return E_FAIL; + + nsres = nsIWebNavigation_GetDocument(This->nscontainer->navigation, &nsdoc); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetDocument failed: %08x\n", nsres); + return E_FAIL; + } + + nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc); + nsIDOMDocument_Release(nsdoc); + + nsAString_Init(&nsstr, v); + nsres = nsIDOMHTMLDocument_SetTitle(nshtmldoc, &nsstr); + nsIDOMHTMLDocument_Release(nshtmldoc); + nsAString_Finish(&nsstr); + if(NS_FAILED(nsres)) + ERR("SetTitle failed: %08x\n", nsres); + + return S_OK; } static HRESULT WINAPI HTMLDocument_get_title(IHTMLDocument2 *iface, BSTR *p) { HTMLDocument *This = HTMLDOC_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsIDOMHTMLDocument *nshtmldoc; + nsIDOMDocument *nsdoc; + const PRUnichar *ret; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->nscontainer) + return E_FAIL; + + nsres = nsIWebNavigation_GetDocument(This->nscontainer->navigation, &nsdoc); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetDocument failed: %08x\n", nsres); + return E_FAIL; + } + + nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc); + nsIDOMDocument_Release(nsdoc); + + nsAString_Init(&nsstr, NULL); + + nsres = nsIDOMHTMLDocument_GetTitle(nshtmldoc, &nsstr); + nsIDOMHTMLDocument_Release(nshtmldoc); + if (NS_FAILED(nsres)) + ERR("GetTitle failed: %08x\n", nsres); + + nsAString_GetData(&nsstr, &ret); + *p = SysAllocString(ret); + nsAString_Finish(&nsstr); + + return S_OK; } static HRESULT WINAPI HTMLDocument_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p) diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index a579333e82e..9c285b070da 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -127,8 +127,13 @@ static HRESULT WINAPI OmNavigator_Invoke(IOmNavigator *iface, DISPID dispIdMembe static HRESULT WINAPI OmNavigator_get_appCodeName(IOmNavigator *iface, BSTR *p) { OmNavigator *This = OMNAVIGATOR_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + static const WCHAR mozillaW[] = {'M','o','z','i','l','l','a',0}; + + TRACE("(%p)->(%p)\n", This, p); + + *p = SysAllocString(mozillaW); + return S_OK; } static HRESULT WINAPI OmNavigator_get_appName(IOmNavigator *iface, BSTR *p) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 2c258709463..cb15187c9e6 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -1361,6 +1361,30 @@ static void _test_node_remove_child(unsigned line, IUnknown *unk, IHTMLDOMNode * IHTMLDOMNode_Release(new_node); } +#define test_doc_title(d,t) _test_doc_title(__LINE__,d,t) +static void _test_doc_title(unsigned line, IHTMLDocument2 *doc, const char *extitle) +{ + BSTR title = NULL; + HRESULT hres; + + hres = IHTMLDocument2_get_title(doc, &title); + ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres); + ok_(__FILE__,line) (!strcmp_wa(title, extitle), "unexpected title %s\n", dbgstr_w(title)); + SysFreeString(title); +} + +#define test_doc_set_title(d,t) _test_doc_set_title(__LINE__,d,t) +static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *title) +{ + BSTR tmp; + HRESULT hres; + + tmp = a2bstr(title); + hres = IHTMLDocument2_put_title(doc, tmp); + ok_(__FILE__,line) (hres == S_OK, "get_title failed: %08x\n", hres); + SysFreeString(tmp); +} + static void test_elem_col_item(IHTMLElementCollection *col, LPCWSTR n, const elem_type_t *elem_types, long len) { @@ -1775,6 +1799,7 @@ static void test_navigator(IHTMLDocument2 *doc) IHTMLWindow2 *window; IOmNavigator *navigator, *navigator2; ULONG ref; + BSTR bstr; HRESULT hres; hres = IHTMLDocument2_get_parentWindow(doc, &window); @@ -1791,6 +1816,12 @@ static void test_navigator(IHTMLDocument2 *doc) IHTMLWindow2_Release(window); IOmNavigator_Release(navigator2); + + hres = IOmNavigator_get_appCodeName(navigator, &bstr); + ok(hres == S_OK, "get_appCodeName failed: %08x\n", hres); + ok(!strcmp_wa(bstr, "Mozilla"), "Unexpected appCodeName %s\n", dbgstr_w(bstr)); + SysFreeString(bstr); + ref = IOmNavigator_Release(navigator); ok(!ref, "navigator should be destroyed here\n"); } @@ -1978,6 +2009,7 @@ static void test_defaults(IHTMLDocument2 *doc) IHTMLStyleSheetsCollection_Release(stylesheetcol); test_default_selection(doc); + test_doc_title(doc, ""); } static void test_stylesheet(IDispatch *disp) @@ -2332,6 +2364,10 @@ static void test_elems(IHTMLDocument2 *doc) test_stylesheets(doc); test_create_option_elem(doc); + + test_doc_title(doc, "test"); + test_doc_set_title(doc, "test title"); + test_doc_title(doc, "test title"); } static void test_create_elems(IHTMLDocument2 *doc) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index cde5c9802ec..5bb7008174c 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -1486,7 +1486,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param) } else { - file->IsCompressed = package->WordCount & MSIWORDCOUNT_COMPRESSED; + file->IsCompressed = package->WordCount & msidbSumInfoSourceTypeCompressed; } if (!file->IsCompressed) diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 08c1959225a..842a72d5634 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -743,12 +743,6 @@ static UINT copy_install_file(MSIFILE *file) TRACE("overwriting existing file\n"); gle = ERROR_SUCCESS; } - else if (gle == ERROR_FILE_NOT_FOUND) - { - /* FIXME: this needs to be tested, I'm pretty sure it fails */ - TRACE("Source file not found\n"); - gle = ERROR_SUCCESS; - } else if (gle == ERROR_ACCESS_DENIED) { SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL); @@ -756,11 +750,6 @@ static UINT copy_install_file(MSIFILE *file) gle = copy_file(file); TRACE("Overwriting existing file: %d\n", gle); } - else if (!(file->Attributes & msidbFileAttributesVital)) - { - TRACE("Ignoring error for nonvital\n"); - gle = ERROR_SUCCESS; - } return gle; } diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c index c578c680948..aba3bd94624 100644 --- a/dlls/msi/helpers.c +++ b/dlls/msi/helpers.c @@ -325,7 +325,11 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, { path = NULL; - if (f->SourceLongPath) + if (package->WordCount & msidbSumInfoSourceTypeCompressed) + path = get_source_root( package ); + else if (package->WordCount & msidbSumInfoSourceTypeSFN) + path = build_directory_name( 3, p, f->SourceShortPath, NULL ); + else path = build_directory_name( 3, p, f->SourceLongPath, NULL ); TRACE("source -> %s\n", debugstr_w(path)); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index fe880c621aa..19abc3f4b7e 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -42,11 +42,6 @@ #define MSITYPE_KEY 0x2000 #define MSITYPE_TEMPORARY 0x4000 -/* Word Count masks */ -#define MSIWORDCOUNT_SHORTFILENAMES 0x0001 -#define MSIWORDCOUNT_COMPRESSED 0x0002 -#define MSIWORDCOUNT_ADMINISTRATIVE 0x0004 -#define MSIWORDCOUNT_PRIVILEGES 0x0008 /* Install UI level mask for AND operation to exclude flags */ #define INSTALLUILEVEL_MASK 0x0007 diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 0b9dacfae75..1b5f2d13428 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -797,7 +797,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) return NULL; } - if (package->WordCount & MSIWORDCOUNT_ADMINISTRATIVE) + if (package->WordCount & msidbSumInfoSourceTypeAdminImage) msi_load_admin_properties( package ); } diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index e81e3a59490..4748831365d 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -691,6 +691,20 @@ static const CHAR is_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tV "Media\tDiskId\n" "1\t12\t\t\tDISK1\t\n"; +static const CHAR sp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "augustus\t\tTWODIR\t0\t\taugustus\n"; + +static const CHAR sp_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" + "s72\tS72\tl255\n" + "Directory\tDirectory\n" + "TARGETDIR\t\tSourceDir\n" + "ProgramFilesFolder\tTARGETDIR\t.\n" + "MSITESTDIR\tProgramFilesFolder\tmsitest:.\n" + "ONEDIR\tMSITESTDIR\t.:shortone|longone\n" + "TWODIR\tONEDIR\t.:shorttwo|longtwo"; + typedef struct _msi_table { const CHAR *filename; @@ -1041,6 +1055,18 @@ static const msi_table is_tables[] = ADD_TABLE(property), }; +static const msi_table sp_tables[] = +{ + ADD_TABLE(sp_component), + ADD_TABLE(sp_directory), + ADD_TABLE(rof_feature), + ADD_TABLE(ci2_feature_comp), + ADD_TABLE(ci2_file), + ADD_TABLE(install_exec_seq), + ADD_TABLE(rof_media), + ADD_TABLE(property), +}; + /* cabinet definitions */ /* make the max size large so there is only one cab file */ @@ -1334,7 +1360,9 @@ static void create_file_data(LPCSTR name, LPCSTR data, DWORD size) DWORD written; file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name); + if (file == INVALID_HANDLE_VALUE) + return; + WriteFile(file, data, strlen(data), &written, NULL); if (size) @@ -4411,22 +4439,22 @@ static void test_sourcefolder(void) MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_FAILURE, + "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); todo_wine { - ok(r == ERROR_INSTALL_FAILURE, - "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest", FALSE), "File installed\n"); } RemoveDirectoryA("msitest"); r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_INSTALL_FAILURE, + "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); todo_wine { - ok(r == ERROR_INSTALL_FAILURE, - "Expected ERROR_INSTALL_FAILURE, got %u\n", r); ok(!delete_pf("msitest", FALSE), "File installed\n"); } @@ -4557,6 +4585,372 @@ static void test_installstate(void) RemoveDirectory("msitest"); } +struct sourcepathmap +{ + BOOL sost; /* shortone\shorttwo */ + BOOL solt; /* shortone\longtwo */ + BOOL lost; /* longone\shorttwo */ + BOOL lolt; /* longone\longtwo */ + BOOL soste; /* shortone\shorttwo source exists */ + BOOL solte; /* shortone\longtwo source exists */ + BOOL loste; /* longone\shorttwo source exists */ + BOOL lolte; /* longone\longtwo source exists */ + UINT err; + DWORD size; +} spmap[256] = +{ + {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, ERROR_SUCCESS, 200}, + {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, ERROR_INSTALL_FAILURE, 0}, + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ERROR_INSTALL_FAILURE, 0}, +}; + +static DWORD get_pf_file_size(LPCSTR file) +{ + CHAR path[MAX_PATH]; + HANDLE hfile; + DWORD size; + + lstrcpyA(path, PROG_FILES_DIR); + lstrcatA(path, "\\"); + lstrcatA(path, file); + + hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hfile == INVALID_HANDLE_VALUE) + return 0; + + size = GetFileSize(hfile, NULL); + CloseHandle(hfile); + return size; +} + +static void test_sourcepath(void) +{ + UINT r, i; + + create_database(msifile, sp_tables, sizeof(sp_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + for (i = 0; i < sizeof(spmap) / sizeof(spmap[0]); i++) + { + if (spmap[i].sost) + { + CreateDirectoryA("shortone", NULL); + CreateDirectoryA("shortone\\shorttwo", NULL); + } + + if (spmap[i].solt) + { + CreateDirectoryA("shortone", NULL); + CreateDirectoryA("shortone\\longtwo", NULL); + } + + if (spmap[i].lost) + { + CreateDirectoryA("longone", NULL); + CreateDirectoryA("longone\\shorttwo", NULL); + } + + if (spmap[i].lolt) + { + CreateDirectoryA("longone", NULL); + CreateDirectoryA("longone\\longtwo", NULL); + } + + if (spmap[i].soste) + create_file("shortone\\shorttwo\\augustus", 50); + if (spmap[i].solte) + create_file("shortone\\longtwo\\augustus", 100); + if (spmap[i].loste) + create_file("longone\\shorttwo\\augustus", 150); + if (spmap[i].lolte) + create_file("longone\\longtwo\\augustus", 200); + + r = MsiInstallProductA(msifile, NULL); + ok(r == spmap[i].err, "%d: Expected %d, got %d\n", i, spmap[i].err, r); + ok(get_pf_file_size("msitest\\augustus") == spmap[i].size, + "%d: Expected %d, got %d\n", i, spmap[i].size, + get_pf_file_size("msitest\\augustus")); + + if (r == ERROR_SUCCESS) + { + ok(delete_pf("msitest\\augustus", TRUE), "%d: File not installed\n", i); + ok(delete_pf("msitest", FALSE), "%d: File not installed\n", i); + } + else + { + ok(!delete_pf("msitest\\augustus", TRUE), "%d: File installed\n", i); + todo_wine ok(!delete_pf("msitest", FALSE), "%d: File installed\n", i); + } + + DeleteFileA("shortone\\shorttwo\\augustus"); + DeleteFileA("shortone\\longtwo\\augustus"); + DeleteFileA("longone\\shorttwo\\augustus"); + DeleteFileA("longone\\longtwo\\augustus"); + RemoveDirectoryA("shortone\\shorttwo"); + RemoveDirectoryA("shortone\\longtwo"); + RemoveDirectoryA("longone\\shorttwo"); + RemoveDirectoryA("longone\\longtwo"); + RemoveDirectoryA("shortone"); + RemoveDirectoryA("longone"); + } + + DeleteFileA(msifile); +} + START_TEST(install) { DWORD len; @@ -4608,6 +5002,7 @@ START_TEST(install) test_sourcefolder(); test_customaction51(); test_installstate(); + test_sourcepath(); SetCurrentDirectoryA(prev_path); } diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index d26226db1c1..3eca2286cfe 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -5237,12 +5237,30 @@ static void test_complocator(void) DeleteFileA(msifile); } +static void set_suminfo_prop(MSIHANDLE db, DWORD prop, DWORD val) +{ + MSIHANDLE summary; + UINT r; + + r = MsiGetSummaryInformationA(db, NULL, 1, &summary); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + r = MsiSummaryInfoSetPropertyA(summary, prop, VT_I4, val, NULL, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + r = MsiSummaryInfoPersist(summary); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + + MsiCloseHandle(summary); +} + static void test_MsiGetSourcePath(void) { MSIHANDLE hdb, hpkg; CHAR path[MAX_PATH]; CHAR cwd[MAX_PATH]; CHAR subsrc[MAX_PATH]; + CHAR sub2[MAX_PATH]; DWORD size; UINT r; @@ -5253,15 +5271,29 @@ static void test_MsiGetSourcePath(void) lstrcatA(subsrc, "subsource"); lstrcatA(subsrc, "\\"); + lstrcpyA(sub2, subsrc); + lstrcatA(sub2, "sub2"); + lstrcatA(sub2, "\\"); + + /* uncompressed source */ + hdb = create_package_db(); ok( hdb, "failed to create database\n"); + set_suminfo_prop(hdb, PID_WORDCOUNT, 0); + r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); ok(r == S_OK, "failed\n"); r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'"); ok(r == S_OK, "failed\n"); + r = add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'"); + ok(r == S_OK, "failed\n"); + + r = MsiDatabaseCommit(hdb); + ok(r == ERROR_SUCCESS , "Failed to commit database\n"); + hpkg = package_from_db(hdb); ok(hpkg, "failed to create package\n"); @@ -5340,6 +5372,15 @@ static void test_MsiGetSourcePath(void) "Expected path to be unchanged, got \"%s\"\n", path); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + /* try SubDir2 */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_DIRECTORY, "Expected ERROR_DIRECTORY, got %d\n", r); + ok(!lstrcmpA(path, "kiwi"), + "Expected path to be unchanged, got \"%s\"\n", path); + ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + r = MsiDoAction(hpkg, "CostInitialize"); ok(r == ERROR_SUCCESS, "cost init failed\n"); @@ -5387,6 +5428,14 @@ static void test_MsiGetSourcePath(void) ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + /* try SubDir2 after CostInitialize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); + ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size); + r = MsiDoAction(hpkg, "ResolveSource"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -5431,6 +5480,14 @@ static void test_MsiGetSourcePath(void) ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + /* try SubDir2 after ResolveSource */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); + ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size); + r = MsiDoAction(hpkg, "FileCost"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -5467,6 +5524,14 @@ static void test_MsiGetSourcePath(void) ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + /* try SubDir2 after FileCost */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); + ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size); + r = MsiDoAction(hpkg, "CostFinalize"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -5503,6 +5568,14 @@ static void test_MsiGetSourcePath(void) ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + /* try SubDir2 after CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, sub2), "Expected \"%s\", got \"%s\"\n", sub2, path); + ok(size == lstrlenA(sub2), "Expected %d, got %d\n", lstrlenA(sub2), size); + /* nonexistent directory */ size = MAX_PATH; lstrcpyA(path, "kiwi"); @@ -5553,6 +5626,68 @@ static void test_MsiGetSourcePath(void) ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); MsiCloseHandle(hpkg); + + /* compressed source */ + + r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeCompressed); + + hpkg = package_from_db(hdb); + ok(hpkg, "failed to create package\n"); + + r = MsiDoAction(hpkg, "CostInitialize"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + r = MsiDoAction(hpkg, "FileCost"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + r = MsiDoAction(hpkg, "CostFinalize"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + /* try TARGETDIR after CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "TARGETDIR", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + + /* try SourceDir after CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SourceDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + + /* try SOURCEDIR after CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SOURCEDIR", path, &size); + todo_wine + { + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + } + + /* try SubDir after CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + + /* try SubDir2 after CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, cwd), "Expected \"%s\", got \"%s\"\n", cwd, path); + ok(size == lstrlenA(cwd), "Expected %d, got %d\n", lstrlenA(cwd), size); + + MsiCloseHandle(hpkg); DeleteFile(msifile); } @@ -5572,26 +5707,65 @@ static void test_shortlongsource(void) lstrcatA(subsrc, "long"); lstrcatA(subsrc, "\\"); + /* long file names */ + hdb = create_package_db(); ok( hdb, "failed to create database\n"); + set_suminfo_prop(hdb, PID_WORDCOUNT, 0); + r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); ok(r == S_OK, "failed\n"); r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'"); ok(r == S_OK, "failed\n"); + /* CostInitialize:short */ + r = add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'"); + ok(r == S_OK, "failed\n"); + + /* CostInitialize:long */ + r = add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'"); + ok(r == S_OK, "failed\n"); + + /* FileCost:short */ + r = add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'"); + ok(r == S_OK, "failed\n"); + + /* FileCost:long */ + r = add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'"); + ok(r == S_OK, "failed\n"); + + /* CostFinalize:short */ + r = add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'"); + ok(r == S_OK, "failed\n"); + + /* CostFinalize:long */ + r = add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'"); + ok(r == S_OK, "failed\n"); + + MsiDatabaseCommit(hdb); + hpkg = package_from_db(hdb); ok(hpkg, "failed to create package\n"); MsiCloseHandle(hdb); + CreateDirectoryA("one", NULL); + CreateDirectoryA("four", NULL); + r = MsiDoAction(hpkg, "CostInitialize"); ok(r == ERROR_SUCCESS, "file cost failed\n"); + CreateDirectory("five", NULL); + CreateDirectory("eight", NULL); + r = MsiDoAction(hpkg, "FileCost"); ok(r == ERROR_SUCCESS, "file cost failed\n"); + CreateDirectory("nine", NULL); + CreateDirectory("twelve", NULL); + r = MsiDoAction(hpkg, "CostFinalize"); ok(r == ERROR_SUCCESS, "file cost failed\n"); @@ -5623,9 +5797,231 @@ static void test_shortlongsource(void) ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "two"); + lstrcatA(subsrc, "\\"); + + /* short dir exists before CostInitialize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "four"); + lstrcatA(subsrc, "\\"); + + /* long dir exists before CostInitialize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir3", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "six"); + lstrcatA(subsrc, "\\"); + + /* short dir exists before FileCost */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir4", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "eight"); + lstrcatA(subsrc, "\\"); + + /* long dir exists before FileCost */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir5", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "ten"); + lstrcatA(subsrc, "\\"); + + /* short dir exists before CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir6", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "twelve"); + lstrcatA(subsrc, "\\"); + + /* long dir exists before CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir7", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + MsiCloseHandle(hpkg); + RemoveDirectoryA("short"); + RemoveDirectoryA("long"); + RemoveDirectoryA("one"); + RemoveDirectoryA("four"); + RemoveDirectoryA("five"); + RemoveDirectoryA("eight"); + RemoveDirectoryA("nine"); + RemoveDirectoryA("twelve"); + + /* short file names */ + + r = MsiOpenDatabase(msifile, MSIDBOPEN_DIRECT, &hdb); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + set_suminfo_prop(hdb, PID_WORDCOUNT, msidbSumInfoSourceTypeSFN); + + hpkg = package_from_db(hdb); + ok(hpkg, "failed to create package\n"); + + MsiCloseHandle(hdb); + + CreateDirectoryA("one", NULL); + CreateDirectoryA("four", NULL); + + r = MsiDoAction(hpkg, "CostInitialize"); + ok(r == ERROR_SUCCESS, "file cost failed\n"); + + CreateDirectory("five", NULL); + CreateDirectory("eight", NULL); + + r = MsiDoAction(hpkg, "FileCost"); + ok(r == ERROR_SUCCESS, "file cost failed\n"); + + CreateDirectory("nine", NULL); + CreateDirectory("twelve", NULL); + + r = MsiDoAction(hpkg, "CostFinalize"); + ok(r == ERROR_SUCCESS, "file cost failed\n"); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "short"); + lstrcatA(subsrc, "\\"); + + /* neither short nor long source directories exist */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + CreateDirectoryA("short", NULL); + + /* short source directory exists */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + CreateDirectoryA("long", NULL); + + /* both short and long source directories exist */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "one"); + lstrcatA(subsrc, "\\"); + + /* short dir exists before CostInitialize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir2", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "three"); + lstrcatA(subsrc, "\\"); + + /* long dir exists before CostInitialize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir3", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "five"); + lstrcatA(subsrc, "\\"); + + /* short dir exists before FileCost */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir4", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "seven"); + lstrcatA(subsrc, "\\"); + + /* long dir exists before FileCost */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir5", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "nine"); + lstrcatA(subsrc, "\\"); + + /* short dir exists before CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir6", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + + lstrcpyA(subsrc, cwd); + lstrcatA(subsrc, "eleven"); + lstrcatA(subsrc, "\\"); + + /* long dir exists before CostFinalize */ + size = MAX_PATH; + lstrcpyA(path, "kiwi"); + r = MsiGetSourcePath(hpkg, "SubDir7", path, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpA(path, subsrc), "Expected \"%s\", got \"%s\"\n", subsrc, path); + ok(size == lstrlenA(subsrc), "Expected %d, got %d\n", lstrlenA(subsrc), size); + MsiCloseHandle(hpkg); RemoveDirectoryA("short"); RemoveDirectoryA("long"); + RemoveDirectoryA("one"); + RemoveDirectoryA("four"); + RemoveDirectoryA("five"); + RemoveDirectoryA("eight"); + RemoveDirectoryA("nine"); + RemoveDirectoryA("twelve"); DeleteFileA(msifile); } diff --git a/dlls/mstask/Makefile.in b/dlls/mstask/Makefile.in index 2fd0a66e8e6..2202e227561 100644 --- a/dlls/mstask/Makefile.in +++ b/dlls/mstask/Makefile.in @@ -3,10 +3,14 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mstask.dll -IMPORTS = kernel32 +IMPORTS = uuid kernel32 C_SRCS = \ - mstask_main.c + factory.c \ + mstask_main.c \ + task_scheduler.c + +IDL_I_SRCS = mstask_local.idl @MAKE_DLL_RULES@ diff --git a/dlls/mstask/factory.c b/dlls/mstask/factory.c new file mode 100644 index 00000000000..8906d922359 --- /dev/null +++ b/dlls/mstask/factory.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 Google (Roy Shea) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "mstask_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mstask); + +static HRESULT WINAPI MSTASK_IClassFactory_QueryInterface( + LPCLASSFACTORY iface, + REFIID riid, + LPVOID *ppvObj) +{ + ClassFactoryImpl *This = (ClassFactoryImpl *)iface; + + TRACE("IID: %s\n",debugstr_guid(riid)); + if (ppvObj == NULL) + return E_POINTER; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + *ppvObj = &This->lpVtbl; + IClassFactory_AddRef(iface); + return S_OK; + } + + WARN("Unknown interface: %s\n", debugstr_guid(riid)); + *ppvObj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI MSTASK_IClassFactory_AddRef(LPCLASSFACTORY iface) +{ + TRACE("\n"); + InterlockedIncrement(&dll_ref); + return 2; +} + +static ULONG WINAPI MSTASK_IClassFactory_Release(LPCLASSFACTORY iface) +{ + TRACE("\n"); + InterlockedDecrement(&dll_ref); + return 1; +} + +static HRESULT WINAPI MSTASK_IClassFactory_CreateInstance( + LPCLASSFACTORY iface, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID *ppvObj) +{ + HRESULT res; + IUnknown *punk = NULL; + *ppvObj = NULL; + + TRACE("IID: %s\n",debugstr_guid(riid)); + + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + res = TaskSchedulerConstructor((LPVOID*) &punk); + if (FAILED(res)) + return res; + + res = ITaskScheduler_QueryInterface(punk, riid, ppvObj); + ITaskScheduler_Release(punk); + return res; +} + +static HRESULT WINAPI MSTASK_IClassFactory_LockServer( + LPCLASSFACTORY iface, + BOOL fLock) +{ + TRACE("\n"); + + if (fLock != FALSE) + MSTASK_IClassFactory_AddRef(iface); + else + MSTASK_IClassFactory_Release(iface); + return S_OK; +} + +static const IClassFactoryVtbl IClassFactory_Vtbl = +{ + MSTASK_IClassFactory_QueryInterface, + MSTASK_IClassFactory_AddRef, + MSTASK_IClassFactory_Release, + MSTASK_IClassFactory_CreateInstance, + MSTASK_IClassFactory_LockServer +}; + +ClassFactoryImpl MSTASK_ClassFactory = { &IClassFactory_Vtbl }; diff --git a/dlls/mstask/mstask.spec b/dlls/mstask/mstask.spec index a65cae09d06..24d5af52ccb 100644 --- a/dlls/mstask/mstask.spec +++ b/dlls/mstask/mstask.spec @@ -1,6 +1,6 @@ @ stub ConvertAtJobsToTasks -@ stub DllCanUnloadNow -@ stub DllGetClassObject +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stub GetNetScheduleAccountInformation @ stub NetrJobAdd @ stub NetrJobDel diff --git a/dlls/oleaut32/version.rc b/dlls/mstask/mstask_local.idl similarity index 79% copy from dlls/oleaut32/version.rc copy to dlls/mstask/mstask_local.idl index 5a3f1fffafa..b1a044ab338 100644 --- a/dlls/oleaut32/version.rc +++ b/dlls/mstask/mstask_local.idl @@ -1,5 +1,5 @@ /* - * Copyright 2001 Dmitry Timoshkov + * Copyright (C) 2008 Google (Roy Shea) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,8 +16,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define WINE_OLESELFREGISTER -#define WINE_FILEDESCRIPTION_STR "Wine OLE dll" -#define WINE_FILENAME_STR "oleaut32.dll" - -#include "wine/wine_common_ver.rc" +#include "mstask.idl" diff --git a/dlls/mstask/mstask_main.c b/dlls/mstask/mstask_main.c index c373d663dcd..61e0a99c813 100644 --- a/dlls/mstask/mstask_main.c +++ b/dlls/mstask/mstask_main.c @@ -16,14 +16,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include - -#include "windef.h" -#include "winbase.h" +#include "mstask_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(mstask); +LONG dll_ref = 0; + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); @@ -41,3 +40,20 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) +{ + TRACE("(%s %s %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID(rclsid, &CLSID_CTaskScheduler)) { + return IClassFactory_QueryInterface((LPCLASSFACTORY)&MSTASK_ClassFactory, iid, ppv); + } + + FIXME("Not supported class: %s\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllCanUnloadNow(void) +{ + return dll_ref != 0 ? S_FALSE : S_OK; +} diff --git a/dlls/mstask/mstask_main.c b/dlls/mstask/mstask_private.h similarity index 64% copy from dlls/mstask/mstask_main.c copy to dlls/mstask/mstask_private.h index c373d663dcd..3ddd2b9b4dc 100644 --- a/dlls/mstask/mstask_main.c +++ b/dlls/mstask/mstask_private.h @@ -16,28 +16,33 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifndef __MSTASK_PRIVATE_H__ +#define __MSTASK_PRIVATE_H__ + #include +#define COBJMACROS + #include "windef.h" #include "winbase.h" -#include "wine/debug.h" +#include "winuser.h" +#include "ole2.h" +#include "mstask.h" -WINE_DEFAULT_DEBUG_CHANNEL(mstask); +extern LONG dll_ref; -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +typedef struct { - TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - case DLL_PROCESS_DETACH: - break; - } - - return TRUE; -} + const IClassFactoryVtbl *lpVtbl; + LONG ref; +} ClassFactoryImpl; +extern ClassFactoryImpl MSTASK_ClassFactory; + +typedef struct +{ + const ITaskSchedulerVtbl *lpVtbl; + LONG ref; +} TaskSchedulerImpl; +extern HRESULT TaskSchedulerConstructor(LPVOID *ppObj); + +#endif /* __MSTASK_PRIVATE_H__ */ diff --git a/dlls/mstask/task_scheduler.c b/dlls/mstask/task_scheduler.c new file mode 100644 index 00000000000..a1d52a893d0 --- /dev/null +++ b/dlls/mstask/task_scheduler.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2008 Google (Roy Shea) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "mstask_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mstask); + +static void TaskSchedulerDestructor(TaskSchedulerImpl *This) +{ + TRACE("%p\n", This); + HeapFree(GetProcessHeap(), 0, This); + InterlockedDecrement(&dll_ref); +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_QueryInterface( + ITaskScheduler* iface, + REFIID riid, + void **ppvObject) +{ + TaskSchedulerImpl * This = (TaskSchedulerImpl *)iface; + + TRACE("IID: %s\n", debugstr_guid(riid)); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_ITaskScheduler)) + { + *ppvObject = &This->lpVtbl; + ITaskScheduler_AddRef(iface); + return S_OK; + } + + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI MSTASK_ITaskScheduler_AddRef( + ITaskScheduler* iface) +{ + TaskSchedulerImpl *This = (TaskSchedulerImpl *)iface; + TRACE("\n"); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI MSTASK_ITaskScheduler_Release( + ITaskScheduler* iface) +{ + TaskSchedulerImpl * This = (TaskSchedulerImpl *)iface; + ULONG ref; + TRACE("\n"); + ref = InterlockedDecrement(&This->ref); + if (ref == 0) + TaskSchedulerDestructor(This); + return ref; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_SetTargetComputer( + ITaskScheduler* iface, + LPCWSTR pwszComputer) +{ + FIXME("%p, %s: stub\n", iface, debugstr_w(pwszComputer)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_GetTargetComputer( + ITaskScheduler* iface, + LPWSTR *ppwszComputer) +{ + FIXME("%p, %p: stub\n", iface, ppwszComputer); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_Enum( + ITaskScheduler* iface, + IEnumWorkItems **ppEnumTasks) +{ + FIXME("%p, %p: stub\n", iface, ppEnumTasks); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_Activate( + ITaskScheduler* iface, + LPCWSTR pwszName, + REFIID riid, + IUnknown **ppunk) +{ + FIXME("%p, %s, %s, %p: stub\n", iface, debugstr_w(pwszName), + debugstr_guid(riid), ppunk); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_Delete( + ITaskScheduler* iface, + LPCWSTR pwszName) +{ + FIXME("%p, %s: stub\n", iface, debugstr_w(pwszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_NewWorkItem( + ITaskScheduler* iface, + LPCWSTR pwszTaskName, + REFCLSID rclsid, + REFIID riid, + IUnknown **ppunk) +{ + FIXME("%p, %s, %s, %s, %p: stub\n", iface, debugstr_w(pwszTaskName), + debugstr_guid(rclsid) ,debugstr_guid(riid), ppunk); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_AddWorkItem( + ITaskScheduler* iface, + LPCWSTR pwszTaskName, + IScheduledWorkItem *pWorkItem) +{ + FIXME("%p, %s, %p: stub\n", iface, debugstr_w(pwszTaskName), pWorkItem); + return E_NOTIMPL; +} + +static HRESULT WINAPI MSTASK_ITaskScheduler_IsOfType( + ITaskScheduler* iface, + LPCWSTR pwszName, + REFIID riid) +{ + FIXME("%p, %s, %s: stub\n", iface, debugstr_w(pwszName), + debugstr_guid(riid)); + return E_NOTIMPL; +} + +static const ITaskSchedulerVtbl MSTASK_ITaskSchedulerVtbl = +{ + MSTASK_ITaskScheduler_QueryInterface, + MSTASK_ITaskScheduler_AddRef, + MSTASK_ITaskScheduler_Release, + MSTASK_ITaskScheduler_SetTargetComputer, + MSTASK_ITaskScheduler_GetTargetComputer, + MSTASK_ITaskScheduler_Enum, + MSTASK_ITaskScheduler_Activate, + MSTASK_ITaskScheduler_Delete, + MSTASK_ITaskScheduler_NewWorkItem, + MSTASK_ITaskScheduler_AddWorkItem, + MSTASK_ITaskScheduler_IsOfType +}; + +HRESULT TaskSchedulerConstructor(LPVOID *ppObj) +{ + TaskSchedulerImpl *This; + TRACE("(%p)\n", ppObj); + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->lpVtbl = &MSTASK_ITaskSchedulerVtbl; + This->ref = 1; + + *ppObj = &This->lpVtbl; + InterlockedIncrement(&dll_ref); + return S_OK; +} diff --git a/dlls/msvcrt/data.c b/dlls/msvcrt/data.c index b0f78d5741e..fd8021003c2 100644 --- a/dlls/msvcrt/data.c +++ b/dlls/msvcrt/data.c @@ -29,34 +29,34 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); -int MSVCRT___argc; -unsigned int MSVCRT_basemajor;/* FIXME: */ -unsigned int MSVCRT_baseminor;/* FIXME: */ -unsigned int MSVCRT_baseversion; /* FIXME: */ -unsigned int MSVCRT__commode; -unsigned int MSVCRT__fmode; -unsigned int MSVCRT_osmajor;/* FIXME: */ -unsigned int MSVCRT_osminor;/* FIXME: */ -unsigned int MSVCRT_osmode;/* FIXME: */ -unsigned int MSVCRT__osver; -unsigned int MSVCRT_osversion; /* FIXME: */ -unsigned int MSVCRT__winmajor; -unsigned int MSVCRT__winminor; -unsigned int MSVCRT__winver; -unsigned int MSVCRT___setlc_active; -unsigned int MSVCRT___unguarded_readlc_active; -double MSVCRT__HUGE; -char **MSVCRT___argv; -MSVCRT_wchar_t **MSVCRT___wargv; -char *MSVCRT__acmdln; -MSVCRT_wchar_t *MSVCRT__wcmdln; -char **MSVCRT__environ = 0; -MSVCRT_wchar_t **_wenviron = 0; -char **MSVCRT___initenv = 0; -MSVCRT_wchar_t **MSVCRT___winitenv = 0; -int MSVCRT_app_type; -char* MSVCRT__pgmptr = 0; -WCHAR* MSVCRT__wpgmptr = 0; +int MSVCRT___argc = 0; +unsigned int MSVCRT_basemajor = 0;/* FIXME: */ +unsigned int MSVCRT_baseminor = 0;/* FIXME: */ +unsigned int MSVCRT_baseversion = 0; /* FIXME: */ +unsigned int MSVCRT__commode = 0; +unsigned int MSVCRT__fmode = 0; +unsigned int MSVCRT_osmajor = 0;/* FIXME: */ +unsigned int MSVCRT_osminor = 0;/* FIXME: */ +unsigned int MSVCRT_osmode = 0;/* FIXME: */ +unsigned int MSVCRT__osver = 0; +unsigned int MSVCRT_osversion = 0; /* FIXME: */ +unsigned int MSVCRT__winmajor = 0; +unsigned int MSVCRT__winminor = 0; +unsigned int MSVCRT__winver = 0; +unsigned int MSVCRT___setlc_active = 0; +unsigned int MSVCRT___unguarded_readlc_active = 0; +double MSVCRT__HUGE = 0; +char **MSVCRT___argv = NULL; +MSVCRT_wchar_t **MSVCRT___wargv = NULL; +char *MSVCRT__acmdln = NULL; +MSVCRT_wchar_t *MSVCRT__wcmdln = NULL; +char **MSVCRT__environ = NULL; +MSVCRT_wchar_t **_wenviron = NULL; +char **MSVCRT___initenv = NULL; +MSVCRT_wchar_t **MSVCRT___winitenv = NULL; +int MSVCRT_app_type = 0; +char* MSVCRT__pgmptr = NULL; +WCHAR* MSVCRT__wpgmptr = NULL; /* Get a snapshot of the current environment * and construct the __p__environ array diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index f85afd3c6fa..cd15e4075ce 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -75,7 +75,7 @@ typedef struct { static ioinfo MSVCRT_fdesc[MSVCRT_MAX_FILES]; -MSVCRT_FILE MSVCRT__iob[3]; +MSVCRT_FILE MSVCRT__iob[3] = { { 0 } }; static int MSVCRT_fdstart = 3; /* first unallocated fd */ static int MSVCRT_fdend = 3; /* highest allocated fd */ diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index e679a28b708..644743672c6 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -43,11 +43,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); */ #define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */ #define MAX_LOCALE_LENGTH 256 -char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH]; -LCID MSVCRT_current_lc_all_lcid; -int MSVCRT___lc_codepage; -int MSVCRT___lc_collate_cp; -HANDLE MSVCRT___lc_handle[MSVCRT_LC_MAX - MSVCRT_LC_MIN + 1]; +char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH] = { 0 }; +LCID MSVCRT_current_lc_all_lcid = 0; +int MSVCRT___lc_codepage = 0; +int MSVCRT___lc_collate_cp = 0; +HANDLE MSVCRT___lc_handle[MSVCRT_LC_MAX - MSVCRT_LC_MIN + 1] = { 0 }; /* MT */ #define LOCK_LOCALE _mlock(_SETLOCALE_LOCK); diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 4acc52f0fe7..c99d16727f5 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -30,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); -unsigned char MSVCRT_mbctype[257]; +unsigned char MSVCRT_mbctype[257] = { 0 }; static int g_mbcp_is_multibyte = 0; int MSVCRT___mb_cur_max = 1; diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c index d544fdfdb49..3b67d019f86 100644 --- a/dlls/msxml3/saxreader.c +++ b/dlls/msxml3/saxreader.c @@ -64,8 +64,9 @@ typedef struct _saxlocator xmlParserCtxtPtr pParserCtxt; WCHAR *publicId; WCHAR *systemId; - int lastLine; - int lastColumn; + xmlChar *lastCur; + int line; + int column; } saxlocator; static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface ) @@ -83,6 +84,56 @@ static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface ) return (saxlocator *)((char*)iface - FIELD_OFFSET(saxlocator, lpSAXLocatorVtbl)); } + +static void format_error_message_from_id(saxlocator *This, HRESULT hr) +{ + xmlStopParser(This->pParserCtxt); + This->ret = hr; + + if(This->saxreader->errorHandler) + { + WCHAR msg[1024]; + if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, hr, 0, msg, sizeof(msg), NULL)) + { + FIXME("MSXML errors not yet supported.\n"); + msg[0] = '\0'; + } + + ISAXErrorHandler_fatalError(This->saxreader->errorHandler, + (ISAXLocator*)&This->lpSAXLocatorVtbl, msg, hr); + } +} + +static void update_position(saxlocator *This, xmlChar *end) +{ + if(This->lastCur == NULL) + { + This->lastCur = (xmlChar*)This->pParserCtxt->input->base; + This->line = 1; + This->column = 1; + } + + if(!end) end = (xmlChar*)This->pParserCtxt->input->cur; + + while(This->lastCur < end) + { + if(*(This->lastCur) == '\n') + { + This->line++; + This->column = 1; + } + else if(*(This->lastCur) == '\r' && (This->lastCur==This->pParserCtxt->input->end || *(This->lastCur+1)!='\n')) + { + This->line++; + This->column = 1; + } + else This->column++; + + This->lastCur++; + } +} + /*** LibXML callbacks ***/ static void libxmlStartDocument(void *ctx) { @@ -92,15 +143,11 @@ static void libxmlStartDocument(void *ctx) if(This->saxreader->contentHandler) { hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler); - if(FAILED(hr)) - { - xmlStopParser(This->pParserCtxt); - This->ret = hr; - } + if(hr != S_OK) + format_error_message_from_id(This, hr); } - This->lastColumn = xmlSAX2GetColumnNumber(This->pParserCtxt); - This->lastLine = xmlSAX2GetLineNumber(This->pParserCtxt); + update_position(This, NULL); } static void libxmlEndDocument(void *ctx) @@ -108,17 +155,16 @@ static void libxmlEndDocument(void *ctx) saxlocator *This = ctx; HRESULT hr; - This->lastColumn = 0; - This->lastLine = 0; + This->column = 0; + This->line = 0; + + if(This->ret != S_OK) return; if(This->saxreader->contentHandler) { hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler); - if(FAILED(hr)) - { - xmlStopParser(This->pParserCtxt); - This->ret = hr; - } + if(hr != S_OK) + format_error_message_from_id(This, hr); } } @@ -139,8 +185,7 @@ static void libxmlStartElementNS( FIXME("Arguments processing not yet implemented.\n"); - This->lastColumn = xmlSAX2GetColumnNumber(This->pParserCtxt)+1; - This->lastLine = xmlSAX2GetLineNumber(This->pParserCtxt); + update_position(This, (xmlChar*)This->pParserCtxt->input->cur+1); if(This->saxreader->contentHandler) { @@ -159,11 +204,8 @@ static void libxmlStartElementNS( SysFreeString(LocalName); SysFreeString(QName); - if(FAILED(hr)) - { - xmlStopParser(This->pParserCtxt); - This->ret = hr; - } + if(hr != S_OK) + format_error_message_from_id(This, hr); } } @@ -176,9 +218,11 @@ static void libxmlEndElementNS( BSTR NamespaceUri, LocalName, QName; saxlocator *This = ctx; HRESULT hr; + xmlChar *end; - This->lastColumn = xmlSAX2GetColumnNumber(This->pParserCtxt); - This->lastLine = xmlSAX2GetLineNumber(This->pParserCtxt); + end = This->lastCur; + while(*end != '<' && *(end+1) != '/') end++; + update_position(This, end+2); if(This->saxreader->contentHandler) { @@ -196,11 +240,8 @@ static void libxmlEndElementNS( SysFreeString(LocalName); SysFreeString(QName); - if(FAILED(hr)) - { - xmlStopParser(This->pParserCtxt); - This->ret = hr; - } + if(hr != S_OK) + format_error_message_from_id(This, hr); } } @@ -211,40 +252,73 @@ static void libxmlCharacters( { BSTR Chars; saxlocator *This = ctx; - const xmlChar *cur; - int pos; HRESULT hr; + xmlChar *end; + xmlChar *lastCurCopy; + xmlChar *chEnd; + int columnCopy; + int lineCopy; - This->lastColumn = 1; - This->lastLine = xmlSAX2GetLineNumber(This->pParserCtxt); + if(*(This->lastCur-1) != '>' && *(This->lastCur-1) != '/') return; - cur = This->pParserCtxt->input->cur; - if(*cur != '<') + if(*(This->lastCur-1) != '>') { - for(pos=0; poslastLine--; - cur--; + end = (xmlChar*)This->pParserCtxt->input->cur-len; + while(*(end-1) != '>') end--; + update_position(This, end); } - else - { - for(pos=0; poslastLine--; - cur = cur-len-1; - } - for(; *cur!='\n' && cur!=This->pParserCtxt->input->base; cur--) - This->lastColumn++; + + chEnd = This->lastCur+len; + while(*chEnd != '<') chEnd++; + + Chars = bstr_from_xmlChar(ch); + + lastCurCopy = This->lastCur; + columnCopy = This->column; + lineCopy = This->line; + end = This->lastCur; if(This->saxreader->contentHandler) { - Chars = bstr_from_xmlChar(ch); - hr = ISAXContentHandler_characters(This->saxreader->contentHandler, Chars, len); - SysFreeString(Chars); - - if(FAILED(hr)) + while(This->lastCur < chEnd) { - xmlStopParser(This->pParserCtxt); - This->ret = hr; + end = This->lastCur; + while(end < chEnd-1) + { + if(*end == '\r') break; + end++; + } + + Chars = bstr_from_xmlChar(This->lastCur); + + if(*end == '\r' && *(end+1) == '\n') + { + memmove((WCHAR*)Chars+(end-This->lastCur), + (WCHAR*)Chars+(end-This->lastCur)+1, + (SysStringLen(Chars)-(end-This->lastCur))*sizeof(WCHAR)); + SysReAllocStringLen(&Chars, Chars, SysStringLen(Chars)-1); + } + else if(*end == '\r') Chars[end-This->lastCur] = '\n'; + + hr = ISAXContentHandler_characters(This->saxreader->contentHandler, Chars, end-This->lastCur+1); + SysFreeString(Chars); + if(hr != S_OK) + { + format_error_message_from_id(This, hr); + return; + } + + if(*(end+1) == '\n') end++; + if(end < chEnd) end++; + + This->column += end-This->lastCur; + This->lastCur = end; } + + This->lastCur = lastCurCopy; + This->column = columnCopy; + This->line = lineCopy; + update_position(This, chEnd); } } @@ -259,10 +333,41 @@ static void libxmlSetDocumentLocator( (ISAXLocator*)&This->lpSAXLocatorVtbl); if(FAILED(hr)) + format_error_message_from_id(This, hr); +} + +void libxmlFatalError(void *ctx, const char *msg, ...) +{ + saxlocator *This = ctx; + char message[1024]; + WCHAR *wszError; + DWORD len; + va_list args; + + if(!This->saxreader->errorHandler) { xmlStopParser(This->pParserCtxt); - This->ret = hr; + This->ret = E_FAIL; + return; } + + FIXME("Error handling is not compatible.\n"); + + va_start(args, msg); + vsprintf(message, msg, args); + va_end(args); + + len = MultiByteToWideChar(CP_ACP, 0, message, -1, NULL, 0); + wszError = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len); + MultiByteToWideChar(CP_ACP, 0, message, -1, (LPWSTR)wszError, len); + + ISAXErrorHandler_fatalError(This->saxreader->errorHandler, + (ISAXLocator*)&This->lpSAXLocatorVtbl, wszError, E_FAIL); + + HeapFree(GetProcessHeap(), 0, wszError); + + xmlStopParser(This->pParserCtxt); + This->ret = E_FAIL; } /*** ISAXLocator interface ***/ @@ -328,7 +433,7 @@ static HRESULT WINAPI isaxlocator_getColumnNumber( { saxlocator *This = impl_from_ISAXLocator( iface ); - *pnColumn = This->lastColumn; + *pnColumn = This->column; return S_OK; } @@ -338,7 +443,7 @@ static HRESULT WINAPI isaxlocator_getLineNumber( { saxlocator *This = impl_from_ISAXLocator( iface ); - *pnLine = This->lastLine; + *pnLine = This->line; return S_OK; } @@ -414,8 +519,9 @@ static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator) locator->pParserCtxt = NULL; locator->publicId = NULL; locator->systemId = NULL; - locator->lastLine = 0; - locator->lastColumn = 0; + locator->lastCur = NULL; + locator->line = 0; + locator->column = 0; locator->ret = S_OK; *ppsaxlocator = locator; @@ -1001,33 +1107,110 @@ static HRESULT WINAPI isaxxmlreader_parse( xmlChar *data = NULL; HRESULT hr; - FIXME("(%p) semi-stub\n", This); + TRACE("(%p)\n", This); hr = SAXLocator_create(This, &locator); if(FAILED(hr)) return E_FAIL; + locator->pParserCtxt = xmlNewParserCtxt(); + if(!locator->pParserCtxt) + { + ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl); + return E_FAIL; + } + + locator->pParserCtxt->sax = &locator->saxreader->sax; + locator->pParserCtxt->userData = locator; + hr = S_OK; switch(V_VT(&varInput)) { case VT_BSTR: - locator->pParserCtxt = xmlNewParserCtxt(); - if(!locator->pParserCtxt) + data = xmlChar_from_wchar(V_BSTR(&varInput)); + xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL); + break; + case VT_ARRAY|VT_UI1: { + void *pSAData; + LONG lBound, uBound; + ULONG dataRead; + + hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound); + if(hr != S_OK) break; + hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound); + if(hr != S_OK) break; + dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput)); + data = HeapAlloc(GetProcessHeap(), 0, dataRead+1); + if(!data) break; + hr = SafeArrayAccessData(V_ARRAY(&varInput), (void**)&pSAData); + if(hr != S_OK) break; + memcpy(data, pSAData, dataRead); + data[dataRead] = '\0'; + xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL); + SafeArrayUnaccessData(V_ARRAY(&varInput)); + break; + } + case VT_UNKNOWN: + case VT_DISPATCH: { + IPersistStream *persistStream; + IStream *stream = NULL; + IXMLDOMDocument *xmlDoc; + + if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IPersistStream, (void**)&persistStream) == S_OK) { - hr = E_FAIL; + hr = IPersistStream_Save(persistStream, stream, TRUE); + IPersistStream_Release(persistStream); + if(hr != S_OK) break; + } + if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IStream, (void**)&stream) == S_OK) + { + STATSTG dataInfo; + ULONG dataRead; + + while(1) + { + hr = IStream_Stat(stream, &dataInfo, STATFLAG_NONAME); + if(hr == E_PENDING) continue; + break; + } + data = HeapAlloc(GetProcessHeap(), 0, + dataInfo.cbSize.QuadPart+1); + while(1) + { + hr = IStream_Read(stream, data, + dataInfo.cbSize.QuadPart, &dataRead); + if(hr == E_PENDING) continue; + break; + } + data[dataInfo.cbSize.QuadPart] = '\0'; + xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL); + IStream_Release(stream); break; } - data = xmlChar_from_wchar(V_BSTR(&varInput)); - xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL); - - locator->pParserCtxt->sax = &locator->saxreader->sax; - locator->pParserCtxt->userData = locator; + if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) + { + BSTR bstrData; - if(xmlParseDocument(locator->pParserCtxt)) hr = E_FAIL; - else hr = locator->ret; - break; + IXMLDOMDocument_get_xml(xmlDoc, &bstrData); + data = xmlChar_from_wchar(bstrData); + xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL); + IXMLDOMDocument_Release(xmlDoc); + hr = E_NOTIMPL; + break; + } + } default: - hr = E_NOTIMPL; + WARN("vt %d not implemented\n", V_VT(&varInput)); + hr = E_INVALIDARG; + } + + if(hr == S_OK) + { + if(xmlParseDocument(locator->pParserCtxt)) hr = E_FAIL; + else hr = locator->ret; } if(locator->pParserCtxt) @@ -1100,6 +1283,8 @@ HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj) reader->sax.endElementNs = libxmlEndElementNS; reader->sax.characters = libxmlCharacters; reader->sax.setDocumentLocator = libxmlSetDocumentLocator; + reader->sax.error = libxmlFatalError; + reader->sax.fatalError = libxmlFatalError; *ppObj = &reader->lpVtbl; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 7c64f6cd76d..1a2f85ca6a2 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -1157,7 +1157,7 @@ todo_wine if (list) { r = IXMLDOMNodeList_QueryInterface(list, &IID_IDispatch, NULL); - ok( r == E_INVALIDARG, "ret %08x\n", r ); + ok( r == E_INVALIDARG || r == E_POINTER, "ret %08x\n", r ); r = IXMLDOMNodeList_get_item(list, 0, NULL); ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r); @@ -1597,8 +1597,11 @@ static void test_get_text(void) ok( r == S_OK, "ret %08x\n", r ); SysFreeString(str); + if (0) { + /* this test crashes on win9x */ r = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatch, NULL); ok( r == E_INVALIDARG, "ret %08x\n", r ); + } r = IXMLDOMNodeList_get_length( node_list, NULL ); ok( r == E_INVALIDARG, "ret %08x\n", r ); diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 5547d72bfa3..dd69e0f376e 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -52,6 +52,21 @@ static const WCHAR szSimpleXML[] = { '<','/','B','a','n','k','A','c','c','o','u','n','t','>','\n','\0' }; +static const WCHAR szCarriageRetTest[] = { +'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>','\r','\n', +'<','B','a','n','k','A','c','c','o','u','n','t','>','\r','\n', +'\t','<','N','u','m','b','e','r','>','1','2','3','4','<','/','N','u','m','b','e','r','>','\r','\n', +'\t','<','N','a','m','e','>','C','a','p','t','a','i','n',' ','A','h','a','b','<','/','N','a','m','e','>','\r','\n', +'<','/','B','a','n','k','A','c','c','o','u','n','t','>','\0' +}; + +static const CHAR szTestXML[] = +"\n" +"\n" +" 1234\n" +" Captain Ahab\n" +"\n"; + typedef struct _contenthandlercheck { CH id; int line; @@ -79,6 +94,26 @@ static content_handler_test contentHandlerTest1[] = { { CH_ENDTEST } }; +static content_handler_test contentHandlerTest2[] = { + { CH_PUTDOCUMENTLOCATOR, 0, 0 }, + { CH_STARTDOCUMENT, 0, 0 }, + { CH_STARTELEMENT, 2, 14, "", "BankAccount", "BankAccount" }, + { CH_CHARACTERS, 2, 14, "\n" }, + { CH_CHARACTERS, 2, 16, "\t" }, + { CH_STARTELEMENT, 3, 10, "", "Number", "Number" }, + { CH_CHARACTERS, 3, 10, "1234" }, + { CH_ENDELEMENT, 3, 16, "", "Number", "Number" }, + { CH_CHARACTERS, 3, 23, "\n" }, + { CH_CHARACTERS, 3, 25, "\t" }, + { CH_STARTELEMENT, 4, 8, "", "Name", "Name" }, + { CH_CHARACTERS, 4, 8, "Captain Ahab" }, + { CH_ENDELEMENT, 4, 22, "", "Name", "Name" }, + { CH_CHARACTERS, 4, 27, "\n" }, + { CH_ENDELEMENT, 5, 3, "", "BankAccount", "BankAccount" }, + { CH_ENDDOCUMENT, 0, 0 }, + { CH_ENDTEST } +}; + static content_handler_test *expectCall; static ISAXLocator *locator; @@ -125,7 +160,7 @@ static void test_locator(unsigned line, int loc_line, int loc_column) ok_(__FILE__,line) (rline == loc_line, "unexpected line %d, expected %d\n", rline, loc_line); ok_(__FILE__,line) (rcolumn == loc_column, - "unexpected columnt %d, expected %d\n", rcolumn, loc_column); + "unexpected column %d, expected %d\n", rcolumn, loc_column); } static HRESULT WINAPI contentHandler_QueryInterface( @@ -357,6 +392,75 @@ static const ISAXContentHandlerVtbl contentHandlerVtbl = static ISAXContentHandler contentHandler = { &contentHandlerVtbl }; +static HRESULT WINAPI isaxerrorHandler_QueryInterface( + ISAXErrorHandler* iface, + REFIID riid, + void **ppvObject) +{ + *ppvObject = NULL; + + if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ISAXErrorHandler)) + { + *ppvObject = iface; + } + else + { + return E_NOINTERFACE; + } + + return S_OK; +} + +static ULONG WINAPI isaxerrorHandler_AddRef( + ISAXErrorHandler* iface) +{ + return 2; +} + +static ULONG WINAPI isaxerrorHandler_Release( + ISAXErrorHandler* iface) +{ + return 1; +} + +static HRESULT WINAPI isaxerrorHandler_error( + ISAXErrorHandler* iface, + ISAXLocator *pLocator, + const WCHAR *pErrorMessage, + HRESULT hrErrorCode) +{ + return S_OK; +} + +static HRESULT WINAPI isaxerrorHandler_fatalError( + ISAXErrorHandler* iface, + ISAXLocator *pLocator, + const WCHAR *pErrorMessage, + HRESULT hrErrorCode) +{ + return S_OK; +} + +static HRESULT WINAPI isaxerrorHanddler_ignorableWarning( + ISAXErrorHandler* iface, + ISAXLocator *pLocator, + const WCHAR *pErrorMessage, + HRESULT hrErrorCode) +{ + return S_OK; +} + +static const ISAXErrorHandlerVtbl errorHandlerVtbl = +{ + isaxerrorHandler_QueryInterface, + isaxerrorHandler_AddRef, + isaxerrorHandler_Release, + isaxerrorHandler_error, + isaxerrorHandler_fatalError, + isaxerrorHanddler_ignorableWarning +}; + +static ISAXErrorHandler errorHandler = { &errorHandlerVtbl }; static void test_saxreader(void) { @@ -364,6 +468,14 @@ static void test_saxreader(void) ISAXXMLReader *reader = NULL; VARIANT var; ISAXContentHandler *lpContentHandler; + ISAXErrorHandler *lpErrorHandler; + SAFEARRAY *pSA; + SAFEARRAYBOUND SADim[1]; + char *pSAData = NULL; + IStream *iStream; + ULARGE_INTEGER liSize; + LARGE_INTEGER liPos; + ULONG bytesWritten; hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (LPVOID*)&reader); @@ -377,16 +489,26 @@ static void test_saxreader(void) hr = ISAXXMLReader_getContentHandler(reader, NULL); ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr); + hr = ISAXXMLReader_getErrorHandler(reader, NULL); + ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr); + hr = ISAXXMLReader_getContentHandler(reader, &lpContentHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(lpContentHandler == NULL, "Expected %p, got %p\n", NULL, lpContentHandler); + hr = ISAXXMLReader_getErrorHandler(reader, &lpErrorHandler); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(lpErrorHandler == NULL, "Expected %p, got %p\n", NULL, lpErrorHandler); + hr = ISAXXMLReader_putContentHandler(reader, NULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = ISAXXMLReader_putContentHandler(reader, &contentHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + hr = ISAXXMLReader_putErrorHandler(reader, &errorHandler); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + hr = ISAXXMLReader_getContentHandler(reader, &lpContentHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(lpContentHandler == &contentHandler, "Expected %p, got %p\n", &contentHandler, lpContentHandler); @@ -399,6 +521,46 @@ static void test_saxreader(void) ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); + SADim[0].lLbound= 0; + SADim[0].cElements= sizeof(szTestXML)-1; + pSA = SafeArrayCreate(VT_UI1, 1, SADim); + SafeArrayAccessData(pSA, (void**)&pSAData); + memcpy(pSAData, szTestXML, sizeof(szTestXML)-1); + SafeArrayUnaccessData(pSA); + V_VT(&var) = VT_ARRAY|VT_UI1; + V_ARRAY(&var) = pSA; + + expectCall = contentHandlerTest1; + hr = ISAXXMLReader_parse(reader, var); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + test_expect_call(CH_ENDTEST); + + SafeArrayDestroy(pSA); + + CreateStreamOnHGlobal(NULL, TRUE, &iStream); + liSize.QuadPart = strlen(szTestXML); + IStream_SetSize(iStream, liSize); + IStream_Write(iStream, (void const*)szTestXML, strlen(szTestXML), &bytesWritten); + liPos.QuadPart = 0; + IStream_Seek(iStream, liPos, STREAM_SEEK_SET, NULL); + V_VT(&var) = VT_UNKNOWN|VT_DISPATCH; + V_UNKNOWN(&var) = (IUnknown*)iStream; + + expectCall = contentHandlerTest1; + hr = ISAXXMLReader_parse(reader, var); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + test_expect_call(CH_ENDTEST); + + IStream_Release(iStream); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(szCarriageRetTest); + + expectCall = contentHandlerTest2; + hr = ISAXXMLReader_parse(reader, var); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + test_expect_call(CH_ENDTEST); + ISAXXMLReader_Release(reader); } diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index cc31dcca0f8..039a3cfb078 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -194,13 +194,39 @@ static inline void notify_alloc( void *ptr, SIZE_T size, BOOL init ) } /* notify that a block of memory has been freed for debugging purposes */ -static inline void notify_free( void *ptr ) +static inline void notify_free( void const *ptr ) { #ifdef VALGRIND_FREELIKE_BLOCK VALGRIND_FREELIKE_BLOCK( ptr, 0 ); #endif } +static void subheap_notify_free_all(SUBHEAP const *subheap) +{ +#ifdef VALGRIND_FREELIKE_BLOCK + char const *ptr = (char const *)subheap->base + subheap->headerSize; + + if (!RUNNING_ON_VALGRIND) return; + + while (ptr < (char const *)subheap->base + subheap->size) + { + if (*(const DWORD *)ptr & ARENA_FLAG_FREE) + { + ARENA_FREE const *pArena = (ARENA_FREE const *)ptr; + if (pArena->magic!=ARENA_FREE_MAGIC) ERR("bad free_magic @%p\n", pArena); + ptr += sizeof(*pArena) + (pArena->size & ARENA_SIZE_MASK); + } + else + { + ARENA_INUSE const *pArena = (ARENA_INUSE const *)ptr; + if (pArena->magic!=ARENA_INUSE_MAGIC) ERR("bad inuse_magic @%p\n", pArena); + notify_free(pArena + 1); + ptr += sizeof(*pArena) + (pArena->size & ARENA_SIZE_MASK); + } + } +#endif +} + /* locate a free list entry of the appropriate size */ /* size is the size of the whole block including the arena header */ static inline unsigned int get_freelist_index( SIZE_T size ) @@ -1151,11 +1177,13 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap ) LIST_FOR_EACH_ENTRY_SAFE( subheap, next, &heapPtr->subheap_list, SUBHEAP, entry ) { if (subheap == &heapPtr->subheap) continue; /* do this one last */ + subheap_notify_free_all(subheap); list_remove( &subheap->entry ); size = 0; addr = subheap->base; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); } + subheap_notify_free_all(&heapPtr->subheap); size = 0; addr = heapPtr->subheap.base; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 575f99da373..e18f3a37ff5 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -488,8 +488,8 @@ @ stdcall RtlCreateSecurityDescriptor(ptr long) # @ stub RtlCreateSystemVolumeInformationFolder @ stub RtlCreateTagHeap -# @ stub RtlCreateTimer -# @ stub RtlCreateTimerQueue +@ stdcall RtlCreateTimer(ptr ptr ptr ptr long long long) +@ stdcall RtlCreateTimerQueue(ptr) @ stdcall RtlCreateUnicodeString(ptr wstr) @ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str) @ stub RtlCreateUserProcess @@ -518,9 +518,9 @@ @ stdcall RtlDeleteRegistryValue(long ptr ptr) @ stdcall RtlDeleteResource(ptr) @ stdcall RtlDeleteSecurityObject(ptr) -# @ stub RtlDeleteTimer +@ stdcall RtlDeleteTimer(ptr ptr ptr) # @ stub RtlDeleteTimerQueue -# @ stub RtlDeleteTimerQueueEx +@ stdcall RtlDeleteTimerQueueEx(ptr ptr) @ stdcall RtlDeregisterWait(ptr) @ stdcall RtlDeregisterWaitEx(ptr ptr) @ stdcall RtlDestroyAtomTable(ptr) @@ -895,7 +895,7 @@ @ stub RtlUpcaseUnicodeToCustomCPN @ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long) @ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) -# @ stub RtlUpdateTimer +@ stdcall RtlUpdateTimer(ptr ptr long long) @ stdcall RtlUpperChar(long) @ stdcall RtlUpperString(ptr ptr) @ stub RtlUsageHeap diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c index ebfa6fb19fa..604154cc7c1 100644 --- a/dlls/ntdll/string.c +++ b/dlls/ntdll/string.c @@ -465,24 +465,6 @@ ULONG __cdecl NTDLL_strtoul( const char *nptr, char **endptr, int base ) /********************************************************************* - * atoi (NTDLL.@) - */ -int __cdecl NTDLL_atoi( const char *nptr ) -{ - return atoi( nptr ); -} - - -/********************************************************************* - * atol (NTDLL.@) - */ -LONG __cdecl NTDLL_atol( const char *nptr ) -{ - return atol( nptr ); -} - - -/********************************************************************* * _ultoa (NTDLL.@) * * Convert an unsigned long integer to a string. @@ -727,7 +709,7 @@ char * __cdecl _i64toa( * - No check is made for value overflow, only the lower 64 bits are assigned. * - If str is NULL it crashes, as the native function does. */ -LONGLONG __cdecl _atoi64( char *str ) +LONGLONG __cdecl _atoi64( const char *str ) { ULONGLONG RunningTotal = 0; char bMinus = 0; @@ -753,6 +735,24 @@ LONGLONG __cdecl _atoi64( char *str ) /********************************************************************* + * atoi (NTDLL.@) + */ +int __cdecl NTDLL_atoi( const char *nptr ) +{ + return _atoi64( nptr ); +} + + +/********************************************************************* + * atol (NTDLL.@) + */ +LONG __cdecl NTDLL_atol( const char *nptr ) +{ + return _atoi64( nptr ); +} + + +/********************************************************************* * sprintf (NTDLL.@) */ int __cdecl NTDLL_sprintf( char *str, const char *format, ... ) diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c index e9bf5e10704..40a39a46a1e 100644 --- a/dlls/ntdll/tests/string.c +++ b/dlls/ntdll/tests/string.c @@ -893,6 +893,31 @@ static void test_wtoi(void) } /* for */ } +static void test_atoi(void) +{ + int test_num; + int result; + + for (test_num = 0; test_num < NB_STR2LONG; test_num++) { + result = patoi(str2long[test_num].str); + ok(result == str2long[test_num].value, + "(test %d): call failed: _atoi(\"%s\") has result %d, expected: %d\n", + test_num, str2long[test_num].str, result, str2long[test_num].value); + } +} + +static void test_atol(void) +{ + int test_num; + int result; + + for (test_num = 0; test_num < NB_STR2LONG; test_num++) { + result = patol(str2long[test_num].str); + ok(result == str2long[test_num].value, + "(test %d): call failed: _atol(\"%s\") has result %d, expected: %d\n", + test_num, str2long[test_num].str, result, str2long[test_num].value); + } +} static void test_wtol(void) { @@ -1095,4 +1120,8 @@ START_TEST(string) test_wtoi64(); if (p_wcschr && p_wcsrchr) test_wcsfuncs(); + if (patoi) + test_atoi(); + if (patol) + test_atol(); } diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c index e0541368b12..a60adfa6573 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c @@ -21,6 +21,7 @@ #include "config.h" #include "wine/port.h" +#include #include #include @@ -528,3 +529,469 @@ NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle) { return RtlDeregisterWaitEx(WaitHandle, NULL); } + + +/************************** Timer Queue Impl **************************/ + +struct timer_queue; +struct queue_timer +{ + struct timer_queue *q; + struct list entry; + ULONG runcount; /* number of callbacks pending execution */ + RTL_WAITORTIMERCALLBACKFUNC callback; + PVOID param; + DWORD period; + ULONG flags; + ULONGLONG expire; + BOOL destroy; /* timer should be deleted; once set, never unset */ + HANDLE event; /* removal event */ +}; + +struct timer_queue +{ + RTL_CRITICAL_SECTION cs; + struct list timers; /* sorted by expiration time */ + BOOL quit; /* queue should be deleted; once set, never unset */ + HANDLE event; + HANDLE thread; +}; + +#define EXPIRE_NEVER (~(ULONGLONG) 0) + +static void queue_remove_timer(struct queue_timer *t) +{ + /* We MUST hold the queue cs while calling this function. This ensures + that we cannot queue another callback for this timer. The runcount + being zero makes sure we don't have any already queued. */ + struct timer_queue *q = t->q; + + assert(t->runcount == 0); + assert(t->destroy); + + list_remove(&t->entry); + if (t->event) + NtSetEvent(t->event, NULL); + RtlFreeHeap(GetProcessHeap(), 0, t); + + if (q->quit && list_count(&q->timers) == 0) + NtSetEvent(q->event, NULL); +} + +static void timer_cleanup_callback(struct queue_timer *t) +{ + struct timer_queue *q = t->q; + RtlEnterCriticalSection(&q->cs); + + assert(0 < t->runcount); + --t->runcount; + + if (t->destroy && t->runcount == 0) + queue_remove_timer(t); + + RtlLeaveCriticalSection(&q->cs); +} + +static DWORD WINAPI timer_callback_wrapper(LPVOID p) +{ + struct queue_timer *t = p; + t->callback(t->param, TRUE); + timer_cleanup_callback(t); + return 0; +} + +static inline ULONGLONG queue_current_time(void) +{ + LARGE_INTEGER now; + NtQuerySystemTime(&now); + return now.QuadPart / 10000; +} + +static void queue_add_timer(struct queue_timer *t, ULONGLONG time, + BOOL set_event) +{ + /* We MUST hold the queue cs while calling this function. */ + struct timer_queue *q = t->q; + struct list *ptr = &q->timers; + + assert(!q->quit || (t->destroy && time == EXPIRE_NEVER)); + + if (time != EXPIRE_NEVER) + LIST_FOR_EACH(ptr, &q->timers) + { + struct queue_timer *cur = LIST_ENTRY(ptr, struct queue_timer, entry); + if (time < cur->expire) + break; + } + list_add_before(ptr, &t->entry); + + t->expire = time; + + /* If we insert at the head of the list, we need to expire sooner + than expected. */ + if (set_event && &t->entry == list_head(&q->timers)) + NtSetEvent(q->event, NULL); +} + +static inline void queue_move_timer(struct queue_timer *t, ULONGLONG time, + BOOL set_event) +{ + /* We MUST hold the queue cs while calling this function. */ + list_remove(&t->entry); + queue_add_timer(t, time, set_event); +} + +static void queue_timer_expire(struct timer_queue *q) +{ + struct queue_timer *t; + + RtlEnterCriticalSection(&q->cs); + if (list_head(&q->timers)) + { + t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry); + if (!t->destroy && t->expire <= queue_current_time()) + { + ++t->runcount; + queue_move_timer( + t, t->period ? queue_current_time() + t->period : EXPIRE_NEVER, + FALSE); + } + } + else + t = NULL; + RtlLeaveCriticalSection(&q->cs); + + if (t) + { + if (t->flags & WT_EXECUTEINTIMERTHREAD) + timer_callback_wrapper(t); + else + { + ULONG flags + = (t->flags + & (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD + | WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION)); + NTSTATUS status = RtlQueueWorkItem(timer_callback_wrapper, t, flags); + if (status != STATUS_SUCCESS) + timer_cleanup_callback(t); + } + } +} + +static ULONG queue_get_timeout(struct timer_queue *q) +{ + struct queue_timer *t; + ULONG timeout = INFINITE; + + RtlEnterCriticalSection(&q->cs); + if (list_head(&q->timers)) + { + t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry); + assert(!t->destroy || t->expire == EXPIRE_NEVER); + + if (t->expire != EXPIRE_NEVER) + { + ULONGLONG time = queue_current_time(); + timeout = t->expire < time ? 0 : t->expire - time; + } + } + RtlLeaveCriticalSection(&q->cs); + + return timeout; +} + +static void WINAPI timer_queue_thread_proc(LPVOID p) +{ + struct timer_queue *q = p; + ULONG timeout_ms; + + timeout_ms = INFINITE; + for (;;) + { + LARGE_INTEGER timeout; + NTSTATUS status; + BOOL done = FALSE; + + status = NtWaitForSingleObject( + q->event, FALSE, get_nt_timeout(&timeout, timeout_ms)); + + if (status == STATUS_WAIT_0) + { + /* There are two possible ways to trigger the event. Either + we are quitting and the last timer got removed, or a new + timer got put at the head of the list so we need to adjust + our timeout. */ + RtlEnterCriticalSection(&q->cs); + if (q->quit && list_count(&q->timers) == 0) + done = TRUE; + RtlLeaveCriticalSection(&q->cs); + } + else if (status == STATUS_TIMEOUT) + queue_timer_expire(q); + + if (done) + break; + + timeout_ms = queue_get_timeout(q); + } + + NtClose(q->event); + RtlDeleteCriticalSection(&q->cs); + RtlFreeHeap(GetProcessHeap(), 0, q); +} + +static void queue_destroy_timer(struct queue_timer *t) +{ + /* We MUST hold the queue cs while calling this function. */ + t->destroy = TRUE; + if (t->runcount == 0) + /* Ensure a timer is promptly removed. If callbacks are pending, + it will be removed after the last one finishes by the callback + cleanup wrapper. */ + queue_remove_timer(t); + else + /* Make sure no destroyed timer masks an active timer at the head + of the sorted list. */ + queue_move_timer(t, EXPIRE_NEVER, FALSE); +} + +/*********************************************************************** + * RtlCreateTimerQueue (NTDLL.@) + * + * Creates a timer queue object and returns a handle to it. + * + * PARAMS + * NewTimerQueue [O] The newly created queue. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue) +{ + NTSTATUS status; + struct timer_queue *q = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *q); + if (!q) + return STATUS_NO_MEMORY; + + RtlInitializeCriticalSection(&q->cs); + list_init(&q->timers); + q->quit = FALSE; + status = NtCreateEvent(&q->event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE); + if (status != STATUS_SUCCESS) + { + RtlFreeHeap(GetProcessHeap(), 0, q); + return status; + } + status = RtlCreateUserThread(GetCurrentProcess(), NULL, FALSE, NULL, 0, 0, + timer_queue_thread_proc, q, &q->thread, NULL); + if (status != STATUS_SUCCESS) + { + NtClose(q->event); + RtlFreeHeap(GetProcessHeap(), 0, q); + return status; + } + + *NewTimerQueue = q; + return STATUS_SUCCESS; +} + +/*********************************************************************** + * RtlDeleteTimerQueueEx (NTDLL.@) + * + * Deletes a timer queue object. + * + * PARAMS + * TimerQueue [I] The timer queue to destroy. + * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE, + * wait until all timers are finished firing before + * returning. Otherwise, return immediately and set the + * event when all timers are done. + * + * RETURNS + * Success: STATUS_SUCCESS if synchronous, STATUS_PENDING if not. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent) +{ + struct timer_queue *q = TimerQueue; + struct queue_timer *t, *temp; + HANDLE thread = q->thread; + NTSTATUS status; + + RtlEnterCriticalSection(&q->cs); + q->quit = TRUE; + if (list_head(&q->timers)) + /* When the last timer is removed, it will signal the timer thread to + exit... */ + LIST_FOR_EACH_ENTRY_SAFE(t, temp, &q->timers, struct queue_timer, entry) + queue_destroy_timer(t); + else + /* However if we have none, we must do it ourselves. */ + NtSetEvent(q->event, NULL); + RtlLeaveCriticalSection(&q->cs); + + if (CompletionEvent == INVALID_HANDLE_VALUE) + { + NtWaitForSingleObject(thread, FALSE, NULL); + status = STATUS_SUCCESS; + } + else + { + if (CompletionEvent) + { + FIXME("asynchronous return on completion event unimplemented\n"); + NtWaitForSingleObject(thread, FALSE, NULL); + NtSetEvent(CompletionEvent, NULL); + } + status = STATUS_PENDING; + } + + NtClose(thread); + return status; +} + +/*********************************************************************** + * RtlCreateTimer (NTDLL.@) + * + * Creates a new timer associated with the given queue. + * + * PARAMS + * NewTimer [O] The newly created timer. + * TimerQueue [I] The queue to hold the timer. + * Callback [I] The callback to fire. + * Parameter [I] The argument for the callback. + * DueTime [I] The delay, in milliseconds, before first firing the + * timer. + * Period [I] The period, in milliseconds, at which to fire the timer + * after the first callback. If zero, the timer will only + * fire once. It still needs to be deleted with + * RtlDeleteTimer. + * Flags [I] Flags controling the execution of the callback. In + * addition to the WT_* thread pool flags (see + * RtlQueueWorkItem), WT_EXECUTEINTIMERTHREAD and + * WT_EXECUTEONLYONCE are supported. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue, + RTL_WAITORTIMERCALLBACKFUNC Callback, + PVOID Parameter, DWORD DueTime, DWORD Period, + ULONG Flags) +{ + NTSTATUS status; + struct timer_queue *q = TimerQueue; + struct queue_timer *t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t); + if (!t) + return STATUS_NO_MEMORY; + + t->q = q; + t->runcount = 0; + t->callback = Callback; + t->param = Parameter; + t->period = Period; + t->flags = Flags; + t->destroy = FALSE; + t->event = NULL; + + status = STATUS_SUCCESS; + RtlEnterCriticalSection(&q->cs); + if (q->quit) + status = STATUS_INVALID_HANDLE; + else + queue_add_timer(t, queue_current_time() + DueTime, TRUE); + RtlLeaveCriticalSection(&q->cs); + + if (status == STATUS_SUCCESS) + *NewTimer = t; + else + RtlFreeHeap(GetProcessHeap(), 0, t); + + return status; +} + +/*********************************************************************** + * RtlUpdateTimer (NTDLL.@) + * + * Changes the time at which a timer expires. + * + * PARAMS + * TimerQueue [I] The queue that holds the timer. + * Timer [I] The timer to update. + * DueTime [I] The delay, in milliseconds, before next firing the timer. + * Period [I] The period, in milliseconds, at which to fire the timer + * after the first callback. If zero, the timer will not + * refire once. It still needs to be deleted with + * RtlDeleteTimer. + * + * RETURNS + * Success: STATUS_SUCCESS. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer, + DWORD DueTime, DWORD Period) +{ + struct timer_queue *q = TimerQueue; + struct queue_timer *t = Timer; + + RtlEnterCriticalSection(&q->cs); + /* Can't change a timer if it was once-only or destroyed. */ + if (t->expire != EXPIRE_NEVER) + { + t->period = Period; + queue_move_timer(t, queue_current_time() + DueTime, TRUE); + } + RtlLeaveCriticalSection(&q->cs); + + return STATUS_SUCCESS; +} + +/*********************************************************************** + * RtlDeleteTimer (NTDLL.@) + * + * Cancels a timer-queue timer. + * + * PARAMS + * TimerQueue [I] The queue that holds the timer. + * Timer [I] The timer to update. + * CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE, + * wait until the timer is finished firing all pending + * callbacks before returning. Otherwise, return + * immediately and set the timer is done. + * + * RETURNS + * Success: STATUS_SUCCESS if the timer is done, STATUS_PENDING if not, + or if the completion event is NULL. + * Failure: Any NTSTATUS code. + */ +NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, + HANDLE CompletionEvent) +{ + struct timer_queue *q = TimerQueue; + struct queue_timer *t = Timer; + NTSTATUS status = STATUS_PENDING; + HANDLE event = NULL; + + if (CompletionEvent == INVALID_HANDLE_VALUE) + status = NtCreateEvent(&event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE); + else if (CompletionEvent) + event = CompletionEvent; + + RtlEnterCriticalSection(&q->cs); + t->event = event; + if (t->runcount == 0 && event) + status = STATUS_SUCCESS; + queue_destroy_timer(t); + RtlLeaveCriticalSection(&q->cs); + + if (CompletionEvent == INVALID_HANDLE_VALUE && event) + { + if (status == STATUS_PENDING) + NtWaitForSingleObject(event, FALSE, NULL); + NtClose(event); + } + + return status; +} diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index ef97eb2968f..78e38dc9249 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -41,8 +41,8 @@ #ifdef HAVE_SYS_MMAN_H # include #endif -#ifdef HAVE_VALGRIND_MEMCHECK_H -# include +#ifdef HAVE_VALGRIND_VALGRIND_H +# include #endif #define NONAMELESSUNION @@ -898,6 +898,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz struct stat st; struct file_view *view = NULL; char *ptr, *header_end; + int delta = 0; /* zero-map the whole range */ @@ -1088,7 +1089,6 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) || !NtCurrentTeb()->Peb->ImageBaseAddress) ) { - int delta = ptr - base; IMAGE_BASE_RELOCATION *rel, *end; const IMAGE_DATA_DIRECTORY *relocs; @@ -1106,6 +1106,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz relocs = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; rel = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress); end = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress + relocs->Size); + delta = ptr - base; while (rel <= end - 1 && rel->SizeOfBlock) { @@ -1154,6 +1155,9 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz server_leave_uninterrupted_section( &csVirtual, &sigset ); *addr_ptr = ptr; +#ifdef VALGRIND_LOAD_PDB_DEBUGINFO + VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta); +#endif return STATUS_SUCCESS; error: diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index cda3476f760..564c55b5cd1 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -40,7 +40,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); WINE_DECLARE_DEBUG_CHANNEL(relay); -KSYSTEM_TIME KeTickCount; +KSYSTEM_TIME KeTickCount = { 0, 0, 0 }; typedef struct _KSERVICE_TABLE_DESCRIPTOR { @@ -50,7 +50,7 @@ typedef struct _KSERVICE_TABLE_DESCRIPTOR PUCHAR Number; } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR; -KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4]; +KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4] = { { 0 } }; typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN); diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index a74e71a12e6..909b21547d2 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -583,6 +583,9 @@ HRESULT WINAPI OleIsCurrentClipboard(IDataObject *pDataObject) if (!theOleClipboard) return E_OUTOFMEMORY; + if (pDataObject == NULL) + return S_FALSE; + return (pDataObject == theOleClipboard->pIDataObjectSrc) ? S_OK : S_FALSE; } diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 3df04216f67..64a99ecc10d 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -3742,7 +3742,8 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv) */ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token ) { - FIXME( "stub\n" ); + static int calls; + if(!(calls++)) FIXME( "stub\n" ); if (token) *token = 0; return E_NOTIMPL; } diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c index 26278b6417c..ee912ce773e 100644 --- a/dlls/ole32/tests/clipboard.c +++ b/dlls/ole32/tests/clipboard.c @@ -451,6 +451,8 @@ static void test_set_clipboard(void) ok(hr == S_OK, "expected current clipboard to be data1, hr = 0x%08x\n", hr); hr = OleIsCurrentClipboard(data2); ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08x\n", hr); + hr = OleIsCurrentClipboard(NULL); + ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr); test_get_clipboard(); @@ -460,6 +462,8 @@ static void test_set_clipboard(void) ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08x\n", hr); hr = OleIsCurrentClipboard(data2); ok(hr == S_OK, "expected current clipboard to be data2, hr = 0x%08x\n", hr); + hr = OleIsCurrentClipboard(NULL); + ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr); hr = OleFlushClipboard(); ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr); @@ -467,6 +471,8 @@ static void test_set_clipboard(void) ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08x\n", hr); hr = OleIsCurrentClipboard(data2); ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08x\n", hr); + hr = OleIsCurrentClipboard(NULL); + ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr); ok(OleSetClipboard(NULL) == S_OK, "failed to clear clipboard, hr = 0x%08x\n", hr); diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index ea0297f4e53..8dc10edf5a4 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1365,6 +1365,8 @@ static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xr DIB_RGB_COLORS ); DeleteDC(hdcref); + if (This->desc.u.bmp.hbitmap == 0) + return E_FAIL; This->desc.picType = PICTYPE_BITMAP; OLEPictureImpl_SetBitmap(This); return S_OK; @@ -1869,6 +1871,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { } else { This->datalen = toread+(headerisdata?8:0); xbuf = This->data = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, This->datalen); + if (!xbuf) + return E_OUTOFMEMORY; if (headerisdata) memcpy (xbuf, header, 8); @@ -2644,8 +2648,15 @@ HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, *ppvObj = NULL; return hr; } - IPersistStream_Load(ps,lpstream); + hr = IPersistStream_Load(ps,lpstream); IPersistStream_Release(ps); + if (FAILED(hr)) + { + ERR("IPersistStream_Load failed\n"); + IPicture_Release(newpic); + *ppvObj = NULL; + return hr; + } hr = IPicture_QueryInterface(newpic,riid,ppvObj); if (hr) FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid)); diff --git a/dlls/oleaut32/safearray.c b/dlls/oleaut32/safearray.c index 34cfd9141c8..a19d599c527 100644 --- a/dlls/oleaut32/safearray.c +++ b/dlls/oleaut32/safearray.c @@ -1500,6 +1500,8 @@ HRESULT WINAPI SafeArrayGetVartype(SAFEARRAY* psa, VARTYPE* pvt) if (psa->fFeatures & FADF_RECORD) *pvt = VT_RECORD; + else if ((psa->fFeatures & (FADF_HAVEIID|FADF_DISPATCH)) == (FADF_HAVEIID|FADF_DISPATCH)) + *pvt = VT_DISPATCH; else if (psa->fFeatures & FADF_HAVEIID) *pvt = VT_UNKNOWN; else if (psa->fFeatures & FADF_HAVEVARTYPE) diff --git a/dlls/oleaut32/tests/safearray.c b/dlls/oleaut32/tests/safearray.c index 53896ef9489..969d6961fed 100644 --- a/dlls/oleaut32/tests/safearray.c +++ b/dlls/oleaut32/tests/safearray.c @@ -490,12 +490,8 @@ static void test_safearray(void) { hres = pSafeArrayGetVartype(a, &vt); ok(hres == S_OK, "SAGVT of arra y with vt %d failed with %x\n", vttypes[i].vt, hres); - if (vttypes[i].vt == VT_DISPATCH) { - /* Special case. Checked against Windows. */ - ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d\n", vt); - } else { - ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt); - } + /* Windows prior to Vista returns VT_UNKNOWN instead of VT_DISPATCH */ + ok(broken(vt == VT_UNKNOWN) || vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt); } hres = SafeArrayCopy(a, &c); @@ -509,12 +505,8 @@ static void test_safearray(void) if (pSafeArrayGetVartype) { hres = pSafeArrayGetVartype(c, &vt); ok(hres == S_OK, "SAGVT of array with vt %d failed with %x\n", vttypes[i].vt, hres); - if (vttypes[i].vt == VT_DISPATCH) { - /* Special case. Checked against Windows. */ - ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d\n", vt); - } else { - ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt); - } + /* Windows prior to Vista returns VT_UNKNOWN instead of VT_DISPATCH */ + ok(broken(vt == VT_UNKNOWN) || vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt); } if (pSafeArrayCopyData) { diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c index 7ddbe757a9e..f705722f09f 100644 --- a/dlls/oleaut32/tests/tmarshal.c +++ b/dlls/oleaut32/tests/tmarshal.c @@ -701,10 +701,12 @@ typedef struct KindaEnum static HRESULT register_current_module_typelib(void) { WCHAR path[MAX_PATH]; + CHAR pathA[MAX_PATH]; HRESULT hr; ITypeLib *typelib; - GetModuleFileNameW(NULL, path, MAX_PATH); + GetModuleFileNameA(NULL, pathA, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH); hr = LoadTypeLib(path, &typelib); if (SUCCEEDED(hr)) diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 3479c184258..868470d61f0 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -672,11 +672,13 @@ static void test_inheritance(void) HREFTYPE href; FUNCDESC *pFD; WCHAR path[MAX_PATH]; + CHAR pathA[MAX_PATH]; static const WCHAR tl_path[] = {'.','\\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0}; BOOL use_midl_tlb = 0; - GetModuleFileNameW(NULL, path, MAX_PATH); + GetModuleFileNameA(NULL, pathA, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH); if(use_midl_tlb) memcpy(path, tl_path, sizeof(tl_path)); diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c index 19e33bcfea5..e2db5196562 100644 --- a/dlls/oleaut32/tests/vartype.c +++ b/dlls/oleaut32/tests/vartype.c @@ -5202,7 +5202,8 @@ static void test_SysReAllocString(void) changed = SysReAllocString(&str, szSmaller); ok (changed == 1, "Expected 1, got %d\n", changed); - ok (str == oldstr, "Created new string\n"); + /* Vista creates a new string, but older versions reuse the existing string. */ + /*ok (str == oldstr, "Created new string\n");*/ bstr = Get(str); ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen); ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n"); @@ -5241,7 +5242,8 @@ static void test_SysReAllocStringLen(void) changed = SysReAllocStringLen(&str, szSmaller, 1); ok (changed == 1, "Expected 1, got %d\n", changed); - ok (str == oldstr, "Created new string\n"); + /* Vista creates a new string, but older versions reuse the existing string. */ + /*ok (str == oldstr, "Created new string\n");*/ bstr = Get(str); ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen); ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n"); diff --git a/dlls/oleaut32/version.rc b/dlls/oleaut32/version.rc index 5a3f1fffafa..6887af389bc 100644 --- a/dlls/oleaut32/version.rc +++ b/dlls/oleaut32/version.rc @@ -19,5 +19,7 @@ #define WINE_OLESELFREGISTER #define WINE_FILEDESCRIPTION_STR "Wine OLE dll" #define WINE_FILENAME_STR "oleaut32.dll" +#define WINE_FILEVERSION 6, 0, 6001, 18000 /* version from Vista SP1 */ +#define WINE_FILEVERSION_STR "6.0.6001.18000" #include "wine/wine_common_ver.rc" diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c index 2bbd8f12e7e..e712eb9b177 100644 --- a/dlls/quartz/avisplit.c +++ b/dlls/quartz/avisplit.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ /* FIXME: - * - Reference leaks, if they are still existant + * - Reference leaks, if they still exist * - Files without an index are not handled correctly yet. * - When stopping/starting, a sample is lost. This should be compensated by * keeping track of previous index/position. @@ -147,7 +147,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe PullPin *pin = This->Parser.pInputPin; IMediaSample *sample = NULL; HRESULT hr; - BOOL endofstream = FALSE; TRACE("(%p, %u)->()\n", This, streamnumber); @@ -181,6 +180,14 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe AVISTDINDEX_ENTRY *entry = &index->aIndex[stream->pos]; BOOL keyframe; + /* End of file */ + if (stream->index >= stream->entries) + { + ERR("END OF STREAM ON %u\n", streamnumber); + IMediaSample_Release(sample); + return S_FALSE; + } + rtSampleStart = index->qwBaseOffset; keyframe = !(entry->dwSize >> 31); rtSampleStart += entry->dwOffset; @@ -196,21 +203,21 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(entry->dwSize & ~(1 << 31)); TRACE("offset(%u) size(%u)\n", (DWORD)BYTES_FROM_MEDIATIME(rtSampleStart), (DWORD)BYTES_FROM_MEDIATIME(rtSampleStop - rtSampleStart)); - - /* End of file */ - if (stream->index_next >= stream->entries) - { - ERR("END OF STREAM ON %u\n", streamnumber); - IMediaSample_Release(sample); - hr = AVISplitter_SendEndOfFile(This, streamnumber); - return S_FALSE; - } } else if (This->oldindex) { DWORD flags = This->oldindex->aIndex[stream->pos].dwFlags; DWORD size = This->oldindex->aIndex[stream->pos].dwSize; BOOL keyframe; + + /* End of file */ + if (stream->index) + { + IMediaSample_Release(sample); + ERR("END OF STREAM ON %u\n", streamnumber); + return S_FALSE; + } + keyframe = !!(flags & AVIIF_KEYFRAME); rtSampleStart = MEDIATIME_FROM_BYTES(This->offset); @@ -238,15 +245,11 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe } while (stream->pos_next * sizeof(This->oldindex->aIndex[0]) < This->oldindex->cb && StreamFromFOURCC(This->oldindex->aIndex[stream->pos_next].dwChunkId) != streamnumber); - /* End of file */ + /* End of file soon */ if (stream->pos_next * sizeof(This->oldindex->aIndex[0]) >= This->oldindex->cb) { - IMediaSample_Release(sample); stream->pos_next = 0; ++stream->index_next; - ERR("END OF STREAM ON %u\n", streamnumber); - hr = AVISplitter_SendEndOfFile(This, streamnumber); - endofstream = TRUE; } } else /* TODO: Generate an index automagically */ @@ -255,12 +258,21 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe assert(0); } - hr = IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop); + if (rtSampleStart != rtSampleStop) + { + hr = IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop); - hr = IAsyncReader_Request(pin->pReader, sample, streamnumber); + hr = IAsyncReader_Request(pin->pReader, sample, streamnumber); - if (FAILED(hr)) - assert(IMediaSample_Release(sample) == 0); + if (FAILED(hr)) + assert(IMediaSample_Release(sample) == 0); + } + else + { + stream->sample = sample; + IMediaSample_SetActualDataLength(sample, 0); + SetEvent(stream->packet_queued); + } } else { @@ -272,9 +284,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe } TRACE("--> %08x\n", hr); - if (endofstream && hr == S_OK) - return S_FALSE; - return hr; } @@ -346,6 +355,8 @@ static DWORD WINAPI AVISplitter_thread_reader(LPVOID data) IMediaSample_Release(sample); if (hr == S_OK) hr = nexthr; + if (nexthr == S_FALSE) + AVISplitter_SendEndOfFile(This, streamnumber); } while (hr == S_OK); FIXME("Thread %u terminated with hr %08x!\n", streamnumber, hr); @@ -360,7 +371,10 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PT HRESULT hr = S_OK; if (!IMediaSample_GetActualDataLength(pSample)) + { + ERR("Received empty sample\n"); return S_OK; + } /* Send the sample to whatever thread is appropiate * That thread should also not have a sample queued at the moment @@ -410,7 +424,7 @@ static HRESULT AVISplitter_first_request(LPVOID iface) stream->pos_next = stream->pos; stream->index_next = stream->index; - /* There should be a a packet queued from AVISplitter_next_request last time + /* There should be a packet queued from AVISplitter_next_request last time * It needs to be done now because this is the only way to ensure that every * stream will have at least 1 packet processed * If this is done after the threads start it could go all awkward and we diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index 5daaf7e4d20..e2b868e397c 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -192,19 +192,15 @@ static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pMemAlloc); if (hr == VFW_E_NO_ALLOCATOR) - { /* Input pin provides no allocator, use standard memory allocator */ hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAlloc); - if (SUCCEEDED(hr)) - { - hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, This->readonly); - } - } - if (SUCCEEDED(hr)) hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual); + if (SUCCEEDED(hr)) + hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, This->readonly); + if (pMemAlloc) IMemAllocator_Release(pMemAlloc); } @@ -940,7 +936,9 @@ HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDI while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) { assert(pmtCandidate); - if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype)) + dump_AM_MEDIA_TYPE(pmtCandidate); + if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype) + && !IsEqualGUID(&GUID_NULL, &pmtCandidate->formattype)) assert(pmtCandidate->pbFormat); if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) @@ -963,7 +961,9 @@ HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDI while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) { assert(pmtCandidate); - if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype)) + dump_AM_MEDIA_TYPE(pmtCandidate); + if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype) + && !IsEqualGUID(&GUID_NULL, &pmtCandidate->formattype)) assert(pmtCandidate->pbFormat); if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) diff --git a/dlls/quartz/tests/avisplitter.c b/dlls/quartz/tests/avisplitter.c index d3cdaacae11..a7461f420c7 100644 --- a/dlls/quartz/tests/avisplitter.c +++ b/dlls/quartz/tests/avisplitter.c @@ -177,7 +177,7 @@ static const char afile[] = "test.avi"; /* This test doesn't use the quartz filtergraph because it makes it impossible * to be certain that a thread is really one owned by the avi splitter * A lot of the decoder filters will also have their own thread, and windows' - * filtergraph has a seperate thread for start/stop/seeking requests. + * filtergraph has a separate thread for start/stop/seeking requests. * By avoiding the filtergraph all together and connecting streams directly to * the null renderer I am sure that this is not the case here. */ diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 2dd758a873f..a801ee2ecc6 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1807,6 +1807,13 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0; + /* Default vertical scrollbar information */ + ed->vert_si.cbSize = sizeof(SCROLLINFO); + ed->vert_si.nMin = 0; + ed->vert_si.nMax = 0; + ed->vert_si.nPage = 0; + ed->vert_si.nPos = 0; + return ed; } @@ -3055,15 +3062,29 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, return (wParam >= 0x40000) ? 0 : MAKELONG( pt.x, pt.y ); } case WM_CREATE: + { + SCROLLINFO si; + GetClientRect(hWnd, &editor->rcFormat); if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL) { /* Squelch the default horizontal scrollbar it would make */ ShowScrollBar(editor->hWnd, SB_HORZ, FALSE); } + + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL) + si.fMask |= SIF_DISABLENOSCROLL; + si.nMax = (si.fMask & SIF_DISABLENOSCROLL) ? 1 : 0; + si.nMin = 0; + si.nPage = 0; + SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + ME_CommitUndo(editor); ME_WrapMarkedParagraphs(editor); ME_MoveCaret(editor); return 0; + } case WM_DESTROY: ME_DestroyEditor(editor); SetWindowLongPtrW(hWnd, 0, 0); diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 81f4cc38ba3..ba0c0d2d210 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -343,6 +343,9 @@ typedef struct tagME_TextEditor /* Track previous notified selection */ CHARRANGE notified_cr; + + /* Cache previously set vertical scrollbar info */ + SCROLLINFO vert_si; } ME_TextEditor; typedef struct tagME_Context diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index a6e86b3c513..adae4cb8097 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -784,6 +784,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type) ME_Repaint(editor); } + editor->vert_si.nMax = 0; ME_UpdateScrollBar(editor); } @@ -806,6 +807,14 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type) bScrollBarWasVisible = ME_GetYScrollVisible(editor); bScrollBarWillBeVisible = editor->nHeight > editor->sizeWindow.cy; + si.fMask = SIF_PAGE | SIF_RANGE; + if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL) + si.fMask |= SIF_DISABLENOSCROLL; + if ((si.fMask & SIF_DISABLENOSCROLL)) + { + bScrollBarWillBeVisible = TRUE; + } + if (bScrollBarWasVisible != bScrollBarWillBeVisible) { ShowScrollBar(hWnd, SB_VERT, bScrollBarWillBeVisible); @@ -813,17 +822,27 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type) ME_WrapMarkedParagraphs(editor); } - si.fMask = SIF_PAGE | SIF_RANGE; - if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL) - si.fMask |= SIF_DISABLENOSCROLL; - si.nMin = 0; si.nMax = editor->nTotalLength; si.nPage = editor->sizeWindow.cy; - TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage); - SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + if (!(si.nMin == editor->vert_si.nMin && si.nMax == editor->vert_si.nMax && si.nPage == editor->vert_si.nPage)) + { + TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage); + editor->vert_si.nMin = si.nMin; + editor->vert_si.nMax = si.nMax; + editor->vert_si.nPage = si.nPage; + if (bScrollBarWillBeVisible) + { + SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + } + else + { + if (bScrollBarWasVisible && !(si.fMask & SIF_DISABLENOSCROLL)) + ShowScrollBar(hWnd, SB_VERT, FALSE); + } + } } int ME_GetYScrollPos(ME_TextEditor *editor) @@ -836,10 +855,7 @@ int ME_GetYScrollPos(ME_TextEditor *editor) BOOL ME_GetYScrollVisible(ME_TextEditor *editor) { /* Returns true if the scrollbar is visible */ - SCROLLBARINFO sbi; - sbi.cbSize = sizeof(sbi); - GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi); - return ((sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE) == 0); + return (editor->vert_si.nMax - editor->vert_si.nMin >= max(editor->vert_si.nPage - 1, 0)); } void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun) diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 8d22e85e10b..e6bc67f92d5 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1383,6 +1383,9 @@ static HWND new_static_wnd(HWND parent) { static void test_EM_AUTOURLDETECT(void) { + /* DO NOT change the properties of the first two elements. To shorten the + tests, all tests after WM_SETTEXT test just the first two elements - + one non-URL and one URL */ struct urls_s { const char *text; int is_url; @@ -1647,10 +1650,12 @@ static void test_EM_AUTOURLDETECT(void) } /* Test detection of URLs within normal text - WM_CHAR case. */ - for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) { + /* Test only the first two URL examples for brevity */ + for (i = 0; i < 2; i++) { hwndRichEdit = new_richedit(parent); - for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) { + /* Also for brevity, test only the first three delimiters */ + for (j = 0; j < 3; j++) { char * at_pos; int at_offset; int end_offset; @@ -1674,7 +1679,6 @@ static void test_EM_AUTOURLDETECT(void) } } SendMessage(hwndRichEdit, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer); - trace("Using template: %s\n", templates_delim[j]); /* This assumes no templates start with the URL itself, and that they have at least two characters before the URL text */ @@ -1784,7 +1788,8 @@ static void test_EM_AUTOURLDETECT(void) } /* Test detection of URLs within normal text - EM_SETTEXTEX case. */ - for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) { + /* Test just the first two URL examples for brevity */ + for (i = 0; i < 2; i++) { SETTEXTEX st; hwndRichEdit = new_richedit(parent); @@ -1971,7 +1976,8 @@ static void test_EM_AUTOURLDETECT(void) } /* Test detection of URLs within normal text - EM_REPLACESEL case. */ - for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) { + /* Test just the first two URL examples for brevity */ + for (i = 0; i < 2; i++) { hwndRichEdit = new_richedit(parent); /* Set selection with X to the URL */ @@ -2223,6 +2229,728 @@ static void test_EM_SCROLL(void) DestroyWindow(hwndRichEdit); } +unsigned int recursionLevel = 0; +unsigned int WM_SIZE_recursionLevel = 0; +BOOL bailedOutOfRecursion = FALSE; +LRESULT WINAPI (*richeditProc)(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +static LRESULT WINAPI RicheditStupidOverrideProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT r; + + if (bailedOutOfRecursion) return 0; + if (recursionLevel >= 32) { + bailedOutOfRecursion = TRUE; + return 0; + } + + recursionLevel++; + switch (message) { + case WM_SIZE: + WM_SIZE_recursionLevel++; + r = richeditProc(hwnd, message, wParam, lParam); + /* Because, uhhhh... I never heard of ES_DISABLENOSCROLL */ + ShowScrollBar(hwnd, SB_VERT, TRUE); + WM_SIZE_recursionLevel--; + break; + default: + r = richeditProc(hwnd, message, wParam, lParam); + break; + } + recursionLevel--; + return r; +} + +static void test_scrollbar_visibility(void) +{ + HWND hwndRichEdit; + const char * text="a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"; + SCROLLINFO si; + WNDCLASSA cls; + BOOL r; + + /* These tests show that richedit should temporarily refrain from automatically + hiding or showing its scrollbars (vertical at least) when an explicit request + is made via ShowScrollBar() or similar, outside of standard richedit logic. + Some applications depend on forced showing (when otherwise richedit would + hide the vertical scrollbar) and are thrown on an endless recursive loop + if richedit auto-hides the scrollbar again. Apparently they never heard of + the ES_DISABLENOSCROLL style... */ + + hwndRichEdit = new_richedit(NULL); + + /* Test default scrollbar visibility behavior */ + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + /* Oddly, setting text to NULL does *not* reset the scrollbar range, + even though it hides the scrollbar */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + /* Setting non-scrolling text again does *not* reset scrollbar range */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)""); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + DestroyWindow(hwndRichEdit); + + /* Test again, with ES_DISABLENOSCROLL style */ + hwndRichEdit = new_window(RICHEDIT_CLASS, ES_MULTILINE|ES_DISABLENOSCROLL, NULL); + + /* Test default scrollbar visibility behavior */ + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 1, + "reported page/range is %d (%d..%d) expected 0 (0..1)\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 1, + "reported page/range is %d (%d..%d) expected 0 (0..1)\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax > 1, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Oddly, setting text to NULL does *not* reset the scrollbar range */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax > 1, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + /* Setting non-scrolling text again does *not* reset scrollbar range */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax > 1, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax > 1, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax > 1, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)""); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax > 1, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + DestroyWindow(hwndRichEdit); + + /* Test behavior with explicit visibility request, using ShowScrollBar() */ + hwndRichEdit = new_richedit(NULL); + + /* Previously failed because builtin incorrectly re-hides scrollbar forced visible */ + ShowScrollBar(hwndRichEdit, SB_VERT, TRUE); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + todo_wine { + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, + "reported page/range is %d (%d..%d) expected 0 (0..100)\n", + si.nPage, si.nMin, si.nMax); + } + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + todo_wine { + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, + "reported page/range is %d (%d..%d) expected 0 (0..100)\n", + si.nPage, si.nMin, si.nMax); + } + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + todo_wine { + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, + "reported page/range is %d (%d..%d) expected 0 (0..100)\n", + si.nPage, si.nMin, si.nMax); + } + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a\na"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + todo_wine { + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, + "reported page/range is %d (%d..%d) expected 0 (0..100)\n", + si.nPage, si.nMin, si.nMax); + } + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + todo_wine { + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, + "reported page/range is %d (%d..%d) expected 0 (0..100)\n", + si.nPage, si.nMin, si.nMax); + } + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + DestroyWindow(hwndRichEdit); + + hwndRichEdit = new_richedit(NULL); + + ShowScrollBar(hwndRichEdit, SB_VERT, FALSE); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Previously, builtin incorrectly re-shows explicitly hidden scrollbar */ + ShowScrollBar(hwndRichEdit, SB_VERT, FALSE); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Testing effect of EM_SCROLL on scrollbar visibility. It seems that + EM_SCROLL will make visible any forcefully invisible scrollbar */ + SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEDOWN, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + ShowScrollBar(hwndRichEdit, SB_VERT, FALSE); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Again, EM_SCROLL, with SB_LINEUP */ + SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEUP, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + DestroyWindow(hwndRichEdit); + + + /* Test behavior with explicit visibility request, using SetWindowLong()() */ + hwndRichEdit = new_richedit(NULL); + +#define ENABLE_WS_VSCROLL(hwnd) \ + SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) | WS_VSCROLL) +#define DISABLE_WS_VSCROLL(hwnd) \ + SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) & ~WS_VSCROLL) + + /* Previously failed because builtin incorrectly re-hides scrollbar forced visible */ + ENABLE_WS_VSCROLL(hwndRichEdit); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a\na"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + /* Ditto, see above */ + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + DestroyWindow(hwndRichEdit); + + hwndRichEdit = new_richedit(NULL); + + DISABLE_WS_VSCROLL(hwndRichEdit); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 0, + "reported page/range is %d (%d..%d) expected all 0\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Previously, builtin incorrectly re-shows explicitly hidden scrollbar */ + DISABLE_WS_VSCROLL(hwndRichEdit); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d) expected nMax/nPage nonzero\n", + si.nPage, si.nMin, si.nMax); + + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + DISABLE_WS_VSCROLL(hwndRichEdit); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Testing effect of EM_SCROLL on scrollbar visibility. It seems that + EM_SCROLL will make visible any forcefully invisible scrollbar */ + SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEDOWN, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + DISABLE_WS_VSCROLL(hwndRichEdit); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) == 0), + "Vertical scrollbar is visible, should be invisible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + /* Again, EM_SCROLL, with SB_LINEUP */ + SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEUP, 0); + memset(&si, 0, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(hwndRichEdit, SB_VERT, &si); + ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), + "Vertical scrollbar is invisible, should be visible.\n"); + ok(si.nPage != 0 && si.nMin == 0 && si.nMax != 0, + "reported page/range is %d (%d..%d)\n", + si.nPage, si.nMin, si.nMax); + + DestroyWindow(hwndRichEdit); + + /* This window proc models what is going on with Corman Lisp 3.0. + At WM_SIZE, this proc unconditionally calls ShowScrollBar() to + force the scrollbar into visibility. Recursion should NOT happen + as a result of this action. + */ + r = GetClassInfoA(NULL, RICHEDIT_CLASS, &cls); + if (r) { + richeditProc = cls.lpfnWndProc; + cls.lpfnWndProc = RicheditStupidOverrideProcA; + cls.lpszClassName = "RicheditStupidOverride"; + if(!RegisterClassA(&cls)) assert(0); + + recursionLevel = 0; + WM_SIZE_recursionLevel = 0; + bailedOutOfRecursion = FALSE; + hwndRichEdit = new_window(cls.lpszClassName, ES_MULTILINE, NULL); + ok(!bailedOutOfRecursion, + "WM_SIZE/scrollbar mutual recursion detected, expected none!\n"); + + recursionLevel = 0; + WM_SIZE_recursionLevel = 0; + bailedOutOfRecursion = FALSE; + MoveWindow(hwndRichEdit, 0, 0, 250, 100, TRUE); + ok(!bailedOutOfRecursion, + "WM_SIZE/scrollbar mutual recursion detected, expected none!\n"); + + /* Unblock window in order to process WM_DESTROY */ + recursionLevel = 0; + bailedOutOfRecursion = FALSE; + WM_SIZE_recursionLevel = 0; + DestroyWindow(hwndRichEdit); + } +} + static void test_EM_SETUNDOLIMIT(void) { /* cases we test for: @@ -4565,6 +5293,7 @@ START_TEST( editor ) test_EM_POSFROMCHAR(); test_EM_SCROLLCARET(); test_EM_SCROLL(); + test_scrollbar_visibility(); test_WM_SETTEXT(); test_EM_LINELENGTH(); test_EM_SETCHARFORMAT(); diff --git a/dlls/rpcrt4/epm_towers.h b/dlls/rpcrt4/epm_towers.h index f38d4872872..3eec37aa228 100644 --- a/dlls/rpcrt4/epm_towers.h +++ b/dlls/rpcrt4/epm_towers.h @@ -19,7 +19,7 @@ * */ -#include "wine/epm.h" +#include "epm.h" #define EPM_PROTOCOL_DNET_NSP 0x04 #define EPM_PROTOCOL_OSI_TP4 0x05 diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 8fcff08dc9d..4e11bc0aba2 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -824,7 +824,7 @@ static void testGetDeviceInterfaceDetail(void) LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size); SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buf; - DWORD expectedsize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR)*(1 + strlen(path)); + DWORD expectedsize = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR)*(1 + strlen(path)); detail->cbSize = 0; SetLastError(0xdeadbeef); @@ -1101,7 +1101,7 @@ static void testRegisterAndGetDetail(void) detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)HeapAlloc(GetProcessHeap(), 0, dwSize); if (detail) { - detail->cbSize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(char); + detail->cbSize = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(char); SetLastError(0xdeadbeef); ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail, dwSize, &dwSize, NULL); diff --git a/dlls/setupapi/tests/misc.c b/dlls/setupapi/tests/misc.c index f8750b60154..a18fd37a242 100644 --- a/dlls/setupapi/tests/misc.c +++ b/dlls/setupapi/tests/misc.c @@ -400,6 +400,7 @@ static void test_SetupGetFileCompressionInfo(void) ok(target_size == sizeof(uncompressed), "got %d\n", target_size); ok(type == FILE_COMPRESSION_NONE, "got %d, expected FILE_COMPRESSION_NONE\n", type); + MyFree(name); DeleteFileA(source); } diff --git a/dlls/setupapi/tests/query.c b/dlls/setupapi/tests/query.c index 1546ff97b71..9c35767cebf 100644 --- a/dlls/setupapi/tests/query.c +++ b/dlls/setupapi/tests/query.c @@ -266,6 +266,8 @@ static void test_SetupGetInfInformation(void) ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n"); ok(check_info_filename(info, inf_two), "Expected returned filename to be equal\n"); + HeapFree(GetProcessHeap(), 0, info); + DeleteFileA(inf_filename); DeleteFileA(inf_one); DeleteFileA(inf_two); diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c index 4c32b3f9000..5eb76f7ffb0 100644 --- a/dlls/shell32/autocomplete.c +++ b/dlls/shell32/autocomplete.c @@ -574,7 +574,8 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, IEnumString_Reset(This->enumstr); filled = FALSE; for(cpt = 0;;) { - hr = IEnumString_Next(This->enumstr, 1, &strs, NULL); + ULONG fetched; + hr = IEnumString_Next(This->enumstr, 1, &strs, &fetched); if (hr != S_OK) break; diff --git a/dlls/shell32/control.c b/dlls/shell32/control.c index dbebbd2716a..642e6114320 100644 --- a/dlls/shell32/control.c +++ b/dlls/shell32/control.c @@ -1,6 +1,7 @@ /* Control Panel management * * Copyright 2001 Eric Pouech + * Copyright 2008 Owen Rudge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,11 +34,16 @@ #include "wine/debug.h" #include "cpl.h" #include "wine/unicode.h" +#include "commctrl.h" #define NO_SHLWAPI_REG #include "shlwapi.h" #include "cpanel.h" +#include "shresdef.h" +#include "shell32_main.h" + +#define MAX_STRING_LEN 1024 WINE_DEFAULT_DEBUG_CHANNEL(shlctrl); @@ -159,107 +165,258 @@ CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel) return NULL; } -static void Control_WndProc_Create(HWND hWnd, const CREATESTRUCTA* cs) +#define IDC_LISTVIEW 1000 +#define IDC_STATUSBAR 1001 + +#define NUM_COLUMNS 2 +#define LISTVIEW_DEFSTYLE (WS_CHILD | WS_VISIBLE | WS_TABSTOP |\ + LVS_SORTASCENDING | LVS_AUTOARRANGE | LVS_SINGLESEL) + +static BOOL Control_CreateListView (CPanel *panel) { - CPanel* panel = (CPanel*)cs->lpCreateParams; + RECT ws, sb; + WCHAR empty_string[] = {0}; + WCHAR buf[MAX_STRING_LEN]; + LVCOLUMNW lvc; + + /* Create list view */ + GetClientRect(panel->hWndStatusBar, &sb); + GetClientRect(panel->hWnd, &ws); + + panel->hWndListView = CreateWindowExW(WS_EX_CLIENTEDGE, WC_LISTVIEWW, + empty_string, LISTVIEW_DEFSTYLE | LVS_ICON, + 0, 0, ws.right - ws.left, ws.bottom - ws.top - + (sb.bottom - sb.top), panel->hWnd, + (HMENU) IDC_LISTVIEW, panel->hInst, NULL); + + if (!panel->hWndListView) + return FALSE; + + /* Create image lists for list view */ + panel->hImageListSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), ILC_MASK, 1, 1); + panel->hImageListLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), ILC_MASK, 1, 1); + + (void) ListView_SetImageList(panel->hWndListView, panel->hImageListSmall, LVSIL_SMALL); + (void) ListView_SetImageList(panel->hWndListView, panel->hImageListLarge, LVSIL_NORMAL); + + /* Create columns for list view */ + lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; + lvc.pszText = buf; + lvc.fmt = LVCFMT_LEFT; + + /* Name column */ + lvc.iSubItem = 0; + lvc.cx = (ws.right - ws.left) / 3; + LoadStringW(shell32_hInstance, IDS_CPANEL_NAME, buf, sizeof(buf) / sizeof(buf[0])); + + if (ListView_InsertColumnW(panel->hWndListView, 0, &lvc) == -1) + return FALSE; + + /* Description column */ + lvc.iSubItem = 1; + lvc.cx = ((ws.right - ws.left) / 3) * 2; + LoadStringW(shell32_hInstance, IDS_CPANEL_DESCRIPTION, buf, sizeof(buf) / + sizeof(buf[0])); + + if (ListView_InsertColumnW(panel->hWndListView, 1, &lvc) == -1) + return FALSE; + + return(TRUE); +} - SetWindowLongPtrA(hWnd, 0, (LONG_PTR)panel); - panel->status = 0; +static void Control_WndProc_Create(HWND hWnd, const CREATESTRUCTW* cs) +{ + CPanel* panel = (CPanel*)cs->lpCreateParams; + HMENU hMenu, hSubMenu; + CPlApplet* applet; + MENUITEMINFOW mii; + int menucount, i, index; + CPlItem *item; + LVITEMW lvItem; + INITCOMMONCONTROLSEX icex; + INT sb_parts; + + SetWindowLongPtrW(hWnd, 0, (LONG_PTR)panel); panel->hWnd = hWnd; -} -#define XICON 32 -#define XSTEP 128 -#define YICON 32 -#define YSTEP 64 + /* Initialise common control DLL */ + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + /* create the status bar */ + if (!(panel->hWndStatusBar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, NULL, hWnd, IDC_STATUSBAR))) + return; + + sb_parts = -1; + SendMessageW(panel->hWndStatusBar, SB_SETPARTS, 1, (LPARAM) &sb_parts); + + /* create the list view */ + if (!Control_CreateListView(panel)) + return; + + hMenu = LoadMenuW(shell32_hInstance, MAKEINTRESOURCEW(MENU_CPANEL)); + + /* insert menu items for applets */ + hSubMenu = GetSubMenu(hMenu, 0); + menucount = 0; + + for (applet = panel->first; applet; applet = applet->next) { + for (i = 0; i < applet->count; i++) { + if (!applet->info[i].dwSize) + continue; + + /* set up a CPlItem for this particular subprogram */ + item = HeapAlloc(GetProcessHeap(), 0, sizeof(CPlItem)); + + if (!item) + continue; + + item->applet = (CPlApplet *) applet; + item->id = i; + + mii.cbSize = sizeof(MENUITEMINFOW); + mii.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA; + mii.dwTypeData = applet->info[i].szName; + mii.cch = sizeof(applet->info[i].szName) / sizeof(applet->info[i].szName[0]); + mii.wID = IDM_CPANEL_APPLET_BASE + menucount; + mii.dwItemData = (DWORD) item; + + if (InsertMenuItemW(hSubMenu, menucount, TRUE, &mii)) { + /* add the list view item */ + index = ImageList_AddIcon(panel->hImageListLarge, applet->info[i].hIcon); + ImageList_AddIcon(panel->hImageListSmall, applet->info[i].hIcon); + + lvItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; + lvItem.iItem = menucount; + lvItem.iSubItem = 0; + lvItem.pszText = applet->info[i].szName; + lvItem.iImage = index; + lvItem.lParam = (LPARAM) item; + + ListView_InsertItemW(panel->hWndListView, &lvItem); + + /* add the description */ + ListView_SetItemTextW(panel->hWndListView, menucount, 1, + applet->info[i].szInfo); + + /* update menu bar, increment count */ + DrawMenuBar(hWnd); + menucount++; + } + } + } + + panel->total_subprogs = menucount; + + /* check the "large items" icon in the View menu */ + hSubMenu = GetSubMenu(hMenu, 1); + CheckMenuRadioItem(hSubMenu, FCIDM_SHVIEW_BIGICON, FCIDM_SHVIEW_REPORTVIEW, + FCIDM_SHVIEW_BIGICON, MF_BYCOMMAND); + + SetMenu(hWnd, hMenu); +} -static BOOL Control_Localize(const CPanel* panel, int cx, int cy, - CPlApplet** papplet, unsigned* psp) +static void Control_FreeCPlItems(HWND hWnd, CPanel *panel) { - unsigned i, x = (XSTEP-XICON)/2, y = 0; - CPlApplet* applet; - RECT rc; - - GetClientRect(panel->hWnd, &rc); - for (applet = panel->first; applet; applet = applet->next) { - for (i = 0; i < applet->count; i++) { - if (!applet->info[i].dwSize) continue; - if (x + XSTEP >= rc.right - rc.left) { - x = (XSTEP-XICON)/2; - y += YSTEP; - } - if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP) { - *papplet = applet; - *psp = i; - return TRUE; - } - x += XSTEP; - } + HMENU hMenu, hSubMenu; + MENUITEMINFOW mii; + int i; + + /* get the File menu */ + hMenu = GetMenu(hWnd); + + if (!hMenu) + return; + + hSubMenu = GetSubMenu(hMenu, 0); + + if (!hSubMenu) + return; + + /* loop and free the item data */ + for (i = IDM_CPANEL_APPLET_BASE; i <= IDM_CPANEL_APPLET_BASE + panel->total_subprogs; i++) + { + mii.cbSize = sizeof(MENUITEMINFOW); + mii.fMask = MIIM_DATA; + + if (!GetMenuItemInfoW(hSubMenu, i, FALSE, &mii)) + continue; + + HeapFree(GetProcessHeap(), 0, (LPVOID) mii.dwItemData); } - return FALSE; } -static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam) +static void Control_UpdateListViewStyle(CPanel *panel, UINT style, UINT id) { - HDC hdc; - PAINTSTRUCT ps; - RECT rc, txtRect; - unsigned i, x = 0, y = 0; - CPlApplet* applet; - HGDIOBJ hOldFont; - - hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps); - hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT)); - GetClientRect(panel->hWnd, &rc); - for (applet = panel->first; applet; applet = applet->next) { - for (i = 0; i < applet->count; i++) { - if (x + XSTEP >= rc.right - rc.left) { - x = 0; - y += YSTEP; - } - if (!applet->info[i].dwSize) continue; - DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon); - txtRect.left = x; - txtRect.right = x + XSTEP; - txtRect.top = y + YICON; - txtRect.bottom = y + YSTEP; - DrawTextW(hdc, applet->info[i].szName, -1, &txtRect, - DT_CENTER | DT_VCENTER); - x += XSTEP; - } - } - SelectObject(hdc, hOldFont); - if (!wParam) EndPaint(panel->hWnd, &ps); - return 0; + HMENU hMenu, hSubMenu; + + SetWindowLongW(panel->hWndListView, GWL_STYLE, LISTVIEW_DEFSTYLE | style); + + /* update the menu */ + hMenu = GetMenu(panel->hWnd); + hSubMenu = GetSubMenu(hMenu, 1); + + CheckMenuRadioItem(hSubMenu, FCIDM_SHVIEW_BIGICON, FCIDM_SHVIEW_REPORTVIEW, + id, MF_BYCOMMAND); } -static LRESULT Control_WndProc_LButton(CPanel* panel, LPARAM lParam, BOOL up) +static CPlItem* Control_GetCPlItem_From_MenuID(HWND hWnd, UINT id) { - unsigned i; - CPlApplet* applet; + HMENU hMenu, hSubMenu; + MENUITEMINFOW mii; - if (Control_Localize(panel, (short)LOWORD(lParam), (short)HIWORD(lParam), &applet, &i)) { - if (up) { - if (panel->clkApplet == applet && panel->clkSP == i) { - applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData); - } - } else { - panel->clkApplet = applet; - panel->clkSP = i; - } + /* retrieve the CPlItem structure from the menu item data */ + hMenu = GetMenu(hWnd); + + if (!hMenu) + return NULL; + + hSubMenu = GetSubMenu(hMenu, 0); + + if (!hSubMenu) + return NULL; + + mii.cbSize = sizeof(MENUITEMINFOW); + mii.fMask = MIIM_DATA; + + if (!GetMenuItemInfoW(hSubMenu, id, FALSE, &mii)) + return NULL; + + return (CPlItem *) mii.dwItemData; +} + +static CPlItem* Control_GetCPlItem_From_ListView(CPanel *panel) +{ + LVITEMW lvItem; + int selitem; + + selitem = SendMessageW(panel->hWndListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED + | LVNI_SELECTED); + + if (selitem != -1) + { + lvItem.iItem = selitem; + lvItem.mask = LVIF_PARAM; + + if (SendMessageW(panel->hWndListView, LVM_GETITEMW, 0, (LPARAM) &lvItem)) + return (CPlItem *) lvItem.lParam; } - return 0; + + return NULL; } static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg, WPARAM lParam1, LPARAM lParam2) { - CPanel* panel = (CPanel*)GetWindowLongPtrA(hWnd, 0); + CPanel* panel = (CPanel*)GetWindowLongPtrW(hWnd, 0); if (panel || wMsg == WM_CREATE) { switch (wMsg) { case WM_CREATE: - Control_WndProc_Create(hWnd, (CREATESTRUCTA*)lParam2); + Control_WndProc_Create(hWnd, (CREATESTRUCTW*)lParam2); return 0; case WM_DESTROY: { @@ -267,56 +424,185 @@ static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg, while (applet) applet = Control_UnloadApplet(applet); } + Control_FreeCPlItems(hWnd, panel); PostQuitMessage(0); break; - case WM_PAINT: - return Control_WndProc_Paint(panel, lParam1); - case WM_LBUTTONUP: - return Control_WndProc_LButton(panel, lParam2, TRUE); - case WM_LBUTTONDOWN: - return Control_WndProc_LButton(panel, lParam2, FALSE); -/* EPP case WM_COMMAND: */ -/* EPP return Control_WndProc_Command(mwi, lParam1, lParam2); */ + case WM_COMMAND: + switch (LOWORD(lParam1)) + { + case IDM_CPANEL_EXIT: + SendMessageW(hWnd, WM_CLOSE, 0, 0); + return 0; + + case IDM_CPANEL_ABOUT: + { + WCHAR appName[MAX_STRING_LEN]; + + LoadStringW(shell32_hInstance, IDS_CPANEL_TITLE, appName, + sizeof(appName) / sizeof(appName[0])); + ShellAboutW(hWnd, appName, NULL, NULL); + + return 0; + } + + case FCIDM_SHVIEW_BIGICON: + Control_UpdateListViewStyle(panel, LVS_ICON, FCIDM_SHVIEW_BIGICON); + return 0; + + case FCIDM_SHVIEW_SMALLICON: + Control_UpdateListViewStyle(panel, LVS_SMALLICON, FCIDM_SHVIEW_SMALLICON); + return 0; + + case FCIDM_SHVIEW_LISTVIEW: + Control_UpdateListViewStyle(panel, LVS_LIST, FCIDM_SHVIEW_LISTVIEW); + return 0; + + case FCIDM_SHVIEW_REPORTVIEW: + Control_UpdateListViewStyle(panel, LVS_REPORT, FCIDM_SHVIEW_REPORTVIEW); + return 0; + + default: + /* check if this is an applet */ + if ((LOWORD(lParam1) >= IDM_CPANEL_APPLET_BASE) && + (LOWORD(lParam1) <= IDM_CPANEL_APPLET_BASE + panel->total_subprogs)) + { + CPlItem *item = Control_GetCPlItem_From_MenuID(hWnd, LOWORD(lParam1)); + + /* execute the applet if item is valid */ + if (item) + item->applet->proc(item->applet->hWnd, CPL_DBLCLK, item->id, + item->applet->info[item->id].lData); + + return 0; + } + + break; + } + + break; + + case WM_NOTIFY: + { + LPNMHDR nmh = (LPNMHDR) lParam2; + + switch (nmh->idFrom) + { + case IDC_LISTVIEW: + switch (nmh->code) + { + case NM_RETURN: + case NM_DBLCLK: + { + CPlItem *item = Control_GetCPlItem_From_ListView(panel); + + /* execute the applet if item is valid */ + if (item) + item->applet->proc(item->applet->hWnd, CPL_DBLCLK, + item->id, item->applet->info[item->id].lData); + + return 0; + } + case LVN_ITEMCHANGED: + { + CPlItem *item = Control_GetCPlItem_From_ListView(panel); + + /* update the status bar if item is valid */ + if (item) + SetWindowTextW(panel->hWndStatusBar, + item->applet->info[item->id].szInfo); + + return 0; + } + } + + break; + } + + break; + } + + case WM_MENUSELECT: + /* check if this is an applet */ + if ((LOWORD(lParam1) >= IDM_CPANEL_APPLET_BASE) && + (LOWORD(lParam1) <= IDM_CPANEL_APPLET_BASE + panel->total_subprogs)) + { + CPlItem *item = Control_GetCPlItem_From_MenuID(hWnd, LOWORD(lParam1)); + + /* update the status bar if item is valid */ + if (item) + SetWindowTextW(panel->hWndStatusBar, item->applet->info[item->id].szInfo); + } + else + SetWindowTextW(panel->hWndStatusBar, NULL); + + return 0; + + case WM_SIZE: + { + HDWP hdwp; + RECT sb; + + hdwp = BeginDeferWindowPos(2); + + if (hdwp == NULL) + break; + + GetClientRect(panel->hWndStatusBar, &sb); + + hdwp = DeferWindowPos(hdwp, panel->hWndListView, NULL, 0, 0, + LOWORD(lParam2), HIWORD(lParam2) - (sb.bottom - sb.top), + SWP_NOZORDER | SWP_NOMOVE); + + if (hdwp == NULL) + break; + + hdwp = DeferWindowPos(hdwp, panel->hWndStatusBar, NULL, 0, 0, + LOWORD(lParam2), LOWORD(lParam1), SWP_NOZORDER | SWP_NOMOVE); + + if (hdwp != NULL) + EndDeferWindowPos(hdwp); + + return 0; } + } } - return DefWindowProcA(hWnd, wMsg, lParam1, lParam2); + return DefWindowProcW(hWnd, wMsg, lParam1, lParam2); } static void Control_DoInterface(CPanel* panel, HWND hWnd, HINSTANCE hInst) { - WNDCLASSA wc; + WNDCLASSW wc; MSG msg; - const CHAR* appName = "Wine Control Panel"; + WCHAR appName[MAX_STRING_LEN]; + const WCHAR className[] = {'S','h','e','l','l','_','C','o','n','t','r','o', + 'l','_','W','n','d','C','l','a','s','s',0}; + + LoadStringW(shell32_hInstance, IDS_CPANEL_TITLE, appName, sizeof(appName) / sizeof(appName[0])); + wc.style = CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc = Control_WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(CPlApplet*); - wc.hInstance = hInst; + wc.hInstance = panel->hInst = hInst; wc.hIcon = 0; - wc.hCursor = 0; + wc.hCursor = LoadCursorW( 0, (LPWSTR)IDC_ARROW ); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = "Shell_Control_WndClass"; + wc.lpszClassName = className; - if (!RegisterClassA(&wc)) return; + if (!RegisterClassW(&wc)) return; - CreateWindowExA(0, wc.lpszClassName, appName, + CreateWindowExW(0, wc.lpszClassName, appName, WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, NULL, hInst, panel); if (!panel->hWnd) return; - if (!panel->first) { - /* FIXME appName & message should be localized */ - MessageBoxA(panel->hWnd, "Cannot load any applets", appName, MB_OK); - return; - } - - while (GetMessageA(&msg, panel->hWnd, 0, 0)) { + while (GetMessageW(&msg, panel->hWnd, 0, 0)) { TranslateMessage(&msg); - DispatchMessageA(&msg); + DispatchMessageW(&msg); } } diff --git a/dlls/shell32/cpanel.h b/dlls/shell32/cpanel.h index 05923f1bdbe..23ec5e538f2 100644 --- a/dlls/shell32/cpanel.h +++ b/dlls/shell32/cpanel.h @@ -1,6 +1,7 @@ /* Control Panel management * * Copyright 2001 Eric Pouech + * Copyright 2008 Owen Rudge * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,13 +34,21 @@ typedef struct CPlApplet { } CPlApplet; typedef struct CPanel { - CPlApplet* first; /* linked list */ - HWND hWnd; - unsigned status; - CPlApplet* clkApplet; - unsigned clkSP; + CPlApplet* first; + HWND hWnd; + HINSTANCE hInst; + unsigned total_subprogs; + HWND hWndListView; + HIMAGELIST hImageListLarge; + HIMAGELIST hImageListSmall; + HWND hWndStatusBar; } CPanel; +/* structure to reference an individual control panel item */ +typedef struct CPlItem { + CPlApplet *applet; + unsigned id; +} CPlItem; CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel); CPlApplet* Control_UnloadApplet(CPlApplet* applet); diff --git a/dlls/shell32/cpanelfolder.c b/dlls/shell32/cpanelfolder.c index 93a79c5c50f..d3934a03017 100644 --- a/dlls/shell32/cpanelfolder.c +++ b/dlls/shell32/cpanelfolder.c @@ -40,6 +40,7 @@ #include "ole2.h" #include "shlguid.h" +#include "commctrl.h" #include "cpanel.h" #include "enumidlist.h" #include "pidl.h" diff --git a/dlls/shell32/shell32_Bg.rc b/dlls/shell32/shell32_Bg.rc index c969f02a694..8624231c6bc 100644 --- a/dlls/shell32/shell32_Bg.rc +++ b/dlls/shell32/shell32_Bg.rc @@ -90,6 +90,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Ãîëåìè èêîíè", FCIDM_SHVIEW_BIGICON + MENUITEM "&Ìàëêè èêîíè", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Ñïèñúê", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Ïîäðîáíîñòè", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Èçáîð íà ïàïêà" @@ -219,4 +241,8 @@ STRINGTABLE IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Ca.rc b/dlls/shell32/shell32_Ca.rc index c332c0ef3fe..930d6a9086d 100644 --- a/dlls/shell32/shell32_Ca.rc +++ b/dlls/shell32/shell32_Ca.rc @@ -40,6 +40,29 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Quant a %s" @@ -68,3 +91,10 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Cancel", IDCANCEL, 116, 63, 50, 14, WS_TABSTOP PUSHBUTTON "&Browse...", 12288, 170, 63, 50, 14, WS_TABSTOP } + +STRINGTABLE +{ + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" +} diff --git a/dlls/shell32/shell32_Cn.rc b/dlls/shell32/shell32_Cn.rc index cef902c0dab..3c65a63c9c1 100644 --- a/dlls/shell32/shell32_Cn.rc +++ b/dlls/shell32/shell32_Cn.rc @@ -41,6 +41,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "¹ØÓÚ %s" @@ -82,6 +104,10 @@ BEGIN IDS_SHV_COLUMN7 "Ê£Óà¿Õ¼ä" IDS_SHV_COLUMN8 "Name" /*FIXME*/ IDS_SHV_COLUMN9 "Comments" /*FIXME*/ + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" END #pragma code_page(default) diff --git a/dlls/shell32/shell32_Cs.rc b/dlls/shell32/shell32_Cs.rc index af8cfeeb281..90b32ae408b 100644 --- a/dlls/shell32/shell32_Cs.rc +++ b/dlls/shell32/shell32_Cs.rc @@ -94,6 +94,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Vedle sebe", FCIDM_SHVIEW_BIGICON + MENUITEM "&Ikony", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Seznam", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Podrobnosti", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Procházet..." @@ -189,4 +211,8 @@ STRINGTABLE IDS_SHV_COLUMN_DELDATE "Date deleted" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Da.rc b/dlls/shell32/shell32_Da.rc index c525c887fd8..49e7b2b2496 100644 --- a/dlls/shell32/shell32_Da.rc +++ b/dlls/shell32/shell32_Da.rc @@ -91,6 +91,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Store Ikoner", FCIDM_SHVIEW_BIGICON + MENUITEM "S&må Ikoner", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Liste", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detaljer", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Vælg folder" @@ -251,6 +273,10 @@ STRINGTABLE IDS_CDBURN_AREA "Lokale indstillinger\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "Ny Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_De.rc b/dlls/shell32/shell32_De.rc index e8ac7cb3be6..afe7534b50e 100644 --- a/dlls/shell32/shell32_De.rc +++ b/dlls/shell32/shell32_De.rc @@ -91,6 +91,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Große Symbole", FCIDM_SHVIEW_BIGICON + MENUITEM "&Kleine Symbole", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Liste", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Verzeichnis auswählen" @@ -250,6 +272,10 @@ STRINGTABLE IDS_CDBURN_AREA "Lokale Einstellungen\\Anwendungsdaten\\Microsoft\\CD Burning" IDS_NEWFOLDER "Neuer Ordner" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_En.rc b/dlls/shell32/shell32_En.rc index ce843747156..f752e6d641a 100644 --- a/dlls/shell32/shell32_En.rc +++ b/dlls/shell32/shell32_En.rc @@ -90,6 +90,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Browse for Folder" @@ -256,6 +278,10 @@ STRINGTABLE IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Eo.rc b/dlls/shell32/shell32_Eo.rc index e5f16b0a52e..40c503ae228 100644 --- a/dlls/shell32/shell32_Eo.rc +++ b/dlls/shell32/shell32_Eo.rc @@ -93,6 +93,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Grandaj Ikonoj", FCIDM_SHVIEW_BIGICON + MENUITEM "Malgrandaj Ikonoj", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Listo", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detale", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Foliu Dosierujon" @@ -236,4 +258,8 @@ STRINGTABLE IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Es.rc b/dlls/shell32/shell32_Es.rc index b54546096bb..17773fc088f 100644 --- a/dlls/shell32/shell32_Es.rc +++ b/dlls/shell32/shell32_Es.rc @@ -91,6 +91,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Iconos &grandes", FCIDM_SHVIEW_BIGICON + MENUITEM "Iconos &pequeños", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lista", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detalles", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Explorar carpeta" @@ -251,6 +273,10 @@ STRINGTABLE IDS_CDBURN_AREA "Configuración local\\Datos de programa\\Microsoft\\CD Burning" IDS_NEWFOLDER "Nueva carpeta" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Fi.rc b/dlls/shell32/shell32_Fi.rc index acd143f73e2..f0a1b5ad282 100644 --- a/dlls/shell32/shell32_Fi.rc +++ b/dlls/shell32/shell32_Fi.rc @@ -90,6 +90,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Suuret kuvakkeet", FCIDM_SHVIEW_BIGICON + MENUITEM "&Pienet kuvakkeet", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lista", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Tiedot", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Valitse kansio" @@ -218,4 +240,8 @@ STRINGTABLE IDS_CDBURN_AREA "Paikalliset asetukset\\Ohjelmien tiedot\\Microsoft\\CD Burning" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Fr.rc b/dlls/shell32/shell32_Fr.rc index face6f1ac15..4b235807af9 100644 --- a/dlls/shell32/shell32_Fr.rc +++ b/dlls/shell32/shell32_Fr.rc @@ -96,6 +96,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Grandes icônes", FCIDM_SHVIEW_BIGICON + MENUITEM "&Petites icônes", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Liste", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Détails", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Parcourir les dossiers" @@ -256,6 +278,10 @@ STRINGTABLE IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "Nouveau dossier" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Hu.rc b/dlls/shell32/shell32_Hu.rc index 00ac5549450..814e0c646ca 100644 --- a/dlls/shell32/shell32_Hu.rc +++ b/dlls/shell32/shell32_Hu.rc @@ -40,6 +40,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Névjegy: %s" @@ -68,3 +90,10 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Mégse", IDCANCEL, 116, 63, 50, 14, WS_TABSTOP PUSHBUTTON "&Tallózás...", 12288, 170, 63, 50, 14, WS_TABSTOP } + +STRINGTABLE +{ + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" +} diff --git a/dlls/shell32/shell32_It.rc b/dlls/shell32/shell32_It.rc index 1afdc328dd4..baa00778a6e 100644 --- a/dlls/shell32/shell32_It.rc +++ b/dlls/shell32/shell32_It.rc @@ -92,6 +92,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Icone &Grandi", FCIDM_SHVIEW_BIGICON + MENUITEM "Icone &Piccole", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lista", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Dettagli", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Sfoglia Cartella" @@ -220,4 +242,8 @@ STRINGTABLE IDS_COOKIES "Cookies" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Ja.rc b/dlls/shell32/shell32_Ja.rc index b858dc5915f..281f30f93d8 100644 --- a/dlls/shell32/shell32_Ja.rc +++ b/dlls/shell32/shell32_Ja.rc @@ -84,6 +84,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "‘å‚«‚ȱ²ºÝ(&G)", FCIDM_SHVIEW_BIGICON + MENUITEM "�¬‚³‚ȱ²ºÝ(&M)", FCIDM_SHVIEW_SMALLICON + MENUITEM "ˆê——(&L)", FCIDM_SHVIEW_LISTVIEW + MENUITEM "�Ú�×(&D)", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + STRINGTABLE { /* columns in the shellview */ @@ -113,6 +135,10 @@ STRINGTABLE IDS_VIEW_DETAILS "�Ú�×(&D)" IDS_SELECT "‘I‘ð" IDS_OPEN "ŠJ‚­" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 diff --git a/dlls/shell32/shell32_Ko.rc b/dlls/shell32/shell32_Ko.rc index 0f5fb8f3dc3..de3cf61b0ab 100644 --- a/dlls/shell32/shell32_Ko.rc +++ b/dlls/shell32/shell32_Ko.rc @@ -91,6 +91,29 @@ MENUITEM " END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Å« ¾ÆÀÌÄÜ(&G)", FCIDM_SHVIEW_BIGICON + MENUITEM "ÀÛÀº ¾ÆÀÌÄÜ(&M)", FCIDM_SHVIEW_SMALLICON + MENUITEM "¸ñ·Ï(&L)", FCIDM_SHVIEW_LISTVIEW + MENUITEM "ÀÚ¼¼È÷(&D)", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Æú´õ Ž»ö" @@ -260,6 +283,10 @@ IDS_COMMON_VIDEO " IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "»õ Æú´õ" + +IDS_CPANEL_TITLE "Wine Control Panel" +IDS_CPANEL_NAME "Name" +IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Nl.rc b/dlls/shell32/shell32_Nl.rc index e90e78ae40e..ac3f18beaf8 100644 --- a/dlls/shell32/shell32_Nl.rc +++ b/dlls/shell32/shell32_Nl.rc @@ -92,6 +92,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Grote Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "&Kleine Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lijst", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Bladeren naar Map" @@ -258,6 +280,10 @@ STRINGTABLE IDS_CDBURN_AREA "Lokale Instellingen\\Applicatie Data\\Microsoft\\CD Branden" IDS_NEWFOLDER "Nieuwe Map" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_No.rc b/dlls/shell32/shell32_No.rc index e646f31d20d..0a8fc20dac7 100644 --- a/dlls/shell32/shell32_No.rc +++ b/dlls/shell32/shell32_No.rc @@ -90,6 +90,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Store ikoner", FCIDM_SHVIEW_BIGICON + MENUITEM "&Små ikoner", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Liste", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detaljer", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Bla etter mappe" @@ -256,6 +278,10 @@ STRINGTABLE IDS_CDBURN_AREA "Lokale innstillinger\\Programdata\\Microsoft\\CD Burning" IDS_NEWFOLDER "Ny mappe" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Pl.rc b/dlls/shell32/shell32_Pl.rc index 3df49c87f75..420c1671990 100644 --- a/dlls/shell32/shell32_Pl.rc +++ b/dlls/shell32/shell32_Pl.rc @@ -91,6 +91,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Du¿e Ikony", FCIDM_SHVIEW_BIGICON + MENUITEM "&Ma³e Ikony", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lista", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Szczegó³y", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Wybierz folder" @@ -257,6 +279,10 @@ STRINGTABLE IDS_CDBURN_AREA "Ustawienia lokalne\\Dane aplikacji\\Microsoft\\Nagrywanie dysków CD" IDS_NEWFOLDER "Nowy Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Pt.rc b/dlls/shell32/shell32_Pt.rc index 2934b414657..ed8b5291628 100644 --- a/dlls/shell32/shell32_Pt.rc +++ b/dlls/shell32/shell32_Pt.rc @@ -139,6 +139,53 @@ BEGIN END END +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE + +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Ícones &grandes", FCIDM_SHVIEW_BIGICON + MENUITEM "Ícones &pequenos", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lista", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detalhes", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN + +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Ícones &grandes", FCIDM_SHVIEW_BIGICON + MENUITEM "Ícones &pequenos", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Lista", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detalhes", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN @@ -312,6 +359,10 @@ STRINGTABLE IDS_CDBURN_AREA "Configurações locais\\Dados de aplicativos\\Microsoft\\CD Burning" IDS_NEWFOLDER "Nova Pasta" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE @@ -399,4 +450,8 @@ STRINGTABLE IDS_CDBURN_AREA "Definições locais\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "Nova Pasta" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Ro.rc b/dlls/shell32/shell32_Ro.rc index 0694d2f2042..25b45655be3 100644 --- a/dlls/shell32/shell32_Ro.rc +++ b/dlls/shell32/shell32_Ro.rc @@ -93,6 +93,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Pictograme &mari", FCIDM_SHVIEW_BIGICON + MENUITEM "Pictograme m&ici", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Listă", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Detailii", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Selectare dosar" @@ -209,6 +231,10 @@ STRINGTABLE IDS_PROGRAMS "Meniu Start\\Programe" IDS_PERSONAL "Documentele mele" IDS_FAVORITES "Favorite" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Ru.rc b/dlls/shell32/shell32_Ru.rc index d68f1d51639..b643cac0a10 100644 --- a/dlls/shell32/shell32_Ru.rc +++ b/dlls/shell32/shell32_Ru.rc @@ -91,6 +91,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Áîëüøèå çíà÷êè", FCIDM_SHVIEW_BIGICON + MENUITEM "&Ìåëêèå çíà÷êè", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Ñïèñîê", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Ïîäðîáíî", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Îáçîð" @@ -251,4 +273,8 @@ STRINGTABLE IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Si.rc b/dlls/shell32/shell32_Si.rc index 18ce18113ca..b7a9137975d 100644 --- a/dlls/shell32/shell32_Si.rc +++ b/dlls/shell32/shell32_Si.rc @@ -92,6 +92,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Ve&like ikone", FCIDM_SHVIEW_BIGICON + MENUITEM "&Male ikone", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Seznam", FCIDM_SHVIEW_LISTVIEW + MENUITEM "Po&drobnosti", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Brskanje po mapah" @@ -251,6 +273,10 @@ STRINGTABLE IDS_CDBURN_AREA "Lokalne nastavitve\\Podatki programov\\Microsoft\\Zapisovanje CD-jev" IDS_NEWFOLDER "Nova mapa" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } STRINGTABLE diff --git a/dlls/shell32/shell32_Sk.rc b/dlls/shell32/shell32_Sk.rc index 83529394ba1..2df139d97d2 100644 --- a/dlls/shell32/shell32_Sk.rc +++ b/dlls/shell32/shell32_Sk.rc @@ -40,6 +40,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "O programe %s" @@ -81,4 +103,8 @@ BEGIN IDS_SHV_COLUMN7 "Ve¾kos� k dispozícii" IDS_SHV_COLUMN8 "Name" /*FIXME*/ IDS_SHV_COLUMN9 "Comments" /*FIXME*/ + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" END diff --git a/dlls/shell32/shell32_Sv.rc b/dlls/shell32/shell32_Sv.rc index e77a37a83f2..c65af34dc1e 100644 --- a/dlls/shell32/shell32_Sv.rc +++ b/dlls/shell32/shell32_Sv.rc @@ -40,6 +40,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Om %s" @@ -68,3 +90,10 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Avbryt", IDCANCEL, 116, 63, 50, 14, WS_TABSTOP PUSHBUTTON "&Bläddra...", 12288, 170, 63, 50, 14, WS_TABSTOP } + +STRINGTABLE +{ + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" +} diff --git a/dlls/shell32/shell32_Tr.rc b/dlls/shell32/shell32_Tr.rc index 9617e850e61..dc2ea3096fd 100644 --- a/dlls/shell32/shell32_Tr.rc +++ b/dlls/shell32/shell32_Tr.rc @@ -90,6 +90,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Bü&yük Simgeler", FCIDM_SHVIEW_BIGICON + MENUITEM "Kü&çük Simgeler", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Liste", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Ayrýntýlý", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Dizine Gözat" @@ -219,4 +241,8 @@ STRINGTABLE IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Uk.rc b/dlls/shell32/shell32_Uk.rc index eef1dc05397..624368ad3fe 100644 --- a/dlls/shell32/shell32_Uk.rc +++ b/dlls/shell32/shell32_Uk.rc @@ -90,6 +90,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "&Âåëèê³ ²êîíêè", FCIDM_SHVIEW_BIGICON + MENUITEM "&Ìàë³ ²êîíêè", FCIDM_SHVIEW_SMALLICON + MENUITEM "&Ñïèñîê", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Ïîäðîáèö³", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK CAPTION "Îãëÿä äî òåêè" @@ -185,4 +207,8 @@ STRINGTABLE IDS_SHV_COLUMN_DELDATE "Date deleted" IDS_NEWFOLDER "New Folder" + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" } diff --git a/dlls/shell32/shell32_Wa.rc b/dlls/shell32/shell32_Wa.rc index 8821290c100..393d65d6ea4 100644 --- a/dlls/shell32/shell32_Wa.rc +++ b/dlls/shell32/shell32_Wa.rc @@ -45,6 +45,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Å dfait di %s" @@ -73,3 +95,10 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Cancel", IDCANCEL, 116, 63, 50, 14, WS_TABSTOP PUSHBUTTON "&Browse...", 12288, 170, 63, 50, 14, WS_TABSTOP } + +STRINGTABLE +{ + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" +} diff --git a/dlls/shell32/shell32_Zh.rc b/dlls/shell32/shell32_Zh.rc index 763c279bea7..cb3839a4fcc 100644 --- a/dlls/shell32/shell32_Zh.rc +++ b/dlls/shell32/shell32_Zh.rc @@ -41,6 +41,28 @@ BEGIN END END +MENU_CPANEL MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_CPANEL_EXIT + END + + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons", FCIDM_SHVIEW_BIGICON + MENUITEM "S&mall Icons", FCIDM_SHVIEW_SMALLICON + MENUITEM "&List", FCIDM_SHVIEW_LISTVIEW + MENUITEM "&Details", FCIDM_SHVIEW_REPORTVIEW + END + + POPUP "&Help" + BEGIN + MENUITEM "&About Control Panel...", IDM_CPANEL_ABOUT + END +END + SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 220, 152 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "êPì¶ %s" @@ -82,6 +104,10 @@ BEGIN IDS_SHV_COLUMN7 "Ê£ðN¿Õég" IDS_SHV_COLUMN8 "Name" /*FIXME*/ IDS_SHV_COLUMN9 "Comments" /*FIXME*/ + + IDS_CPANEL_TITLE "Wine Control Panel" + IDS_CPANEL_NAME "Name" + IDS_CPANEL_DESCRIPTION "Description" END #pragma code_page(default) diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index fb0c309cd95..362a25a06ca 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -2139,7 +2139,7 @@ static void _SHCreateSymbolicLinks(void) const char *pszHome; HRESULT hr; const unsigned int num = sizeof(xdg_dirs) / sizeof(xdg_dirs[0]); - char ** xdg_results = NULL; + char ** xdg_results; char * xdg_desktop_dir; /* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */ @@ -2149,7 +2149,8 @@ static void _SHCreateSymbolicLinks(void) pszPersonal = wine_get_unix_file_name(wszTempPath); if (!pszPersonal) return; - XDG_UserDirLookup(xdg_dirs, num, &xdg_results); + hr = XDG_UserDirLookup(xdg_dirs, num, &xdg_results); + if (FAILED(hr)) xdg_results = NULL; pszHome = getenv("HOME"); if (pszHome && !stat(pszHome, &statFolder) && S_ISDIR(statFolder.st_mode)) { diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h index 90b1c767756..c6df4622e98 100644 --- a/dlls/shell32/shresdef.h +++ b/dlls/shell32/shresdef.h @@ -97,6 +97,10 @@ #define IDS_NEWFOLDER 142 +#define IDS_CPANEL_TITLE 143 +#define IDS_CPANEL_NAME 144 +#define IDS_CPANEL_DESCRIPTION 145 + #define IDS_RUNDLG_ERROR 160 #define IDS_RUNDLG_BROWSE_ERROR 161 #define IDS_RUNDLG_BROWSE_CAPTION 162 @@ -107,6 +111,11 @@ #define MENU_SHV_FILE 144 +#define MENU_CPANEL 200 +#define IDM_CPANEL_EXIT 201 +#define IDM_CPANEL_ABOUT 202 +#define IDM_CPANEL_APPLET_BASE 210 + /* Note: this string is referenced from the registry*/ #define IDS_RECYCLEBIN_FOLDER_NAME 8964 diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c index 5b905b4db70..710920d77c7 100644 --- a/dlls/shell32/tests/shelllink.c +++ b/dlls/shell32/tests/shelllink.c @@ -33,6 +33,9 @@ #include "shell32_test.h" +#ifndef SLDF_HAS_LOGO3ID +# define SLDF_HAS_LOGO3ID 0x00000800 /* not available in the Vista SDK */ +#endif typedef void (WINAPI *fnILFree)(LPITEMIDLIST); typedef BOOL (WINAPI *fnILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST); @@ -49,7 +52,6 @@ static const GUID _IID_IShellLinkDataList = { { 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1 } }; -static const WCHAR lnkfile[]= { 'C',':','\\','t','e','s','t','.','l','n','k',0 }; static const WCHAR notafile[]= { 'C',':','\\','n','o','n','e','x','i','s','t','e','n','t','\\','f','i','l','e',0 }; @@ -224,19 +226,19 @@ static void test_get_set(void) ok(!lstrcmp(buffer, "C:\\nonexistent\\file"), "case doesn't match\n"); r = IShellLinkA_SetPath(sl, "\"c:\\foo"); - ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r); + ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r); r = IShellLinkA_SetPath(sl, "\"\"c:\\foo"); - ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r); + ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r); r = IShellLinkA_SetPath(sl, "c:\\foo\""); - ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r); + ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r); r = IShellLinkA_SetPath(sl, "\"\"c:\\foo\""); - ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r); + ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r); r = IShellLinkA_SetPath(sl, "\"\"c:\\foo\"\""); - ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r); + ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r); /* Test Getting / Setting the arguments */ strcpy(buffer,"garbage"); @@ -494,6 +496,12 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo) static void test_load_save(void) { + WCHAR lnkfile[MAX_PATH]; + static const WCHAR lnkfile_name[] = { '\\', 't', 'e', 's', 't', '.', 'l', 'n', 'k', '\0' }; + + char lnkfileA[MAX_PATH]; + static const char lnkfileA_name[] = "\\test.lnk"; + lnk_desc_t desc; char mypath[MAX_PATH]; char mydir[MAX_PATH]; @@ -508,6 +516,12 @@ static void test_load_save(void) return; } + /* Don't used a fixed path for the test.lnk file */ + GetTempPathW(MAX_PATH, lnkfile); + lstrcatW(lnkfile, lnkfile_name); + GetTempPathA(MAX_PATH, lnkfileA); + lstrcatA(lnkfileA, lnkfileA_name); + /* Save an empty .lnk file */ memset(&desc, 0, sizeof(desc)); create_lnk(lnkfile, &desc, 0); @@ -608,8 +622,8 @@ static void test_load_save(void) */ /* DeleteFileW is not implemented on Win9x */ - r=DeleteFileA("c:\\test.lnk"); - ok(r, "failed to delete link (%d)\n", GetLastError()); + r=DeleteFileA(lnkfileA); + ok(r, "failed to delete link '%s' (%d)\n", lnkfileA, GetLastError()); } static void test_datalink(void) diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index 4b1bf1b6483..644d611c11a 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -38,6 +38,7 @@ /* Needed to get SEE_MASK_NOZONECHECKS with the PSDK */ #define NTDDI_WINXPSP1 0x05010100 #define NTDDI_VERSION NTDDI_WINXPSP1 +#define _WIN32_WINNT 0x0501 #include "wtypes.h" #include "winbase.h" @@ -200,7 +201,7 @@ static int shell_execute_ex(DWORD mask, LPCSTR operation, LPCSTR file, * ***/ -static void create_test_association(const char* extension) +static BOOL create_test_association(const char* extension) { HKEY hkey, hkey_shell; char class[MAX_PATH]; @@ -209,19 +210,25 @@ static void create_test_association(const char* extension) sprintf(class, "shlexec%s", extension); rc=RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, NULL); - assert(rc==ERROR_SUCCESS); + if (rc != ERROR_SUCCESS) + return FALSE; + rc=RegSetValueEx(hkey, NULL, 0, REG_SZ, (LPBYTE) class, strlen(class)+1); - assert(rc==ERROR_SUCCESS); + ok(rc==ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc); CloseHandle(hkey); rc=RegCreateKeyEx(HKEY_CLASSES_ROOT, class, 0, NULL, 0, KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, NULL, &hkey, NULL); - assert(rc==ERROR_SUCCESS); + ok(rc==ERROR_SUCCESS, "RegCreateKeyEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc); + rc=RegCreateKeyEx(hkey, "shell", 0, NULL, 0, KEY_CREATE_SUB_KEY, NULL, &hkey_shell, NULL); - assert(rc==ERROR_SUCCESS); + ok(rc==ERROR_SUCCESS, "RegCreateKeyEx 'shell' failed, expected ERROR_SUCCESS, got %d\n", rc); + CloseHandle(hkey); CloseHandle(hkey_shell); + + return TRUE; } /* Based on RegDeleteTreeW from dlls/advapi32/registry.c */ @@ -830,7 +837,11 @@ static void test_find_executable(void) const filename_tests_t* test; int rc; - create_test_association(".sfe"); + if (!create_test_association(".sfe")) + { + skip("Unable to create association for '.sfe'\n"); + return; + } create_test_verb(".sfe", "Open", 1, "%1"); /* Don't test FindExecutable(..., NULL), it always crashes */ @@ -858,7 +869,11 @@ static void test_find_executable(void) delete_test_association(".sfe"); - create_test_association(".shl"); + if (!create_test_association(".shl")) + { + skip("Unable to create association for '.shl'\n"); + return; + } create_test_verb(".shl", "Open", 0, "Open"); sprintf(filename, "%s\\test file.shl", tmpdir); @@ -1233,7 +1248,11 @@ static void test_dde(void) test = dde_tests; while (test->command) { - create_test_association(".sde"); + if (!create_test_association(".sde")) + { + skip("Unable to create association for '.sfe'\n"); + return; + } create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec, test->application, test->topic, test->ifexec); hszApplication = DdeCreateStringHandleA(ddeInst, test->application ? @@ -1383,7 +1402,11 @@ static void test_dde_default_app(void) test = dde_default_app_tests; while (test->command) { - create_test_association(".sde"); + if (!create_test_association(".sde")) + { + skip("Unable to create association for '.sde'\n"); + return; + } sprintf(params, test->command, tmpdir); create_test_verb_dde(".sde", "Open", 1, params, "[test]", NULL, "shlexec", NULL); @@ -1543,7 +1566,11 @@ static void init_test(void) create_lnk(lnkfile, &desc, 0); /* Create a basic association suitable for most tests */ - create_test_association(".shlexec"); + if (!create_test_association(".shlexec")) + { + skip("Unable to create association for '.shlexec'\n"); + return; + } create_test_verb(".shlexec", "Open", 0, "Open \"%1\""); create_test_verb(".shlexec", "NoQuotes", 0, "NoQuotes %1"); create_test_verb(".shlexec", "LowerL", 0, "LowerL %l"); diff --git a/dlls/snmpapi/tests/util.c b/dlls/snmpapi/tests/util.c index 1aa245f5d1e..780556c0228 100644 --- a/dlls/snmpapi/tests/util.c +++ b/dlls/snmpapi/tests/util.c @@ -220,6 +220,7 @@ static void test_SnmpUtilOidCpyFree(void) ok(ret, "SnmpUtilOidCpy failed\n"); ok(src.idLength == dst.idLength, "SnmpUtilOidCpy failed\n"); ok(!memcmp(src.ids, dst.ids, dst.idLength * sizeof(UINT)), "SnmpUtilOidCpy failed\n"); + SnmpUtilOidFree(&dst); /* These crashes under win98 */ if(0) diff --git a/dlls/user32/dde_misc.c b/dlls/user32/dde_misc.c index 049deaee685..d99cdcf746f 100644 --- a/dlls/user32/dde_misc.c +++ b/dlls/user32/dde_misc.c @@ -1658,9 +1658,10 @@ void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) pConvNext = pConv->next; if (DdeCmpStringHandles(pConv->hszService, hszService) == 0) { + HWND client = pConv->hwndClient, server = pConv->hwndServer; WDML_RemoveConv(pConv, WDML_SERVER_SIDE); /* don't care about return code (whether client window is present or not) */ - PostMessageW(pConv->hwndClient, WM_DDE_TERMINATE, (WPARAM)pConv->hwndServer, 0); + PostMessageW(client, WM_DDE_TERMINATE, (WPARAM)server, 0); } } if (pServer == pInstance->servers) diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index 436bd16a717..65f708e6383 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -623,6 +623,8 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags ) if (child) hwnd = *child; + if (hwnd == GetDesktopWindow()) return whole_rgn; + if (whole_rgn) { RECT client, update; diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c index e00c45ec7d0..6b165600c79 100644 --- a/dlls/user32/tests/cursoricon.c +++ b/dlls/user32/tests/cursoricon.c @@ -504,7 +504,7 @@ static void test_CreateIcon(void) static const BYTE bmp_bits[1024]; HICON hIcon; HBITMAP hbmMask, hbmColor; - BITMAPINFO bmpinfo; + BITMAPINFO *bmpinfo; ICONINFO info; HDC hdc; void *bits; @@ -585,22 +585,22 @@ static void test_CreateIcon(void) /* test creating an icon from a DIB section */ - memset( &bmpinfo, 0, sizeof(bmpinfo) ); - bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmpinfo.bmiHeader.biWidth = 32; - bmpinfo.bmiHeader.biHeight = 32; - bmpinfo.bmiHeader.biPlanes = 1; - bmpinfo.bmiHeader.biBitCount = 8; - bmpinfo.bmiHeader.biCompression = BI_RGB; - hbmColor = CreateDIBSection( hdc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); + bmpinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO,bmiColors[256])); + bmpinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmpinfo->bmiHeader.biWidth = 32; + bmpinfo->bmiHeader.biHeight = 32; + bmpinfo->bmiHeader.biPlanes = 1; + bmpinfo->bmiHeader.biBitCount = 8; + bmpinfo->bmiHeader.biCompression = BI_RGB; + hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); ok(hbmColor != NULL, "Expected a handle to the DIB\n"); if (bits) - memset( bits, 0x55, 32 * 32 * bmpinfo.bmiHeader.biBitCount / 8 ); - bmpinfo.bmiHeader.biBitCount = 1; - hbmMask = CreateDIBSection( hdc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); + memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 ); + bmpinfo->bmiHeader.biBitCount = 1; + hbmMask = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); ok(hbmMask != NULL, "Expected a handle to the DIB\n"); if (bits) - memset( bits, 0x55, 32 * 32 * bmpinfo.bmiHeader.biBitCount / 8 ); + memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 ); info.fIcon = TRUE; info.xHotspot = 8; @@ -614,11 +614,11 @@ static void test_CreateIcon(void) DestroyIcon(hIcon); DeleteObject(hbmColor); - bmpinfo.bmiHeader.biBitCount = 16; - hbmColor = CreateDIBSection( hdc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); + bmpinfo->bmiHeader.biBitCount = 16; + hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); ok(hbmColor != NULL, "Expected a handle to the DIB\n"); if (bits) - memset( bits, 0x55, 32 * 32 * bmpinfo.bmiHeader.biBitCount / 8 ); + memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 ); info.fIcon = TRUE; info.xHotspot = 8; @@ -632,11 +632,11 @@ static void test_CreateIcon(void) DestroyIcon(hIcon); DeleteObject(hbmColor); - bmpinfo.bmiHeader.biBitCount = 32; - hbmColor = CreateDIBSection( hdc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); + bmpinfo->bmiHeader.biBitCount = 32; + hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); ok(hbmColor != NULL, "Expected a handle to the DIB\n"); if (bits) - memset( bits, 0x55, 32 * 32 * bmpinfo.bmiHeader.biBitCount / 8 ); + memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 ); info.fIcon = TRUE; info.xHotspot = 8; @@ -651,6 +651,7 @@ static void test_CreateIcon(void) DeleteObject(hbmMask); DeleteObject(hbmColor); + HeapFree( GetProcessHeap(), 0, bmpinfo ); ReleaseDC(0, hdc); } diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 37198d3b53a..7227eb7f924 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -45,6 +45,7 @@ */ #define _WIN32_WINNT 0x401 +#define _WIN32_IE 0x0500 #include #include diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c index 1aa2eb6688c..4e879c6e0ab 100644 --- a/dlls/user32/tests/menu.c +++ b/dlls/user32/tests/menu.c @@ -1691,7 +1691,7 @@ static struct menu_mouse_tests_s { static void send_key(WORD wVk) { TEST_INPUT i[2]; - memset(&i, 0, 2*sizeof(INPUT)); + memset(i, 0, sizeof(i)); i[0].type = i[1].type = INPUT_KEYBOARD; i[0].u.ki.wVk = i[1].u.ki.wVk = wVk; i[1].u.ki.dwFlags = KEYEVENTF_KEYUP; @@ -1706,10 +1706,10 @@ static void click_menu(HANDLE hWnd, struct menu_item_pair_s *mi) RECT r; int screen_w = GetSystemMetrics(SM_CXSCREEN); int screen_h = GetSystemMetrics(SM_CYSCREEN); + BOOL ret = GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r); + if(!ret) return; - GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r); - - memset(&i, 0, 3*sizeof(INPUT)); + memset(i, 0, sizeof(i)); i[0].type = i[1].type = i[2].type = INPUT_MOUSE; i[0].u.mi.dx = i[1].u.mi.dx = i[2].u.mi.dx = ((r.left + 5) * 65535) / screen_w; diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c index f899dab143a..60a07af5b89 100644 --- a/dlls/user32/tests/sysparams.c +++ b/dlls/user32/tests/sysparams.c @@ -23,7 +23,8 @@ #include #undef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 /* For SPI_GETMOUSEHOVERWIDTH and more */ +#define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */ +#define _WIN32_IE 0x0700 #include "wine/test.h" #include "windef.h" diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index acfd4810d55..a05b5f756d8 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -434,8 +434,11 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset ) } if (wndPtr == WND_DESKTOP) break; if (wndPtr == WND_OTHER_PROCESS) goto other_process; - offset->x += wndPtr->rectClient.left; - offset->y += wndPtr->rectClient.top; + if (wndPtr->parent) + { + offset->x += wndPtr->rectClient.left; + offset->y += wndPtr->rectClient.top; + } hwnd = wndPtr->parent; WIN_ReleasePtr( wndPtr ); } @@ -455,8 +458,11 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset ) } if (wndPtr == WND_DESKTOP) break; if (wndPtr == WND_OTHER_PROCESS) goto other_process; - offset->x -= wndPtr->rectClient.left; - offset->y -= wndPtr->rectClient.top; + if (wndPtr->parent) + { + offset->x -= wndPtr->rectClient.left; + offset->y -= wndPtr->rectClient.top; + } hwnd = wndPtr->parent; WIN_ReleasePtr( wndPtr ); } diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index 070590468eb..67a4ea9c884 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -615,22 +615,26 @@ static void test_ScriptXtoX(void) * This routine tests the ScriptXtoCP and ScriptCPtoX functions using static variables * ****************************************************************************************/ { + static const WCHAR test[] = {'t', 'e', 's', 't',0}; + SCRIPT_ITEM items[2]; int iX, iCP; int cChars; int cGlyphs; WORD pwLogClust[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; SCRIPT_VISATTR psva[10]; int piAdvance[10] = {200, 190, 210, 180, 170, 204, 189, 195, 212, 203}; - SCRIPT_ANALYSIS psa; int piCP, piX; int piTrailing; BOOL fTrailing; HRESULT hr; + hr = ScriptItemize(test, lstrlenW(test), sizeof(items)/sizeof(items[0]), NULL, NULL, items, NULL); + ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr); + iX = -1; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); if (piTrailing) ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP); @@ -640,7 +644,7 @@ static void test_ScriptXtoX(void) iX = 1954; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); if (piTrailing) /* win2k3 */ ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP); @@ -650,7 +654,7 @@ static void test_ScriptXtoX(void) iX = 779; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); ok(piCP == 3 || piCP == -1, /* win2k3 */ @@ -660,7 +664,7 @@ static void test_ScriptXtoX(void) iX = 780; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); ok(piCP == 3 || piCP == -1, /* win2k3 */ @@ -670,7 +674,7 @@ static void test_ScriptXtoX(void) iX = 868; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); ok(piCP == 4 || piCP == -1, /* win2k3 */ @@ -679,7 +683,7 @@ static void test_ScriptXtoX(void) iX = 0; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); ok(piCP == 0 || piCP == 10, /* win2k3 */ @@ -688,14 +692,14 @@ static void test_ScriptXtoX(void) iX = 195; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); ok(piCP == 0, "iX=%d should return piCP=0 not %d\n", iX, piCP); iX = 196; cChars = 10; cGlyphs = 10; - hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing); ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr); ok(piCP == 1 || piCP == 0, /* win2k3 */ @@ -705,7 +709,7 @@ static void test_ScriptXtoX(void) fTrailing = FALSE; cChars = 10; cGlyphs = 10; - hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX); ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr); ok(piX == 976 || piX == 100, /* win2k3 */ @@ -715,7 +719,7 @@ static void test_ScriptXtoX(void) fTrailing = TRUE; cChars = 10; cGlyphs = 10; - hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX); ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr); ok(piX == 1171 || piX == 80, /* win2k3 */ @@ -725,7 +729,7 @@ static void test_ScriptXtoX(void) fTrailing = FALSE; cChars = 10; cGlyphs = 10; - hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX); ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr); ok(piX == 1171 || piX == 80, /* win2k3 */ @@ -735,7 +739,7 @@ static void test_ScriptXtoX(void) fTrailing = FALSE; cChars = 10; cGlyphs = 10; - hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX); ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr); ok(piX == 1953 || piX == 0, /* win2k3 */ @@ -745,7 +749,7 @@ static void test_ScriptXtoX(void) fTrailing = TRUE; cChars = 10; cGlyphs = 10; - hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX); ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr); ok(piX == 1953 || piX == 0, /* win2k3 */ diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index ef9c08a2522..cf66c94b174 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -382,7 +382,7 @@ static void test_GetCurrentThemeName(void) hRes = pGetCurrentThemeName(currentTheme, 2, NULL, 0, NULL, 0); if (bThemeActive) todo_wine - ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes); + ok(hRes == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes); else ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); ok( GetLastError() == 0xdeadbeef, @@ -396,7 +396,7 @@ static void test_GetCurrentThemeName(void) currentSize, sizeof(currentSize) / sizeof(WCHAR)); if (bThemeActive) todo_wine - ok( LOWORD(hRes) == ERROR_INSUFFICIENT_BUFFER, "Expected 0x8007007A, got 0x%08x\n", hRes); + ok(hRes == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got 0x%08x\n", hRes); else ok( hRes == E_PROP_ID_UNSUPPORTED, "Expected E_PROP_ID_UNSUPPORTED, got 0x%08x\n", hRes); ok( GetLastError() == 0xdeadbeef, diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 83a7ed8aa7b..2de05bfce5d 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -816,6 +816,30 @@ static void shader_arb_color_correction(SHADER_OPCODE_ARG* arg) { } break; + case WINED3DFMT_ATI2N: + /* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha, + * which means the first one is replicated accross .rgb, and the 2nd one is in + * .a. We need the 2nd in .g + * + * GL_EXT_texture_compression_rgtc returns the values in .rg, however, they + * are swapped compared to d3d. So swap red and green. + */ + if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) { + shader_addline(arg->buffer, "SWZ %s, %s, %c, %c, 1, 0;\n", + reg, reg, writemask[2], writemask[1]); + } else { + if(strlen(writemask) == 5) { + shader_addline(arg->buffer, "MOV %s.%c, %s.%c;\n", + reg, writemask[2], reg, writemask[4]); + } else if(strlen(writemask) == 2) { + /* Nothing to do */ + } else { + /* This is bad: We have VL, but we need VU */ + FIXME("2 or 3 components sampled from a converted ATI2N texture\n"); + } + } + break; + /* stupid compiler */ default: break; @@ -1694,15 +1718,30 @@ void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { unsigned int i; if ((curOpcode->opcode == WINED3DSIO_MOV && dst_regtype == WINED3DSPR_ADDR) || curOpcode->opcode == WINED3DSIO_MOVA) { + memset(tmpLine, 0, sizeof(tmpLine)); if(shader->rel_offset) { - memset(tmpLine, 0, sizeof(tmpLine)); vshader_program_add_param(arg, src[0], TRUE, tmpLine); shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", tmpLine); shader_addline(buffer, "ARL A0.x, TMP.x;\n"); - return; } else { - strcpy(tmpLine, "ARL"); + /* Apple's ARB_vertex_program implementation does not accept an ARL source argument + * with more than one component. Thus replicate the first source argument over all + * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc) + */ + DWORD parm = src[0] & ~(WINED3DVS_SWIZZLE_MASK); + if((src[0] & WINED3DVS_X_W) == WINED3DVS_X_W) { + parm |= WINED3DVS_X_W | WINED3DVS_Y_W | WINED3DVS_Z_W | WINED3DVS_W_W; + } else if((src[0] & WINED3DVS_X_Z) == WINED3DVS_X_Z) { + parm |= WINED3DVS_X_Z | WINED3DVS_Y_Z | WINED3DVS_Z_Z | WINED3DVS_W_Z; + } else if((src[0] & WINED3DVS_X_Y) == WINED3DVS_X_Y) { + parm |= WINED3DVS_X_Y | WINED3DVS_Y_Y | WINED3DVS_Z_Y | WINED3DVS_W_Y; + } else if((src[0] & WINED3DVS_X_X) == WINED3DVS_X_X) { + parm |= WINED3DVS_X_X | WINED3DVS_Y_X | WINED3DVS_Z_X | WINED3DVS_W_X; + } + vshader_program_add_param(arg, parm, TRUE, tmpLine); + shader_addline(buffer, "ARL A0.x, %s;\n", tmpLine); } + return; } else strcpy(tmpLine, curOpcode->glname); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index efa1006d07f..ca81f3a5aca 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -113,10 +113,28 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand /* This function takes care of WineD3D pixel format selection. */ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DFORMAT ColorFormat, WINED3DFORMAT DepthStencilFormat, BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible) { - int iPixelFormat=0; + int iPixelFormat=0, matchtry; short redBits, greenBits, blueBits, alphaBits, colorBits; short depthBits=0, stencilBits=0; + struct match_type { + BOOL require_aux; + BOOL exact_alpha; + BOOL exact_color; + } matches[] = { + /* First, try without aux buffers - this is the most common cause + * for not finding a pixel format. Also some drivers(the open source ones) + * only offer 32 bit ARB pixel formats. First try without an exact alpha + * match, then try without an exact alpha and color match. + */ + { TRUE, TRUE, TRUE }, + { FALSE, TRUE, TRUE }, + { TRUE, FALSE, TRUE }, + { TRUE, FALSE, FALSE }, + { FALSE, FALSE, TRUE }, + { FALSE, FALSE, FALSE }, + }; + int i = 0; int nCfgs = This->adapter->nCfgs; WineD3D_PixelFormat *cfgs = This->adapter->cfgs; @@ -149,70 +167,85 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DF getDepthStencilBits(DepthStencilFormat, &depthBits, &stencilBits); } - /* Find a pixel format which EXACTLY matches our requirements (except for depth) */ - for(i=0; iadapter->cfgs[i]; - - /* For now only accept RGBA formats. Perhaps some day we will - * allow floating point formats for pbuffers. */ - if(cfgs->iPixelType != WGL_TYPE_RGBA_ARB) - continue; - - /* In window mode (!pbuffer) we need a window drawable format and double buffering. */ - if(!pbuffer && !(cfgs->windowDrawable && cfgs->doubleBuffer)) - continue; - - /* We like to have aux buffers in backbuffer mode */ - if(auxBuffers && !cfgs->auxBuffers) - continue; - - /* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */ - if(pbuffer && (!cfgs->pbufferDrawable || cfgs->doubleBuffer)) - continue; - - if(cfgs->redSize != redBits) - continue; - if(cfgs->greenSize != greenBits) - continue; - if(cfgs->blueSize != blueBits) - continue; - if(cfgs->alphaSize != alphaBits) - continue; - - /* We try to locate a format which matches our requirements exactly. In case of - * depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */ - if(cfgs->depthSize < depthBits) - continue; - else if(cfgs->depthSize > depthBits) - exactDepthMatch = FALSE; - - /* In all cases make sure the number of stencil bits matches our requirements - * even when we don't need stencil because it could affect performance EXCEPT - * on cards which don't offer depth formats without stencil like the i915 drivers - * on Linux. */ - if(stencilBits != cfgs->stencilSize && !(This->adapter->brokenStencil && stencilBits <= cfgs->stencilSize)) - continue; - - /* Check multisampling support */ - if(cfgs->numSamples != numSamples) - continue; - - /* When we have passed all the checks then we have found a format which matches our - * requirements. Note that we only check for a limit number of capabilities right now, - * so there can easily be a dozen of pixel formats which appear to be the 'same' but - * can still differ in things like multisampling, stereo, SRGB and other flags. - */ + for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])); matchtry++) { + for(i=0; iadapter->cfgs[i]; + + /* For now only accept RGBA formats. Perhaps some day we will + * allow floating point formats for pbuffers. */ + if(cfgs->iPixelType != WGL_TYPE_RGBA_ARB) + continue; + + /* In window mode (!pbuffer) we need a window drawable format and double buffering. */ + if(!pbuffer && !(cfgs->windowDrawable && cfgs->doubleBuffer)) + continue; + + /* We like to have aux buffers in backbuffer mode */ + if(auxBuffers && !cfgs->auxBuffers && matches[matchtry].require_aux) + continue; + + /* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */ + if(pbuffer && (!cfgs->pbufferDrawable || cfgs->doubleBuffer)) + continue; + + if(matches[matchtry].exact_color) { + if(cfgs->redSize != redBits) + continue; + if(cfgs->greenSize != greenBits) + continue; + if(cfgs->blueSize != blueBits) + continue; + } else { + if(cfgs->redSize < redBits) + continue; + if(cfgs->greenSize < greenBits) + continue; + if(cfgs->blueSize < blueBits) + continue; + } + if(matches[matchtry].exact_alpha) { + if(cfgs->alphaSize != alphaBits) + continue; + } else { + if(cfgs->alphaSize < alphaBits) + continue; + } - /* Exit the loop as we have found a format :) */ - if(exactDepthMatch) { - iPixelFormat = cfgs->iPixelFormat; - break; - } else if(!iPixelFormat) { - /* In the end we might end up with a format which doesn't exactly match our depth - * requirements. Accept the first format we found because formats with higher iPixelFormat - * values tend to have more extended capabilities (e.g. multisampling) which we don't need. */ - iPixelFormat = cfgs->iPixelFormat; + /* We try to locate a format which matches our requirements exactly. In case of + * depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */ + if(cfgs->depthSize < depthBits) + continue; + else if(cfgs->depthSize > depthBits) + exactDepthMatch = FALSE; + + /* In all cases make sure the number of stencil bits matches our requirements + * even when we don't need stencil because it could affect performance EXCEPT + * on cards which don't offer depth formats without stencil like the i915 drivers + * on Linux. */ + if(stencilBits != cfgs->stencilSize && !(This->adapter->brokenStencil && stencilBits <= cfgs->stencilSize)) + continue; + + /* Check multisampling support */ + if(cfgs->numSamples != numSamples) + continue; + + /* When we have passed all the checks then we have found a format which matches our + * requirements. Note that we only check for a limit number of capabilities right now, + * so there can easily be a dozen of pixel formats which appear to be the 'same' but + * can still differ in things like multisampling, stereo, SRGB and other flags. + */ + + /* Exit the loop as we have found a format :) */ + if(exactDepthMatch) { + iPixelFormat = cfgs->iPixelFormat; + break; + } else if(!iPixelFormat) { + /* In the end we might end up with a format which doesn't exactly match our depth + * requirements. Accept the first format we found because formats with higher iPixelFormat + * values tend to have more extended capabilities (e.g. multisampling) which we don't need. */ + iPixelFormat = cfgs->iPixelFormat; + } } } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 131e1b76fa0..0a6bd2b7ba4 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -459,11 +459,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, object->changed.pixelShader = TRUE; /* Pixel Shader Constants */ - for (i = 0; i < GL_LIMITS(vshader_constantsF); ++i) { + for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i) { object->contained_ps_consts_f[i] = i; object->changed.pixelShaderConstantsF[i] = TRUE; } - object->num_contained_ps_consts_f = GL_LIMITS(vshader_constantsF); + object->num_contained_ps_consts_f = GL_LIMITS(pshader_constantsF); for (i = 0; i < MAX_CONST_B; ++i) { object->contained_ps_consts_b[i] = i; object->changed.pixelShaderConstantsB[i] = TRUE; @@ -641,7 +641,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)) >> 1; } else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 || - Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5) { + Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5 || + Format == WINED3DFMT_ATI2N) { Size = ((max(Width,4) * tableEntry->bpp) * max(Height,4)); } else { /* The pitch is a multiple of 4 bytes */ diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c9b5c09e07b..a95c7783e3d 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -59,6 +59,7 @@ static const struct { {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE, 0 }, {"GL_ATI_envmap_bumpmap", ATI_ENVMAP_BUMPMAP, 0 }, {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER, 0 }, + {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC, 0 }, /* ARB */ {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT, 0 }, @@ -104,6 +105,7 @@ static const struct { {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 }, {"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) }, {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 }, + {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC, 0 }, {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 }, {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 }, {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 }, @@ -2371,6 +2373,15 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat) TRACE_(d3d_caps)("[FAILED]\n"); return FALSE; + /* Vendor specific formats */ + case WINED3DFMT_ATI2N: + if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) { + TRACE_(d3d_caps)("[OK]\n"); + return TRUE; + } + TRACE_(d3d_caps)("[FAILED]\n"); + return FALSE; + case WINED3DFMT_UNKNOWN: return FALSE; @@ -3253,8 +3264,8 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, pCaps->MaxStreamStride = 1024; /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */ - pCaps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET; - /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */ + pCaps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET | + WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET; pCaps->MaxNpatchTessellationLevel = 0; pCaps->MasterAdapterOrdinal = 0; pCaps->AdapterOrdinalInGroup = 0; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index da13d1d99a0..ce84ea75fb9 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1344,6 +1344,41 @@ static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) { } break; + case WINED3DFMT_ATI2N: + /* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha, + * which means the first one is replicated accross .rgb, and the 2nd one is in + * .a. We need the 2nd in .g + * + * GL_EXT_texture_compression_rgtc returns the values in .rg, however, they + * are swapped compared to d3d. So swap red and green. + */ + mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param); + mask_size = shader_glsl_get_write_mask_size(mask); + if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) { + if(mask_size >= 2) { + shader_addline(arg->buffer, "%s.%c%c = %s.%c%c;\n", + dst_param.reg_name, dst_param.mask_str[1], + dst_param.mask_str[2], + dst_param.reg_name, dst_param.mask_str[2], + dst_param.mask_str[1]); + } else { + FIXME("%u components sampled from a converted ATI2N texture\n", mask_size); + } + } else { + if(mask_size == 4) { + /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */ + shader_addline(arg->buffer, "%s.%c = %s.%c;\n", + dst_param.reg_name, dst_param.mask_str[2], + dst_param.reg_name, dst_param.mask_str[4]); + } else if(mask_size == 1) { + /* Nothing to do */ + } else { + FIXME("%u components sampled from a converted ATI2N texture\n", mask_size); + /* This is bad: We have .r[gb], but we need .ra */ + } + } + break; + /* stupid compiler */ default: break; diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 6844a9b88ea..e2176785553 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -65,6 +65,391 @@ void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, W } } +typedef struct { + GLenum input[3]; + GLenum mapping[3]; + GLenum component_usage[3]; +} tex_op_args; + +static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) { + switch (d3dta) { + case WINED3DTA_DIFFUSE: + return GL_PRIMARY_COLOR_NV; + + case WINED3DTA_CURRENT: + if (stage) return GL_SPARE0_NV; + else return GL_PRIMARY_COLOR_NV; + + case WINED3DTA_TEXTURE: + if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx; + else return GL_PRIMARY_COLOR_NV; + + case WINED3DTA_TFACTOR: + return GL_CONSTANT_COLOR0_NV; + + case WINED3DTA_SPECULAR: + return GL_SECONDARY_COLOR_NV; + + case WINED3DTA_TEMP: + return GL_SPARE1_NV; + + case WINED3DTA_CONSTANT: + /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */ + FIXME("WINED3DTA_CONSTANT, not properly supported.\n"); + return GL_CONSTANT_COLOR1_NV; + + default: + FIXME("Unrecognized texture arg %#x\n", d3dta); + return GL_TEXTURE; + } +} + +static GLenum invert_mapping(GLenum mapping) { + if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV; + else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV; + + FIXME("Unhandled mapping %#x\n", mapping); + return mapping; +} + +static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) { + /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should + * be used. */ + if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV; + else *mapping = GL_SIGNED_IDENTITY_NV; + + /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input + * should be used for all input components. */ + if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA; + else *component_usage = GL_RGB; + + *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx); +} + +void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface; + tex_op_args tex_op_args = {{0}, {0}, {0}}; + GLenum portion = is_alpha ? GL_ALPHA : GL_RGB; + GLenum target = GL_COMBINER0_NV + stage; + GLenum output; + IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* For GLINFO_LOCATION */ + + TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", + stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx); + + /* If a texture stage references an invalid texture unit the stage just + * passes through the result from the previous stage */ + if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) { + arg1 = WINED3DTA_CURRENT; + op = WINED3DTOP_SELECTARG1; + } + + get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0], + &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx); + get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1], + &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx); + get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2], + &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx); + + + if(dst == WINED3DTA_TEMP) { + output = GL_SPARE1_NV; + } else { + output = GL_SPARE0_NV; + } + + /* This is called by a state handler which has the gl lock held and a context for the thread */ + switch(op) + { + case WINED3DTOP_DISABLE: + /* Only for alpha */ + if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n"); + /* Input, prev_alpha*1 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_SELECTARG1: + case WINED3DTOP_SELECTARG2: + /* Input, arg*1 */ + if (op == WINED3DTOP_SELECTARG1) { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + } else { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + } + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATE: + case WINED3DTOP_MODULATE2X: + case WINED3DTOP_MODULATE4X: + /* Input, arg1*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + if (op == WINED3DTOP_MODULATE) { + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_MODULATE2X) { + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_MODULATE4X) { + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } + break; + + case WINED3DTOP_ADD: + case WINED3DTOP_ADDSIGNED: + case WINED3DTOP_ADDSIGNED2X: + /* Input, arg1*1+arg2*1 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + if (op == WINED3DTOP_ADD) { + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_ADDSIGNED) { + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_ADDSIGNED2X) { + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); + } + break; + + case WINED3DTOP_SUBTRACT: + /* Input, arg1*1+-arg2*1 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_ADDSMOOTH: + /* Input, arg1*1+(1-arg1)*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_BLENDDIFFUSEALPHA: + case WINED3DTOP_BLENDTEXTUREALPHA: + case WINED3DTOP_BLENDFACTORALPHA: + case WINED3DTOP_BLENDTEXTUREALPHAPM: + case WINED3DTOP_BLENDCURRENTALPHA: + { + GLenum alpha_src = GL_PRIMARY_COLOR_NV; + if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx); + else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); + else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx); + else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); + else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx); + else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op)); + + /* Input, arg1*alpha_src+arg2*(1-alpha_src) */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) + { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + } else { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); + } + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + } + + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_DOTPRODUCT3: + /* Input, arg1 . arg2 */ + /* FIXME: DX7 uses a different calculation? */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MULTIPLYADD: + /* Input, arg3*1+arg1*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_LERP: + /* Input, arg3*arg1+(1-arg3)*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_BUMPENVMAPLUMINANCE: + case WINED3DTOP_BUMPENVMAP: + if(GL_SUPPORT(NV_TEXTURE_SHADER)) { + /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to + * perform bump mapping and source from the current stage. Pretty much a SELECTARG2. + * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1 + * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage + */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + /* Always pass through to CURRENT, ignore temp arg */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + } + + default: + FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", + stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx); + } + + checkGLcall("set_tex_op_nvrc()\n"); + +} + + static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE; DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 01ee00614a0..a6903c6cd63 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1840,6 +1840,1115 @@ static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, Win } } +/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/ +#if defined (GL_VERSION_1_3) +# define useext(A) A +#elif defined (GL_EXT_texture_env_combine) +# define useext(A) A##_EXT +#elif defined (GL_ARB_texture_env_combine) +# define useext(A) A##_ARB +#endif + +static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) { + /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the + * input should be used for all input components. The WINED3DTA_COMPLEMENT + * flag specifies the complement of the input should be used. */ + BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE; + BOOL complement = arg & WINED3DTA_COMPLEMENT; + + /* Calculate the operand */ + if (complement) { + if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA; + else *operand = GL_ONE_MINUS_SRC_COLOR; + } else { + if (from_alpha) *operand = GL_SRC_ALPHA; + else *operand = GL_SRC_COLOR; + } + + /* Calculate the source */ + switch (arg & WINED3DTA_SELECTMASK) { + case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break; + case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break; + case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break; + case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break; + case WINED3DTA_SPECULAR: + /* + * According to the GL_ARB_texture_env_combine specs, SPECULAR is + * 'Secondary color' and isn't supported until base GL supports it + * There is no concept of temp registers as far as I can tell + */ + FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n"); + *source = GL_TEXTURE; + break; + default: + FIXME("Unrecognized texture arg %#x\n", arg); + *source = GL_TEXTURE; + break; + } +} + +/* Setup the texture operations texture stage states */ +static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) +{ + GLenum src1, src2, src3; + GLenum opr1, opr2, opr3; + GLenum comb_target; + GLenum src0_target, src1_target, src2_target; + GLenum opr0_target, opr1_target, opr2_target; + GLenum scal_target; + GLenum opr=0, invopr, src3_target, opr3_target; + BOOL Handled = FALSE; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* for GLINFO_LOCATION */ + + TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3); + + /* This is called by a state handler which has the gl lock held and a context for the thread */ + + /* Note: Operations usually involve two ars, src0 and src1 and are operations of + the form (a1 a2). However, some of the more complex operations + take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added + in a third parameter called a0. Therefore these are operations of the form + a0 a1 a2, i.e., the new parameter goes to the front. + + However, below we treat the new (a0) parameter as src2/opr2, so in the actual + functions below, expect their syntax to differ slightly to those listed in the + manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2 + This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */ + + if (isAlpha) { + comb_target = useext(GL_COMBINE_ALPHA); + src0_target = useext(GL_SOURCE0_ALPHA); + src1_target = useext(GL_SOURCE1_ALPHA); + src2_target = useext(GL_SOURCE2_ALPHA); + opr0_target = useext(GL_OPERAND0_ALPHA); + opr1_target = useext(GL_OPERAND1_ALPHA); + opr2_target = useext(GL_OPERAND2_ALPHA); + scal_target = GL_ALPHA_SCALE; + } + else { + comb_target = useext(GL_COMBINE_RGB); + src0_target = useext(GL_SOURCE0_RGB); + src1_target = useext(GL_SOURCE1_RGB); + src2_target = useext(GL_SOURCE2_RGB); + opr0_target = useext(GL_OPERAND0_RGB); + opr1_target = useext(GL_OPERAND1_RGB); + opr2_target = useext(GL_OPERAND2_RGB); + scal_target = useext(GL_RGB_SCALE); + } + + /* If a texture stage references an invalid texture unit the stage just + * passes through the result from the previous stage */ + if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) { + arg1 = WINED3DTA_CURRENT; + op = WINED3DTOP_SELECTARG1; + } + + /* From MSDN (WINED3DTSS_ALPHAARG1) : + The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage, + then the default argument is WINED3DTA_DIFFUSE. + FIXME? If texture added/removed, may need to reset back as well? */ + if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) { + get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1); + } else { + get_src_and_opr(arg1, isAlpha, &src1, &opr1); + } + get_src_and_opr(arg2, isAlpha, &src2, &opr2); + get_src_and_opr(arg3, isAlpha, &src3, &opr3); + + TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3); + + Handled = TRUE; /* Assume will be handled */ + + /* Other texture operations require special extensions: */ + if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { + if (isAlpha) { + opr = GL_SRC_ALPHA; + invopr = GL_ONE_MINUS_SRC_ALPHA; + src3_target = GL_SOURCE3_ALPHA_NV; + opr3_target = GL_OPERAND3_ALPHA_NV; + } else { + opr = GL_SRC_COLOR; + invopr = GL_ONE_MINUS_SRC_COLOR; + src3_target = GL_SOURCE3_RGB_NV; + opr3_target = GL_OPERAND3_RGB_NV; + } + switch (op) { + case WINED3DTOP_DISABLE: /* Only for alpha */ + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + break; + case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */ + case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */ + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + if (op == WINED3DTOP_SELECTARG1) { + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + } else { + glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); + checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); + } + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + break; + + case WINED3DTOP_MODULATE: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATE2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + case WINED3DTOP_MODULATE4X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); + checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); + break; + + case WINED3DTOP_ADD: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_ADDSIGNED: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_ADDSIGNED2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + + case WINED3DTOP_ADDSMOOTH: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); + checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_BLENDDIFFUSEALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)); + checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)); + checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDTEXTUREALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDFACTORALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)); + checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)); + checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDTEXTUREALPHAPM: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */ + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */ + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */ + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */ + glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); + checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); + switch (opr) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); + checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MULTIPLYADD: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, src2); + checkGLcall("GL_TEXTURE_ENV, src3_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_BUMPENVMAP: + { + } + + case WINED3DTOP_BUMPENVMAPLUMINANCE: + FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n"); + + default: + Handled = FALSE; + } + if (Handled) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV); + checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV"); + + return; + } + } /* GL_NV_texture_env_combine4 */ + + Handled = TRUE; /* Again, assume handled */ + switch (op) { + case WINED3DTOP_DISABLE: /* Only for alpha */ + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); + checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_SELECTARG1: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_SELECTARG2: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); + checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATE: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATE2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + case WINED3DTOP_MODULATE4X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); + checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); + break; + case WINED3DTOP_ADD: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_ADDSIGNED: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_ADDSIGNED2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + case WINED3DTOP_SUBTRACT: + if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else { + FIXME("This version of opengl does not support GL_SUBTRACT\n"); + } + break; + + case WINED3DTOP_BLENDDIFFUSEALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR)); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDTEXTUREALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDFACTORALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT)); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDCURRENTALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS)); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_DOTPRODUCT3: + if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB"); + } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT"); + } else { + FIXME("This version of opengl does not support GL_DOT3\n"); + } + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_LERP: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src3); + checkGLcall("GL_TEXTURE_ENV, src2_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_ADDSMOOTH: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_BLENDTEXTUREALPHAPM: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MULTIPLYADD: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src3); + checkGLcall("GL_TEXTURE_ENV, src1_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_BUMPENVMAPLUMINANCE: + if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { + /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although + * they check for the non-luminance cap flag. Well, give them what they asked + * for :-) + */ + WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n"); + } else { + Handled = FALSE; + break; + } + /* Fall through */ + case WINED3DTOP_BUMPENVMAP: + if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { + TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1); + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)"); + glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); + checkGLcall("GL_TEXTURE_ENV, src0_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + + Handled = TRUE; + break; + } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { + /* Technically texture shader support without register combiners is possible, but not expected to occur + * on real world cards, so for now a fixme should be enough + */ + FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n"); + } + default: + Handled = FALSE; + } + + if (Handled) { + BOOL combineOK = TRUE; + if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { + DWORD op2; + + if (isAlpha) { + op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP]; + } else { + op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP]; + } + + /* Note: If COMBINE4 in effect can't go back to combine! */ + switch (op2) { + case WINED3DTOP_ADDSMOOTH: + case WINED3DTOP_BLENDTEXTUREALPHAPM: + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + case WINED3DTOP_MULTIPLYADD: + /* Ignore those implemented in both cases */ + switch (op) { + case WINED3DTOP_SELECTARG1: + case WINED3DTOP_SELECTARG2: + combineOK = FALSE; + Handled = FALSE; + break; + default: + FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha); + return; + } + } + } + + if (combineOK) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)); + checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)"); + + return; + } + } + + /* After all the extensions, if still unhandled, report fixme */ + FIXME("Unhandled texture operation %s\n", debug_d3dtop(op)); +} + + static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE; DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; @@ -1999,6 +3108,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0); DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit]; BOOL generated; + int coordIdx; /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */ if(use_vs(stateblock->wineD3DDevice) || @@ -2021,13 +3131,14 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W return; } generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU; + coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1); set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw, - stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ? - stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType: + stateblock->wineD3DDevice->strided_streams.u.s.texCoords[coordIdx].dwStride ? + stateblock->wineD3DDevice->strided_streams.u.s.texCoords[coordIdx].dwType: WINED3DDECLTYPE_UNUSED); /* The sampler applying function calls us if this changes */ @@ -2516,7 +3627,7 @@ static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, W if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) && !isStateDirty(context, STATE_PIXELSHADER)) { shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context); - } + } } } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index cd312bcad4c..2227243aadc 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -93,7 +93,8 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { if (This->resource.format == WINED3DFMT_DXT1 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || - This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) { + This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5 || + This->resource.format == WINED3DFMT_ATI2N) { if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* We can assume this as the texture would not have been created otherwise */ FIXME("(%p) : Attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This); } else { @@ -232,7 +233,8 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { if (This->resource.format == WINED3DFMT_DXT1 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || - This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) { + This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5 || + This->resource.format == WINED3DFMT_ATI2N) { if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { FIXME("Using DXT1/3/5 without advertized support\n"); } else { @@ -296,7 +298,8 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, if (This->resource.format == WINED3DFMT_DXT1 || This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 || - This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) { + This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5 || + This->resource.format == WINED3DFMT_ATI2N) { /* glCompressedTexImage2D does not accept NULL pointers, so we cannot allocate a compressed texture without uploading data */ TRACE("Not allocating compressed surfaces, surface_upload_data will specify them\n"); @@ -3771,7 +3774,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { WINED3DFORMAT Format = This->resource.format; /** TODO: add support for non power two compressed textures **/ if (Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 - || Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5) { + || Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5 + || This->resource.format == WINED3DFMT_ATI2N) { FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n", This, This->currentDesc.Width, This->currentDesc.Height); return WINED3DERR_NOTAVAILABLE; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 40c154d9e0e..da08d4f0ece 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -112,6 +112,8 @@ static const StaticPixelFormatDesc formats[] = { {WINED3DFMT_INDEX16 ,0x0 ,0x0 ,0x0 ,0x0 ,2 ,0 ,0 ,FALSE }, {WINED3DFMT_INDEX32 ,0x0 ,0x0 ,0x0 ,0x0 ,4 ,0 ,0 ,FALSE }, {WINED3DFMT_Q16W16V16U16,0x0 ,0x0 ,0x0 ,0x0 ,8 ,0 ,0 ,FALSE }, + /* Vendor-specific formats */ + {WINED3DFMT_ATI2N ,0x0 ,0x0 ,0x0 ,0x0 ,1 ,0 ,0 ,TRUE }, }; typedef struct { @@ -260,6 +262,9 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { {WINED3DFMT_INDEX32 ,0 ,0 , 0, 0 ,0 ,0 }, {WINED3DFMT_Q16W16V16U16 ,GL_COLOR_INDEX ,GL_COLOR_INDEX , 0, GL_COLOR_INDEX ,GL_UNSIGNED_SHORT + ,0 }, + /* Vendor-specific formats */ + {WINED3DFMT_ATI2N ,0 ,0 , 0, GL_LUMINANCE_ALPHA ,GL_UNSIGNED_BYTE ,0 } }; @@ -390,6 +395,18 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info) */ } + if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) { + dst = getFmtIdx(WINED3DFMT_ATI2N); + gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; + gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; + gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N; + } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) { + dst = getFmtIdx(WINED3DFMT_ATI2N); + gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI; + gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI; + gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N; + } + return TRUE; } @@ -519,6 +536,7 @@ const char* debug_d3dformat(WINED3DFORMAT fmt) { FMT_TO_STR(WINED3DFMT_G32R32F); FMT_TO_STR(WINED3DFMT_A32B32G32R32F); FMT_TO_STR(WINED3DFMT_CxV8U8); + FMT_TO_STR(WINED3DFMT_ATI2N); #undef FMT_TO_STR default: { @@ -942,7 +960,7 @@ const char* debug_d3dtexturestate(DWORD state) { } } -static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) { +const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) { switch (d3dtop) { #define D3DTOP_TO_STR(u) case u: return #u D3DTOP_TO_STR(WINED3DTOP_DISABLE); @@ -1107,68 +1125,7 @@ GLenum CompareFunc(DWORD func) { } } -static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) { - switch (d3dta) { - case WINED3DTA_DIFFUSE: - return GL_PRIMARY_COLOR_NV; - - case WINED3DTA_CURRENT: - if (stage) return GL_SPARE0_NV; - else return GL_PRIMARY_COLOR_NV; - - case WINED3DTA_TEXTURE: - if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx; - else return GL_PRIMARY_COLOR_NV; - - case WINED3DTA_TFACTOR: - return GL_CONSTANT_COLOR0_NV; - - case WINED3DTA_SPECULAR: - return GL_SECONDARY_COLOR_NV; - - case WINED3DTA_TEMP: - return GL_SPARE1_NV; - - case WINED3DTA_CONSTANT: - /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */ - FIXME("WINED3DTA_CONSTANT, not properly supported.\n"); - return GL_CONSTANT_COLOR1_NV; - - default: - FIXME("Unrecognized texture arg %#x\n", d3dta); - return GL_TEXTURE; - } -} - -static GLenum invert_mapping(GLenum mapping) { - if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV; - else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV; - - FIXME("Unhandled mapping %#x\n", mapping); - return mapping; -} - -static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) { - /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should - * be used. */ - if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV; - else *mapping = GL_SIGNED_IDENTITY_NV; - - /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input - * should be used for all input components. */ - if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA; - else *component_usage = GL_RGB; - - *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx); -} - -typedef struct { - GLenum input[3]; - GLenum mapping[3]; - GLenum component_usage[3]; -} tex_op_args; - -static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) { +BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) { if (op == WINED3DTOP_DISABLE) return FALSE; if (This->stateBlock->textures[stage]) return FALSE; @@ -1182,1449 +1139,6 @@ static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP return FALSE; } -void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface; - tex_op_args tex_op_args = {{0}, {0}, {0}}; - GLenum portion = is_alpha ? GL_ALPHA : GL_RGB; - GLenum target = GL_COMBINER0_NV + stage; - GLenum output; - - TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", - stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx); - - /* If a texture stage references an invalid texture unit the stage just - * passes through the result from the previous stage */ - if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) { - arg1 = WINED3DTA_CURRENT; - op = WINED3DTOP_SELECTARG1; - } - - get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0], - &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx); - get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1], - &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx); - get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2], - &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx); - - - if(dst == WINED3DTA_TEMP) { - output = GL_SPARE1_NV; - } else { - output = GL_SPARE0_NV; - } - - /* This is called by a state handler which has the gl lock held and a context for the thread */ - switch(op) - { - case WINED3DTOP_DISABLE: - /* Only for alpha */ - if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n"); - /* Input, prev_alpha*1 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_SELECTARG1: - case WINED3DTOP_SELECTARG2: - /* Input, arg*1 */ - if (op == WINED3DTOP_SELECTARG1) { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - } else { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - } - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATE: - case WINED3DTOP_MODULATE2X: - case WINED3DTOP_MODULATE4X: - /* Input, arg1*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - if (op == WINED3DTOP_MODULATE) { - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_MODULATE2X) { - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_MODULATE4X) { - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } - break; - - case WINED3DTOP_ADD: - case WINED3DTOP_ADDSIGNED: - case WINED3DTOP_ADDSIGNED2X: - /* Input, arg1*1+arg2*1 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - if (op == WINED3DTOP_ADD) { - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_ADDSIGNED) { - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_ADDSIGNED2X) { - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); - } - break; - - case WINED3DTOP_SUBTRACT: - /* Input, arg1*1+-arg2*1 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_ADDSMOOTH: - /* Input, arg1*1+(1-arg1)*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_BLENDDIFFUSEALPHA: - case WINED3DTOP_BLENDTEXTUREALPHA: - case WINED3DTOP_BLENDFACTORALPHA: - case WINED3DTOP_BLENDTEXTUREALPHAPM: - case WINED3DTOP_BLENDCURRENTALPHA: - { - GLenum alpha_src = GL_PRIMARY_COLOR_NV; - if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx); - else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); - else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx); - else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); - else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx); - else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op)); - - /* Input, arg1*alpha_src+arg2*(1-alpha_src) */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) - { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - } else { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); - } - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - } - - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_DOTPRODUCT3: - /* Input, arg1 . arg2 */ - /* FIXME: DX7 uses a different calculation? */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MULTIPLYADD: - /* Input, arg3*1+arg1*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_LERP: - /* Input, arg3*arg1+(1-arg3)*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_BUMPENVMAPLUMINANCE: - case WINED3DTOP_BUMPENVMAP: - if(GL_SUPPORT(NV_TEXTURE_SHADER)) { - /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to - * perform bump mapping and source from the current stage. Pretty much a SELECTARG2. - * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1 - * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage - */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - /* Always pass through to CURRENT, ignore temp arg */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - } - - default: - FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", - stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx); - } - - checkGLcall("set_tex_op_nvrc()\n"); - -} - -static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) { - /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the - * input should be used for all input components. The WINED3DTA_COMPLEMENT - * flag specifies the complement of the input should be used. */ - BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE; - BOOL complement = arg & WINED3DTA_COMPLEMENT; - - /* Calculate the operand */ - if (complement) { - if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA; - else *operand = GL_ONE_MINUS_SRC_COLOR; - } else { - if (from_alpha) *operand = GL_SRC_ALPHA; - else *operand = GL_SRC_COLOR; - } - - /* Calculate the source */ - switch (arg & WINED3DTA_SELECTMASK) { - case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break; - case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break; - case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break; - case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break; - case WINED3DTA_SPECULAR: - /* - * According to the GL_ARB_texture_env_combine specs, SPECULAR is - * 'Secondary color' and isn't supported until base GL supports it - * There is no concept of temp registers as far as I can tell - */ - FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n"); - *source = GL_TEXTURE; - break; - default: - FIXME("Unrecognized texture arg %#x\n", arg); - *source = GL_TEXTURE; - break; - } -} - -/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/ -#if defined (GL_VERSION_1_3) -# define useext(A) A -# define combine_ext 1 -#elif defined (GL_EXT_texture_env_combine) -# define useext(A) A##_EXT -# define combine_ext 1 -#elif defined (GL_ARB_texture_env_combine) -# define useext(A) A##_ARB -# define combine_ext 1 -#else -# undef combine_ext -#endif - -#if !defined(combine_ext) -void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) -{ - FIXME("Requires opengl combine extensions to work\n"); - return; -} -#else -/* Setup the texture operations texture stage states */ -void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) -{ - GLenum src1, src2, src3; - GLenum opr1, opr2, opr3; - GLenum comb_target; - GLenum src0_target, src1_target, src2_target; - GLenum opr0_target, opr1_target, opr2_target; - GLenum scal_target; - GLenum opr=0, invopr, src3_target, opr3_target; - BOOL Handled = FALSE; - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - - TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3); - - /* This is called by a state handler which has the gl lock held and a context for the thread */ - - /* Note: Operations usually involve two ars, src0 and src1 and are operations of - the form (a1 a2). However, some of the more complex operations - take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added - in a third parameter called a0. Therefore these are operations of the form - a0 a1 a2, i.e., the new parameter goes to the front. - - However, below we treat the new (a0) parameter as src2/opr2, so in the actual - functions below, expect their syntax to differ slightly to those listed in the - manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2 - This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */ - - if (isAlpha) { - comb_target = useext(GL_COMBINE_ALPHA); - src0_target = useext(GL_SOURCE0_ALPHA); - src1_target = useext(GL_SOURCE1_ALPHA); - src2_target = useext(GL_SOURCE2_ALPHA); - opr0_target = useext(GL_OPERAND0_ALPHA); - opr1_target = useext(GL_OPERAND1_ALPHA); - opr2_target = useext(GL_OPERAND2_ALPHA); - scal_target = GL_ALPHA_SCALE; - } - else { - comb_target = useext(GL_COMBINE_RGB); - src0_target = useext(GL_SOURCE0_RGB); - src1_target = useext(GL_SOURCE1_RGB); - src2_target = useext(GL_SOURCE2_RGB); - opr0_target = useext(GL_OPERAND0_RGB); - opr1_target = useext(GL_OPERAND1_RGB); - opr2_target = useext(GL_OPERAND2_RGB); - scal_target = useext(GL_RGB_SCALE); - } - - /* If a texture stage references an invalid texture unit the stage just - * passes through the result from the previous stage */ - if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) { - arg1 = WINED3DTA_CURRENT; - op = WINED3DTOP_SELECTARG1; - } - - /* From MSDN (WINED3DTSS_ALPHAARG1) : - The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage, - then the default argument is WINED3DTA_DIFFUSE. - FIXME? If texture added/removed, may need to reset back as well? */ - if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) { - get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1); - } else { - get_src_and_opr(arg1, isAlpha, &src1, &opr1); - } - get_src_and_opr(arg2, isAlpha, &src2, &opr2); - get_src_and_opr(arg3, isAlpha, &src3, &opr3); - - TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3); - - Handled = TRUE; /* Assume will be handled */ - - /* Other texture operations require special extensions: */ - if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { - if (isAlpha) { - opr = GL_SRC_ALPHA; - invopr = GL_ONE_MINUS_SRC_ALPHA; - src3_target = GL_SOURCE3_ALPHA_NV; - opr3_target = GL_OPERAND3_ALPHA_NV; - } else { - opr = GL_SRC_COLOR; - invopr = GL_ONE_MINUS_SRC_COLOR; - src3_target = GL_SOURCE3_RGB_NV; - opr3_target = GL_OPERAND3_RGB_NV; - } - switch (op) { - case WINED3DTOP_DISABLE: /* Only for alpha */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - break; - case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */ - case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - if (op == WINED3DTOP_SELECTARG1) { - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - } else { - glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); - } - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - break; - - case WINED3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATE2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case WINED3DTOP_MODULATE4X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); - checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); - break; - - case WINED3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_ADDSIGNED2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - - case WINED3DTOP_ADDSMOOTH: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_BLENDDIFFUSEALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDTEXTUREALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDFACTORALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDTEXTUREALPHAPM: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */ - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */ - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */ - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */ - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MULTIPLYADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src2); - checkGLcall("GL_TEXTURE_ENV, src3_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_BUMPENVMAP: - { - } - - case WINED3DTOP_BUMPENVMAPLUMINANCE: - FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n"); - - default: - Handled = FALSE; - } - if (Handled) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV); - checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV"); - - return; - } - } /* GL_NV_texture_env_combine4 */ - - Handled = TRUE; /* Again, assume handled */ - switch (op) { - case WINED3DTOP_DISABLE: /* Only for alpha */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); - checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_SELECTARG1: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_SELECTARG2: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATE2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case WINED3DTOP_MODULATE4X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); - checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); - break; - case WINED3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_ADDSIGNED2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case WINED3DTOP_SUBTRACT: - if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else { - FIXME("This version of opengl does not support GL_SUBTRACT\n"); - } - break; - - case WINED3DTOP_BLENDDIFFUSEALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDTEXTUREALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDFACTORALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDCURRENTALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_DOTPRODUCT3: - if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB"); - } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT"); - } else { - FIXME("This version of opengl does not support GL_DOT3\n"); - } - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_LERP: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src3); - checkGLcall("GL_TEXTURE_ENV, src2_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_ADDSMOOTH: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_BLENDTEXTUREALPHAPM: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MULTIPLYADD: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src3); - checkGLcall("GL_TEXTURE_ENV, src1_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_BUMPENVMAPLUMINANCE: - if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { - /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although - * they check for the non-luminance cap flag. Well, give them what they asked - * for :-) - */ - WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n"); - } else { - Handled = FALSE; - break; - } - /* Fall through */ - case WINED3DTOP_BUMPENVMAP: - if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { - TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1); - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)"); - glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); - checkGLcall("GL_TEXTURE_ENV, src0_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - - Handled = TRUE; - break; - } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { - /* Technically texture shader support without register combiners is possible, but not expected to occur - * on real world cards, so for now a fixme should be enough - */ - FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n"); - } - default: - Handled = FALSE; - } - - if (Handled) { - BOOL combineOK = TRUE; - if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { - DWORD op2; - - if (isAlpha) { - op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP]; - } else { - op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP]; - } - - /* Note: If COMBINE4 in effect can't go back to combine! */ - switch (op2) { - case WINED3DTOP_ADDSMOOTH: - case WINED3DTOP_BLENDTEXTUREALPHAPM: - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - case WINED3DTOP_MULTIPLYADD: - /* Ignore those implemented in both cases */ - switch (op) { - case WINED3DTOP_SELECTARG1: - case WINED3DTOP_SELECTARG2: - combineOK = FALSE; - Handled = FALSE; - break; - default: - FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha); - return; - } - } - } - - if (combineOK) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)); - checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)"); - - return; - } - } - - /* After all the extensions, if still unhandled, report fixme */ - FIXME("Unhandled texture operation %s\n", debug_d3dtop(op)); -#undef GLINFO_LOCATION -} -#endif - /* Setup this textures matrix according to the texture flags*/ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype) { @@ -2714,6 +1228,7 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B glLoadMatrixf(mat); checkGLcall("glLoadMatrixf(mat)"); } +#undef GLINFO_LOCATION #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index 0802b1fa645..936ef57fbbe 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -159,6 +159,12 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte */ if(This->pDeclarationWine[i].Stream >= MAX_STREAMS) continue; + if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_UNUSED) { + WARN("The application tries to use WINED3DDECLTYPE_UNUSED, returning E_FAIL\n"); + /* The caller will release the vdecl, which will free This->pDeclarationWine */ + return E_FAIL; + } + if(This->pDeclarationWine[i].Offset & 0x3) { WARN("Declaration element %d is not 4 byte aligned(%d), returning E_FAIL\n", i, This->pDeclarationWine[i].Offset); HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fdbb4a3fb0a..61b29839c07 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1730,11 +1730,12 @@ const char *debug_fbostatus(GLenum status); const char *debug_glerror(GLenum error); const char *debug_d3dbasis(WINED3DBASISTYPE basis); const char *debug_d3ddegree(WINED3DDEGREETYPE order); +const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop); /* Routines for GL <-> D3D values */ GLenum StencilOp(DWORD op); GLenum CompareFunc(DWORD func); -void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3); +BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3); void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst); void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype); void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context); diff --git a/dlls/wineps.drv/Makefile.in b/dlls/wineps.drv/Makefile.in index ed8282bfa33..fef94aecbbb 100644 --- a/dlls/wineps.drv/Makefile.in +++ b/dlls/wineps.drv/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = wineps.drv IMPORTS = user32 gdi32 winspool advapi32 kernel32 -EXTRAINCL = @FREETYPEINCL@ +EXTRAINCL = @FREETYPEINCL@ @CUPSINCL@ SPEC_SRCS16 = wineps16.drv.spec diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c index 6fddb0ae85a..93482816587 100644 --- a/dlls/winex11.drv/dib.c +++ b/dlls/winex11.drv/dib.c @@ -3525,7 +3525,7 @@ static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr ) ERR("Out of memory!\n"); XDestroyImage( bmpImage ); wine_tsx11_unlock(); - return lines; + return 0; } } wine_tsx11_unlock(); @@ -3654,7 +3654,7 @@ static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr ) ERR("Out of memory!\n"); XDestroyImage( bmpImage ); wine_tsx11_unlock(); - return lines; + return 0; } } diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 92c13f0b168..773e8128b84 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -126,6 +126,19 @@ static const WORD main_key_scan_qwerty_jp106[MAIN_LEN] = 0x56 /* the 102nd key (actually to the right of l-shift) */ }; +static const WORD main_key_scan_qwerty_macjp[MAIN_LEN] = +{ + /* 1 2 3 4 5 6 7 8 9 0 - ^ \ */ + 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x7d, + /* q w e r t y u i o p @ [ */ + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B, + /* a s d f g h j k l ; : ] */ + 0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B, + /* z x c v b n m , . / */ + 0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, + 0x73 /* the 102nd key (actually to the right of l-shift) */ +}; + static const WORD main_key_vkey_qwerty[MAIN_LEN] = { @@ -147,6 +160,16 @@ static const WORD main_key_vkey_qwerty_jp106[MAIN_LEN] = VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */ }; +static const WORD main_key_vkey_qwerty_macjp[MAIN_LEN] = +{ +/* NOTE: this layout must concur with the scan codes layout above */ + '1','2','3','4','5','6','7','8','9','0',VK_OEM_MINUS,VK_OEM_7,VK_OEM_5, + 'Q','W','E','R','T','Y','U','I','O','P',VK_OEM_3,VK_OEM_4, + 'A','S','D','F','G','H','J','K','L',VK_OEM_PLUS,VK_OEM_1,VK_OEM_6, + 'Z','X','C','V','B','N','M',VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_2, + VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */ +}; + static const WORD main_key_vkey_qwerty_v2[MAIN_LEN] = { /* NOTE: this layout must concur with the scan codes layout above */ @@ -648,6 +671,15 @@ static const char main_key_JA_jp106[MAIN_LEN][4] = "\\_", }; +static const char main_key_JA_macjp[MAIN_LEN][4] = +{ + "1!","2\"","3#","4$","5%","6&","7'","8(","9)","0","-=","^~","\\|", + "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","@`","[{", + "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";+",":*","]}", + "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?", + "__", +}; + /*** Japanese pc98x1 keyboard layout ***/ static const char main_key_JA_pc98x1[MAIN_LEN][4] = { @@ -925,6 +957,7 @@ static const struct { {0x041a, "Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz}, {0x041a, "Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x0411, "Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty_jp106, &main_key_vkey_qwerty_jp106}, + {0x0411, "Japanese Mac keyboard layout", &main_key_JA_macjp, &main_key_scan_qwerty_macjp, &main_key_vkey_qwerty_macjp}, {0x0411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x041b, "Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, {0x041b, "Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty}, diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index 36e90057008..cb24782fa4b 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -1227,8 +1227,7 @@ static DWORD FTPFILE_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b return ERROR_SUCCESS; } - FIXME("Not implemented option %d\n", option); - return ERROR_INTERNET_INVALID_OPTION; + return INET_QueryOption(option, buffer, size, unicode); } static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read) @@ -1553,6 +1552,7 @@ static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, &iar, sizeof(INTERNET_ASYNC_RESULT)); } + if (!bSuccess) DeleteFileW(lpszNewFile); return bSuccess; } @@ -2194,8 +2194,7 @@ static DWORD FTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void return ERROR_SUCCESS; } - FIXME("Not implemented option %d\n", option); - return ERROR_INTERNET_INVALID_OPTION; + return INET_QueryOption(option, buffer, size, unicode); } static const HANDLEHEADERVtbl FTPSESSIONVtbl = { @@ -3275,8 +3274,7 @@ static DWORD FTPFINDNEXT_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, voi return ERROR_SUCCESS; } - FIXME("Not implemented option %d\n", option); - return ERROR_INTERNET_INVALID_OPTION; + return INET_QueryOption(option, buffer, size, unicode); } static DWORD FTPFINDNEXT_FindNextFileW(WININETHANDLEHEADER *hdr, void *data) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 38023a82221..2a786708e29 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1579,8 +1579,7 @@ static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b } } - FIXME("Not implemented option %d\n", option); - return ERROR_INTERNET_INVALID_OPTION; + return INET_QueryOption(option, buffer, size, unicode); } static DWORD HTTPREQ_SetOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD size) @@ -1889,15 +1888,10 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs, { LPWININETAPPINFOW hIC = NULL; LPWININETHTTPREQW lpwhr; - LPWSTR lpszCookies; - LPWSTR lpszUrl = NULL; LPWSTR lpszHostName = NULL; - DWORD nCookieSize; HINTERNET handle = NULL; - static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s',0}; static const WCHAR szHostForm[] = {'%','s',':','%','u',0}; DWORD len; - LPHTTPHEADERW Host; TRACE("-->\n"); @@ -2009,32 +2003,6 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs, if (NULL != hIC->lpszProxy && hIC->lpszProxy[0] != 0) HTTP_DealWithProxy( hIC, lpwhs, lpwhr ); - Host = HTTP_GetHeader(lpwhr,szHost); - - len = lstrlenW(Host->lpszValue) + strlenW(szUrlForm); - lpszUrl = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - sprintfW( lpszUrl, szUrlForm, Host->lpszValue ); - - if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) && - InternetGetCookieW(lpszUrl, NULL, NULL, &nCookieSize)) - { - int cnt = 0; - static const WCHAR szCookie[] = {'C','o','o','k','i','e',':',' ',0}; - static const WCHAR szcrlf[] = {'\r','\n',0}; - - lpszCookies = HeapAlloc(GetProcessHeap(), 0, (nCookieSize + 1 + 8)*sizeof(WCHAR)); - - cnt += sprintfW(lpszCookies, szCookie); - InternetGetCookieW(lpszUrl, NULL, lpszCookies + cnt, &nCookieSize); - strcatW(lpszCookies, szcrlf); - - HTTP_HttpAddRequestHeadersW(lpwhr, lpszCookies, strlenW(lpszCookies), - HTTP_ADDREQ_FLAG_ADD); - HeapFree(GetProcessHeap(), 0, lpszCookies); - } - HeapFree(GetProcessHeap(), 0, lpszUrl); - - INTERNET_SendCallback(&lpwhs->hdr, dwContext, INTERNET_STATUS_HANDLE_CREATED, &handle, sizeof(handle)); @@ -3152,6 +3120,37 @@ static BOOL HTTP_SecureProxyConnect(LPWININETHTTPREQW lpwhr) return TRUE; } +static void HTTP_InsertCookies(LPWININETHTTPREQW lpwhr) +{ + static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s',0}; + LPWSTR lpszCookies, lpszUrl = NULL; + DWORD nCookieSize, size; + LPHTTPHEADERW Host = HTTP_GetHeader(lpwhr,szHost); + + size = (strlenW(Host->lpszValue) + strlenW(szUrlForm)) * sizeof(WCHAR); + if (!(lpszUrl = HeapAlloc(GetProcessHeap(), 0, size))) return; + sprintfW( lpszUrl, szUrlForm, Host->lpszValue ); + + if (InternetGetCookieW(lpszUrl, NULL, NULL, &nCookieSize)) + { + int cnt = 0; + static const WCHAR szCookie[] = {'C','o','o','k','i','e',':',' ',0}; + static const WCHAR szcrlf[] = {'\r','\n',0}; + + size = sizeof(szCookie) + nCookieSize * sizeof(WCHAR) + sizeof(szcrlf); + if ((lpszCookies = HeapAlloc(GetProcessHeap(), 0, size))) + { + cnt += sprintfW(lpszCookies, szCookie); + InternetGetCookieW(lpszUrl, NULL, lpszCookies + cnt, &nCookieSize); + strcatW(lpszCookies, szcrlf); + + HTTP_HttpAddRequestHeadersW(lpwhr, lpszCookies, strlenW(lpszCookies), HTTP_ADDREQ_FLAG_ADD); + HeapFree(GetProcessHeap(), 0, lpszCookies); + } + } + HeapFree(GetProcessHeap(), 0, lpszUrl); +} + /*********************************************************************** * HTTP_HttpSendRequestW (internal) * @@ -3241,6 +3240,9 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders, HTTP_InsertAuthorization(lpwhr, lpwhr->pAuthInfo, szAuthorization); HTTP_InsertAuthorization(lpwhr, lpwhr->pProxyAuthInfo, szProxy_Authorization); + if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES)) + HTTP_InsertCookies(lpwhr); + /* add the headers the caller supplied */ if( lpszHeaders && dwHeaderLength ) { @@ -3472,8 +3474,7 @@ static DWORD HTTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, voi return ERROR_SUCCESS; } - FIXME("Not implemented option %d\n", option); - return ERROR_INTERNET_INVALID_OPTION; + return INET_QueryOption(option, buffer, size, unicode); } static const HANDLEHEADERVtbl HTTPSESSIONVtbl = { @@ -3835,7 +3836,10 @@ lend: if (bSuccess) return rc; else + { + HeapFree(GetProcessHeap(), 0, lpszRawHeaders); return 0; + } } diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index b05476553e5..a306fd2d5df 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -495,6 +495,8 @@ static VOID APPINFO_Destroy(WININETHANDLEHEADER *hdr) static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { + LPWININETAPPINFOW ai = (LPWININETAPPINFOW)hdr; + switch(option) { case INTERNET_OPTION_HANDLE_TYPE: TRACE("INTERNET_OPTION_HANDLE_TYPE\n"); @@ -505,10 +507,98 @@ static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *b *size = sizeof(DWORD); *(DWORD*)buffer = INTERNET_HANDLE_TYPE_INTERNET; return ERROR_SUCCESS; + + case INTERNET_OPTION_USER_AGENT: { + DWORD bufsize; + + TRACE("INTERNET_OPTION_USER_AGENT\n"); + + bufsize = *size; + + if (unicode) { + *size = (strlenW(ai->lpszAgent) + 1) * sizeof(WCHAR); + if(!buffer || bufsize < *size) + return ERROR_INSUFFICIENT_BUFFER; + + strcpyW(buffer, ai->lpszAgent); + }else { + *size = WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, NULL, 0, NULL, NULL); + if(!buffer || bufsize < *size) + return ERROR_INSUFFICIENT_BUFFER; + + WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, buffer, *size, NULL, NULL); + } + + return ERROR_SUCCESS; } - FIXME("Not implemented option %d\n", option); - return ERROR_INTERNET_INVALID_OPTION; + case INTERNET_OPTION_PROXY: + if (unicode) { + INTERNET_PROXY_INFOW *pi = (INTERNET_PROXY_INFOW *)buffer; + DWORD proxyBytesRequired = 0, proxyBypassBytesRequired = 0; + LPWSTR proxy, proxy_bypass; + + if (ai->lpszProxy) + proxyBytesRequired = (lstrlenW(ai->lpszProxy) + 1) * sizeof(WCHAR); + if (ai->lpszProxyBypass) + proxyBypassBytesRequired = (lstrlenW(ai->lpszProxyBypass) + 1) * sizeof(WCHAR); + if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired) + return ERROR_INSUFFICIENT_BUFFER; + + proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW)); + proxy_bypass = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired); + + pi->dwAccessType = ai->dwAccessType; + pi->lpszProxy = NULL; + pi->lpszProxyBypass = NULL; + if (ai->lpszProxy) { + lstrcpyW(proxy, ai->lpszProxy); + pi->lpszProxy = proxy; + } + + if (ai->lpszProxyBypass) { + lstrcpyW(proxy_bypass, ai->lpszProxyBypass); + pi->lpszProxyBypass = proxy_bypass; + } + + *size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired; + return ERROR_SUCCESS; + }else { + INTERNET_PROXY_INFOA *pi = (INTERNET_PROXY_INFOA *)buffer; + DWORD proxyBytesRequired = 0, proxyBypassBytesRequired = 0; + LPSTR proxy, proxy_bypass; + + if (ai->lpszProxy) + proxyBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->lpszProxy, -1, NULL, 0, NULL, NULL); + if (ai->lpszProxyBypass) + proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->lpszProxyBypass, -1, + NULL, 0, NULL, NULL); + if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired) + return ERROR_INSUFFICIENT_BUFFER; + + proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA)); + proxy_bypass = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired); + + pi->dwAccessType = ai->dwAccessType; + pi->lpszProxy = NULL; + pi->lpszProxyBypass = NULL; + if (ai->lpszProxy) { + WideCharToMultiByte(CP_ACP, 0, ai->lpszProxy, -1, proxy, proxyBytesRequired, NULL, NULL); + pi->lpszProxy = proxy; + } + + if (ai->lpszProxyBypass) { + WideCharToMultiByte(CP_ACP, 0, ai->lpszProxyBypass, -1, proxy_bypass, + proxyBypassBytesRequired, NULL, NULL); + pi->lpszProxyBypass = proxy_bypass; + } + + *size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired; + return ERROR_SUCCESS; + } + } + + return INET_QueryOption(option, buffer, size, unicode); } static const HANDLEHEADERVtbl APPINFOVtbl = { @@ -1929,315 +2019,137 @@ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, return FALSE; } -/*********************************************************************** - * INET_QueryOptionHelper (internal) - */ -static BOOL INET_QueryOptionHelper(BOOL bIsUnicode, HINTERNET hInternet, DWORD dwOption, - LPVOID lpBuffer, LPDWORD lpdwBufferLength) +DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) { - LPWININETHANDLEHEADER lpwhh; - BOOL bSuccess = FALSE; + switch(option) { + case INTERNET_OPTION_REQUEST_FLAGS: + TRACE("INTERNET_OPTION_REQUEST_FLAGS\n"); - TRACE("(%p, 0x%08x, %p, %p)\n", hInternet, dwOption, lpBuffer, lpdwBufferLength); + if (*size < sizeof(ULONG)) + return ERROR_INSUFFICIENT_BUFFER; - lpwhh = WININET_GetObject( hInternet ); + *(ULONG*)buffer = 4; + *size = sizeof(ULONG); - switch (dwOption) - { - case INTERNET_OPTION_REQUEST_FLAGS: - { - ULONG flags = 4; - TRACE("INTERNET_OPTION_REQUEST_FLAGS: %d\n", flags); - if (*lpdwBufferLength < sizeof(ULONG)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - memcpy(lpBuffer, &flags, sizeof(ULONG)); - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(ULONG); - break; - } + return ERROR_SUCCESS; - case INTERNET_OPTION_USER_AGENT: - { - DWORD required; - LPWININETAPPINFOW ai = (LPWININETAPPINFOW)lpwhh; + case INTERNET_OPTION_HTTP_VERSION: + if (*size < sizeof(HTTP_VERSION_INFO)) + return ERROR_INSUFFICIENT_BUFFER; - TRACE("INTERNET_OPTION_USER_AGENT\n"); + /* + * Presently hardcoded to 1.1 + */ + ((HTTP_VERSION_INFO*)buffer)->dwMajorVersion = 1; + ((HTTP_VERSION_INFO*)buffer)->dwMinorVersion = 1; + *size = sizeof(HTTP_VERSION_INFO); - if (!lpwhh || lpwhh->htype != INTERNET_HANDLE_TYPE_INTERNET) - { - INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); - return FALSE; - } - if (bIsUnicode) - { - required = (strlenW(ai->lpszAgent) + 1) * sizeof(WCHAR); - if (*lpdwBufferLength < required) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else if (lpBuffer) - { - strcpyW(lpBuffer, ai->lpszAgent); - bSuccess = TRUE; - } - } - else - { - required = WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, NULL, 0, NULL, NULL); - if (*lpdwBufferLength < required) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else if (lpBuffer) - { - WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, lpBuffer, required, NULL, NULL); - bSuccess = TRUE; - } - } - *lpdwBufferLength = required; - break; - } - case INTERNET_OPTION_HTTP_VERSION: - { - if (*lpdwBufferLength < sizeof(HTTP_VERSION_INFO)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - /* - * Presently hardcoded to 1.1 - */ - ((HTTP_VERSION_INFO*)lpBuffer)->dwMajorVersion = 1; - ((HTTP_VERSION_INFO*)lpBuffer)->dwMinorVersion = 1; - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(HTTP_VERSION_INFO); - break; - } - case INTERNET_OPTION_CONNECTED_STATE: - { - DWORD *pdwConnectedState = (DWORD *)lpBuffer; - FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n"); + return ERROR_SUCCESS; - if (*lpdwBufferLength < sizeof(*pdwConnectedState)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - *pdwConnectedState = INTERNET_STATE_CONNECTED; - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(*pdwConnectedState); - break; - } - case INTERNET_OPTION_PROXY: - { - LPWININETAPPINFOW lpwai = (LPWININETAPPINFOW)lpwhh; - WININETAPPINFOW wai; + case INTERNET_OPTION_CONNECTED_STATE: + FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n"); - if (lpwai == NULL) - { - TRACE("Getting global proxy info\n"); - memset(&wai, 0, sizeof(WININETAPPINFOW)); - INTERNET_ConfigureProxy( &wai ); - lpwai = &wai; - } + if (*size < sizeof(ULONG)) + return ERROR_INSUFFICIENT_BUFFER; - if (bIsUnicode) - { - INTERNET_PROXY_INFOW *pPI = (INTERNET_PROXY_INFOW *)lpBuffer; - DWORD proxyBytesRequired = 0, proxyBypassBytesRequired = 0; - - if (lpwai->lpszProxy) - proxyBytesRequired = (lstrlenW(lpwai->lpszProxy) + 1) * - sizeof(WCHAR); - if (lpwai->lpszProxyBypass) - proxyBypassBytesRequired = - (lstrlenW(lpwai->lpszProxyBypass) + 1) * sizeof(WCHAR); - if (*lpdwBufferLength < sizeof(INTERNET_PROXY_INFOW) + - proxyBytesRequired + proxyBypassBytesRequired) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - LPWSTR proxy = (LPWSTR)((LPBYTE)lpBuffer + - sizeof(INTERNET_PROXY_INFOW)); - LPWSTR proxy_bypass = (LPWSTR)((LPBYTE)lpBuffer + - sizeof(INTERNET_PROXY_INFOW) + - proxyBytesRequired); - - pPI->dwAccessType = lpwai->dwAccessType; - pPI->lpszProxy = NULL; - pPI->lpszProxyBypass = NULL; - if (lpwai->lpszProxy) - { - lstrcpyW(proxy, lpwai->lpszProxy); - pPI->lpszProxy = proxy; - } + *(ULONG*)buffer = INTERNET_STATE_CONNECTED; + *size = sizeof(ULONG); - if (lpwai->lpszProxyBypass) - { - lstrcpyW(proxy_bypass, lpwai->lpszProxyBypass); - pPI->lpszProxyBypass = proxy_bypass; - } - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(INTERNET_PROXY_INFOW) + - proxyBytesRequired + proxyBypassBytesRequired; - } - else - { - INTERNET_PROXY_INFOA *pPI = (INTERNET_PROXY_INFOA *)lpBuffer; - DWORD proxyBytesRequired = 0, proxyBypassBytesRequired = 0; - - if (lpwai->lpszProxy) - proxyBytesRequired = WideCharToMultiByte(CP_ACP, 0, - lpwai->lpszProxy, -1, NULL, 0, NULL, NULL); - if (lpwai->lpszProxyBypass) - proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, - lpwai->lpszProxyBypass, -1, NULL, 0, NULL, NULL); - if (*lpdwBufferLength < sizeof(INTERNET_PROXY_INFOA) + - proxyBytesRequired + proxyBypassBytesRequired) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - LPSTR proxy = (LPSTR)((LPBYTE)lpBuffer + - sizeof(INTERNET_PROXY_INFOA)); - LPSTR proxy_bypass = (LPSTR)((LPBYTE)lpBuffer + - sizeof(INTERNET_PROXY_INFOA) + - proxyBytesRequired); - - pPI->dwAccessType = lpwai->dwAccessType; - pPI->lpszProxy = NULL; - pPI->lpszProxyBypass = NULL; - if (lpwai->lpszProxy) - { - WideCharToMultiByte(CP_ACP, 0, lpwai->lpszProxy, -1, - proxy, proxyBytesRequired, NULL, NULL); - pPI->lpszProxy = proxy; - } + return ERROR_SUCCESS; - if (lpwai->lpszProxyBypass) - { - WideCharToMultiByte(CP_ACP, 0, lpwai->lpszProxyBypass, - -1, proxy_bypass, proxyBypassBytesRequired, - NULL, NULL); - pPI->lpszProxyBypass = proxy_bypass; - } - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(INTERNET_PROXY_INFOA) + - proxyBytesRequired + proxyBypassBytesRequired; - } - break; - } - case INTERNET_OPTION_MAX_CONNS_PER_SERVER: - { - ULONG conn = 2; - TRACE("INTERNET_OPTION_MAX_CONNS_PER_SERVER: %d\n", conn); - if (*lpdwBufferLength < sizeof(ULONG)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - memcpy(lpBuffer, &conn, sizeof(ULONG)); - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(ULONG); - break; - } - case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER: - { - ULONG conn = 4; - TRACE("INTERNET_OPTION_MAX_CONNS_1_0_SERVER: %d\n", conn); - if (*lpdwBufferLength < sizeof(ULONG)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - memcpy(lpBuffer, &conn, sizeof(ULONG)); - bSuccess = TRUE; - } - *lpdwBufferLength = sizeof(ULONG); - break; - } - case INTERNET_OPTION_SECURITY_FLAGS: - FIXME("INTERNET_OPTION_SECURITY_FLAGS: Stub\n"); - bSuccess = TRUE; - break; + case INTERNET_OPTION_PROXY: { + WININETAPPINFOW ai; - case INTERNET_OPTION_VERSION: - { - TRACE("INTERNET_OPTION_VERSION\n"); - if (*lpdwBufferLength < sizeof(INTERNET_VERSION_INFO)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - static const INTERNET_VERSION_INFO info = { 1, 2 }; - memcpy(lpBuffer, &info, sizeof(info)); - *lpdwBufferLength = sizeof(info); - bSuccess = TRUE; - } - break; - } - case INTERNET_OPTION_PER_CONNECTION_OPTION: - FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n"); - if (*lpdwBufferLength < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) - INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); - else - { - INTERNET_PER_CONN_OPTION_LISTW *con = lpBuffer; - int x; - bSuccess = TRUE; - for (x = 0; x < con->dwOptionCount; ++x) - { - INTERNET_PER_CONN_OPTIONW *option = con->pOptions + x; - switch (option->dwOption) - { - case INTERNET_PER_CONN_FLAGS: - option->Value.dwValue = PROXY_TYPE_DIRECT; - break; - - case INTERNET_PER_CONN_PROXY_SERVER: - case INTERNET_PER_CONN_PROXY_BYPASS: - case INTERNET_PER_CONN_AUTOCONFIG_URL: - case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: - case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: - case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS: - case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: - case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: - FIXME("Unhandled dwOption %d\n", option->dwOption); - option->Value.dwValue = 0; - bSuccess = FALSE; - break; - - default: - FIXME("Unknown dwOption %d\n", option->dwOption); - bSuccess = FALSE; - break; - } - } - if (!bSuccess) - INTERNET_SetLastError(ERROR_INVALID_PARAMETER); - } - break; - case 66: - FIXME("66\n"); - bSuccess = TRUE; - break; - default: { - if(lpwhh) { - DWORD res; + TRACE("Getting global proxy info\n"); + memset(&ai, 0, sizeof(WININETAPPINFOW)); + INTERNET_ConfigureProxy(&ai); - res = lpwhh->vtbl->QueryOption(lpwhh, dwOption, lpBuffer, lpdwBufferLength, bIsUnicode); - if(res == ERROR_SUCCESS) - bSuccess = TRUE; - else - SetLastError(res); - }else { - FIXME("Stub! %d\n", dwOption); + return APPINFO_QueryOption(&ai.hdr, INTERNET_OPTION_PROXY, buffer, size, unicode); /* FIXME */ + } + + case INTERNET_OPTION_MAX_CONNS_PER_SERVER: + TRACE("INTERNET_OPTION_MAX_CONNS_PER_SERVER\n"); + + if (*size < sizeof(ULONG)) + return ERROR_INSUFFICIENT_BUFFER; + + *(ULONG*)buffer = 2; + *size = sizeof(ULONG); + + return ERROR_SUCCESS; + + case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER: + TRACE("INTERNET_OPTION_MAX_CONNS_1_0_SERVER\n"); + + if (*size < sizeof(ULONG)) + return ERROR_INSUFFICIENT_BUFFER; + + *(ULONG*)size = 4; + *size = sizeof(ULONG); + + return ERROR_SUCCESS; + + case INTERNET_OPTION_SECURITY_FLAGS: + FIXME("INTERNET_OPTION_SECURITY_FLAGS: Stub\n"); + return ERROR_SUCCESS; + + case INTERNET_OPTION_VERSION: { + static const INTERNET_VERSION_INFO info = { 1, 2 }; + + TRACE("INTERNET_OPTION_VERSION\n"); + + if (*size < sizeof(INTERNET_VERSION_INFO)) + return ERROR_INSUFFICIENT_BUFFER; + + memcpy(buffer, &info, sizeof(info)); + *size = sizeof(info); + + return ERROR_SUCCESS; + } + + case INTERNET_OPTION_PER_CONNECTION_OPTION: { + INTERNET_PER_CONN_OPTION_LISTW *con = buffer; + DWORD res = ERROR_SUCCESS, i; + + FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n"); + + if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) + return ERROR_INSUFFICIENT_BUFFER; + + for (i = 0; i < con->dwOptionCount; i++) { + INTERNET_PER_CONN_OPTIONW *option = con->pOptions + i; + + switch (option->dwOption) { + case INTERNET_PER_CONN_FLAGS: + option->Value.dwValue = PROXY_TYPE_DIRECT; + break; + + case INTERNET_PER_CONN_PROXY_SERVER: + case INTERNET_PER_CONN_PROXY_BYPASS: + case INTERNET_PER_CONN_AUTOCONFIG_URL: + case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: + case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: + case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS: + case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: + case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: + FIXME("Unhandled dwOption %d\n", option->dwOption); + option->Value.dwValue = 0; + res = ERROR_INVALID_PARAMETER; + break; + + default: + FIXME("Unknown dwOption %d\n", option->dwOption); + res = ERROR_INVALID_PARAMETER; break; } } + + return res; + } } - if (lpwhh) - WININET_Release( lpwhh ); - return bSuccess; + FIXME("Stub for %d\n", option); + return ERROR_INTERNET_INCORRECT_HANDLE_TYPE; } /*********************************************************************** @@ -2253,7 +2165,24 @@ static BOOL INET_QueryOptionHelper(BOOL bIsUnicode, HINTERNET hInternet, DWORD d BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength) { - return INET_QueryOptionHelper(TRUE, hInternet, dwOption, lpBuffer, lpdwBufferLength); + LPWININETHANDLEHEADER hdr; + DWORD res = ERROR_INVALID_HANDLE; + + TRACE("%p %d %p %p\n", hInternet, dwOption, lpBuffer, lpdwBufferLength); + + if(hInternet) { + hdr = WININET_GetObject(hInternet); + if (hdr) { + res = hdr->vtbl->QueryOption(hdr, dwOption, lpBuffer, lpdwBufferLength, TRUE); + WININET_Release(hdr); + } + }else { + res = INET_QueryOption(dwOption, lpBuffer, lpdwBufferLength, TRUE); + } + + if(res != ERROR_SUCCESS) + SetLastError(res); + return res == ERROR_SUCCESS; } /*********************************************************************** @@ -2269,7 +2198,24 @@ BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength) { - return INET_QueryOptionHelper(FALSE, hInternet, dwOption, lpBuffer, lpdwBufferLength); + LPWININETHANDLEHEADER hdr; + DWORD res = ERROR_INVALID_HANDLE; + + TRACE("%p %d %p %p\n", hInternet, dwOption, lpBuffer, lpdwBufferLength); + + if(hInternet) { + hdr = WININET_GetObject(hInternet); + if (hdr) { + res = hdr->vtbl->QueryOption(hdr, dwOption, lpBuffer, lpdwBufferLength, FALSE); + WININET_Release(hdr); + } + }else { + res = INET_QueryOption(dwOption, lpBuffer, lpdwBufferLength, FALSE); + } + + if(res != ERROR_SUCCESS) + SetLastError(res); + return res == ERROR_SUCCESS; } diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 43b8d8e4cc1..bb694e91b3e 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -347,6 +347,8 @@ LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info ); BOOL WININET_Release( LPWININETHANDLEHEADER info ); BOOL WININET_FreeHandle( HINTERNET hinternet ); +DWORD INET_QueryOption(DWORD,void*,DWORD*,BOOL); + time_t ConvertTimeString(LPCWSTR asctime); HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c index 992bce99feb..34aa68fa1dd 100644 --- a/dlls/wininet/tests/ftp.c +++ b/dlls/wininet/tests/ftp.c @@ -259,7 +259,6 @@ static void test_getfile(HINTERNET hFtp, HINTERNET hConnect) ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR, "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError()); /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */ - todo_wine ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES, "Local file should not have been created\n"); @@ -280,7 +279,6 @@ static void test_getfile(HINTERNET hFtp, HINTERNET hConnect) ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR, "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError()); /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */ - todo_wine ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES, "Local file should not have been created\n"); diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 6e27669a8a7..8209b2243ca 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -1489,6 +1489,13 @@ static DWORD CALLBACK server_thread(LPVOID param) recvfrom(c, buffer, sizeof buffer, 0, NULL, NULL); send(c, okmsg, sizeof okmsg-1, 0); } + if (strstr(buffer, "/testC")) + { + if (strstr(buffer, "Cookie: cookie=biscuit")) + send(c, okmsg, sizeof okmsg-1, 0); + else + send(c, notokmsg, sizeof notokmsg-1, 0); + } if (strstr(buffer, "GET /quit")) { send(c, okmsg, sizeof okmsg-1, 0); @@ -1688,7 +1695,7 @@ static void test_header_handling_order(int port) size = sizeof(status); ret = HttpQueryInfo( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL ); ok(ret, "HttpQueryInfo failed\n"); - ok(status == 200, "request failed with status %u\n", status); + ok(status == 200 || status == 400 /* IE6 */, "got status %u, expected 200 or 400\n", status); InternetCloseHandle(request); @@ -1705,7 +1712,7 @@ static void test_header_handling_order(int port) size = sizeof(status); ret = HttpQueryInfo( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL ); ok(ret, "HttpQueryInfo failed\n"); - ok(status == 200 || status == 400 /* IE6 */, "request failed with status %u\n", status); + ok(status == 200 || status == 400 /* IE6 */, "got status %u, expected 200 or 400\n", status); InternetCloseHandle(request); InternetCloseHandle(connect); @@ -1815,6 +1822,52 @@ static void test_http1_1(int port) InternetCloseHandle(ses); } +static void test_cookie_header(int port) +{ + HINTERNET ses, con, req; + DWORD size, status, error; + BOOL ret; + char buffer[64]; + + ses = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(ses != NULL, "InternetOpen failed\n"); + + con = InternetConnect(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(con != NULL, "InternetConnect failed\n"); + + InternetSetCookie("http://localhost", "cookie", "biscuit"); + + req = HttpOpenRequest(con, NULL, "/testC", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0); + ok(req != NULL, "HttpOpenRequest failed\n"); + + buffer[0] = 0; + size = sizeof(buffer); + SetLastError(0xdeadbeef); + ret = HttpQueryInfo(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL); + error = GetLastError(); + ok(!ret, "HttpQueryInfo succeeded\n"); + ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "got %u expected ERROR_HTTP_HEADER_NOT_FOUND\n", error); + + ret = HttpSendRequest(req, NULL, 0, NULL, 0); + ok(ret, "HttpSendRequest failed: %u\n", GetLastError()); + + status = 0; + size = sizeof(status); + ret = HttpQueryInfo(req, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL); + ok(ret, "HttpQueryInfo failed\n"); + ok(status == 200, "request failed with status %u\n", status); + + buffer[0] = 0; + size = sizeof(buffer); + ret = HttpQueryInfo(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL); + ok(ret, "HttpQueryInfo failed: %u\n", GetLastError()); + ok(!strcmp(buffer, "cookie=biscuit"), "got '%s' expected \'cookie=biscuit\'\n", buffer); + + InternetCloseHandle(req); + InternetCloseHandle(con); + InternetCloseHandle(ses); +} + static void test_http_connection(void) { struct server_info si; @@ -1840,6 +1893,7 @@ static void test_http_connection(void) test_basic_request(si.port, "GET", "/test6"); test_connection_header(si.port); test_http1_1(si.port); + test_cookie_header(si.port); /* send the basic request again to shutdown the server thread */ test_basic_request(si.port, "GET", "/quit"); diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 2c5f4e3492c..14adc43be33 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -161,7 +161,7 @@ static void test_InternetQueryOptionA(void) err=GetLastError(); ok(len == strlen(useragent)+1,"Got wrong user agent length %d instead of %d\n",len,lstrlenA(useragent)); ok(retval == 0,"Got wrong return value %d\n",retval); - todo_wine ok(err == ERROR_INSUFFICIENT_BUFFER, "Got wrong error code%d\n",err); + ok(err == ERROR_INSUFFICIENT_BUFFER, "Got wrong error code %d\n",err); SetLastError(0xdeadbeef); len=strlen(useragent)+1; @@ -221,7 +221,7 @@ static void test_InternetQueryOptionA(void) err=GetLastError(); todo_wine ok(len == 1,"Got wrong user agent length %d instead of %d\n",len,1); ok(retval == 0,"Got wrong return value %d\n",retval); - todo_wine ok(err == ERROR_INSUFFICIENT_BUFFER, "Got wrong error code%d\n",err); + ok(err == ERROR_INSUFFICIENT_BUFFER, "Got wrong error code%d\n",err); InternetCloseHandle(hinet); } diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c index 6af062b2977..90a185fd938 100644 --- a/dlls/winmm/tests/mci.c +++ b/dlls/winmm/tests/mci.c @@ -28,7 +28,9 @@ START_TEST(mci) const char command_open[] = "open new type waveaudio alias mysound"; const char command_close_my[] = "close mysound notify"; const char command_close_all[] = "close all notify"; + const char command_sysinfo[] = "sysinfo waveaudio quantity open"; MSG msg; + char buf[1024]; err = mciSendString(command_open, NULL, 0, NULL); ok(!err,"mciSendString(%s, NULL, 0 , NULL) returned error: %d\n", command_open, err); @@ -44,6 +46,16 @@ START_TEST(mci) err = mciSendString(command_close_all, NULL, 0, NULL); todo_wine ok(!err,"mciSendString(%s, NULL, 0 , NULL) returned error: %d\n", command_close_all, err); + memset(buf, 0, sizeof(buf)); + err = mciSendString(command_close_all, buf, sizeof(buf), NULL); + todo_wine ok(!err,"mciSendString(%s, buf, sizeof(buf) , NULL) returned error: %d\n", command_close_all, err); + todo_wine ok(buf[0] == 0, "mciSendString(%s, buf, sizeof(buf) , NULL) changed output buffer: %s\n", command_close_all, buf); + + memset(buf, 0, sizeof(buf)); + err = mciSendString(command_sysinfo, buf, sizeof(buf), NULL); + ok(!err,"mciSendString(%s, buf, sizeof(buf) , NULL) returned error: %d\n", command_sysinfo, err); + todo_wine ok(buf[0] == '0' && buf[1] == 0, "mciSendString(%s, buf, sizeof(buf) , NULL), expected output buffer '0', got: '%s'\n", command_sysinfo, buf); + err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, 0); todo_wine ok(err == MCIERR_INVALID_DEVICE_ID, "mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_NOTIFY, NULL) returned %d instead of %d\n", diff --git a/dlls/winspool.drv/Makefile.in b/dlls/winspool.drv/Makefile.in index bd878242c48..7e670dbd018 100644 --- a/dlls/winspool.drv/Makefile.in +++ b/dlls/winspool.drv/Makefile.in @@ -6,6 +6,7 @@ VPATH = @srcdir@ MODULE = winspool.drv IMPORTLIB = winspool IMPORTS = user32 gdi32 advapi32 kernel32 ntdll +EXTRAINCL = @CUPSINCL@ C_SRCS = \ info.c \ diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c index 8819ea8bb20..e2129dffc60 100644 --- a/dlls/wintrust/crypt.c +++ b/dlls/wintrust/crypt.c @@ -2,6 +2,10 @@ * WinTrust Cryptography functions * * Copyright 2006 James Hawkins + * Copyright 2000-2002 Stuart Caie + * Copyright 2002 Patrik Stridvall + * Copyright 2003 Greg Turner + * Copyright 2008 Juan Lang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,7 +23,7 @@ */ #include - +#include #include "windef.h" #include "winbase.h" #include "wintrust.h" @@ -202,11 +206,9 @@ BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcb return FALSE; } -/*********************************************************************** - * CryptSIPGetSignedDataMsg (WINTRUST.@) - */ -BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType, - DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg) +static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo, + DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg, + BYTE *pbSignedDataMsg) { BOOL ret; WIN_CERTIFICATE *pCert = NULL; @@ -264,9 +266,240 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn } } } - error: HeapFree(GetProcessHeap(), 0, pCert); + return ret; +} + +/* structure offsets */ +#define cfhead_Signature (0x00) +#define cfhead_CabinetSize (0x08) +#define cfhead_MinorVersion (0x18) +#define cfhead_MajorVersion (0x19) +#define cfhead_Flags (0x1E) +#define cfhead_SIZEOF (0x24) +#define cfheadext_HeaderReserved (0x00) +#define cfheadext_SIZEOF (0x04) +#define cfsigninfo_CertOffset (0x04) +#define cfsigninfo_CertSize (0x08) +#define cfsigninfo_SIZEOF (0x0C) + +/* flags */ +#define cfheadRESERVE_PRESENT (0x0004) + +/* endian-neutral reading of little-endian data */ +#define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0])) +#define EndGetI16(a) ((((a)[1])<<8)|((a)[0])) + +/* For documentation purposes only: this is the structure in the reserved + * area of a signed cabinet file. The cert offset indicates where in the + * cabinet file the signature resides, and the count indicates its size. + */ +typedef struct _CAB_SIGNINFO +{ + WORD unk0; /* always 0? */ + WORD unk1; /* always 0x0010? */ + DWORD dwCertOffset; + DWORD cbCertBlock; +} CAB_SIGNINFO, *PCAB_SIGNINFO; + +static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo, + DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg, + BYTE *pbSignedDataMsg) +{ + int header_resv; + LONG base_offset, cabsize; + USHORT flags; + BYTE buf[64]; + DWORD cert_offset, cert_size, dwRead; + + TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, + pcbSignedDataMsg, pbSignedDataMsg); + + /* + * FIXME: I just noticed that I am memorizing the initial file pointer + * offset and restoring it before reading in the rest of the header + * information in the cabinet. Perhaps that's correct -- that is, perhaps + * this API is supposed to support "streaming" cabinets which are embedded + * in other files, or cabinets which begin at file offsets other than zero. + * Otherwise, I should instead go to the absolute beginning of the file. + * (Either way, the semantics of wine's FDICopy require me to leave the + * file pointer where it is afterwards -- If Windows does not do so, we + * ought to duplicate the native behavior in the FDIIsCabinet API, not here. + * + * So, the answer lies in Windows; will native cabinet.dll recognize a + * cabinet "file" embedded in another file? Note that cabextract.c does + * support this, which implies that Microsoft's might. I haven't tried it + * yet so I don't know. ATM, most of wine's FDI cabinet routines (except + * this one) would not work in this way. To fix it, we could just make the + * various references to absolute file positions in the code relative to an + * initial "beginning" offset. Because the FDICopy API doesn't take a + * file-handle like this one, we would therein need to search through the + * file for the beginning of the cabinet (as we also do in cabextract.c). + * Note that this limits us to a maximum of one cabinet per. file: the first. + * + * So, in summary: either the code below is wrong, or the rest of fdi.c is + * wrong... I cannot imagine that both are correct ;) One of these flaws + * should be fixed after determining the behavior on Windows. We ought + * to check both FDIIsCabinet and FDICopy for the right behavior. + * + * -gmt + */ + + /* get basic offset & size info */ + base_offset = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR); + + if (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_END) == -1) + { + TRACE("seek error\n"); + return FALSE; + } + + cabsize = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR); + if ((cabsize == -1) || (base_offset == -1) || + (SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET) == -1)) + { + TRACE("seek error\n"); + return FALSE; + } + + /* read in the CFHEADER */ + if (!ReadFile(pSubjectInfo->hFile, buf, cfhead_SIZEOF, &dwRead, NULL) || + dwRead != cfhead_SIZEOF) + { + TRACE("reading header failed\n"); + return FALSE; + } + + /* check basic MSCF signature */ + if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) + { + WARN("cabinet signature not present\n"); + return FALSE; + } + + /* Ignore the number of folders and files and the set and cabinet IDs */ + + /* check the header revision */ + if ((buf[cfhead_MajorVersion] > 1) || + (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3)) + { + WARN("cabinet format version > 1.3\n"); + return FALSE; + } + + /* pull the flags out */ + flags = EndGetI16(buf+cfhead_Flags); + + if (!(flags & cfheadRESERVE_PRESENT)) + { + TRACE("no header present, not signed\n"); + return FALSE; + } + + if (!ReadFile(pSubjectInfo->hFile, buf, cfheadext_SIZEOF, &dwRead, NULL) || + dwRead != cfheadext_SIZEOF) + { + ERR("bunk reserve-sizes?\n"); + return FALSE; + } + + header_resv = EndGetI16(buf+cfheadext_HeaderReserved); + if (!header_resv) + { + TRACE("no header_resv, not signed\n"); + return FALSE; + } + else if (header_resv < cfsigninfo_SIZEOF) + { + TRACE("header_resv too small, not signed\n"); + return FALSE; + } + + if (header_resv > 60000) + { + WARN("WARNING; header reserved space > 60000\n"); + } + + if (!ReadFile(pSubjectInfo->hFile, buf, cfsigninfo_SIZEOF, &dwRead, NULL) || + dwRead != cfsigninfo_SIZEOF) + { + ERR("couldn't read reserve\n"); + return FALSE; + } + + cert_offset = EndGetI32(buf+cfsigninfo_CertOffset); + TRACE("cert_offset: %d\n", cert_offset); + cert_size = EndGetI32(buf+cfsigninfo_CertSize); + TRACE("cert_size: %d\n", cert_size); + + /* The redundant checks are to avoid wraparound */ + if (cert_offset > cabsize || cert_size > cabsize || + cert_offset + cert_size > cabsize) + { + WARN("offset beyond file, not attempting to read\n"); + return FALSE; + } + + SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET); + if (!pbSignedDataMsg) + { + *pcbSignedDataMsg = cert_size; + return TRUE; + } + if (*pcbSignedDataMsg < cert_size) + { + *pcbSignedDataMsg = cert_size; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + if (SetFilePointer(pSubjectInfo->hFile, cert_offset, NULL, SEEK_SET) == -1) + { + ERR("couldn't seek to cert location\n"); + return FALSE; + } + if (!ReadFile(pSubjectInfo->hFile, pbSignedDataMsg, cert_size, &dwRead, + NULL) || dwRead != cert_size) + { + ERR("couldn't read cert\n"); + return FALSE; + } + /* The encoding of the files I've seen appears to be in ASN.1 + * format, and there isn't a field indicating the type, so assume it + * always is. + */ + *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; + return TRUE; +} + +/*********************************************************************** + * CryptSIPGetSignedDataMsg (WINTRUST.@) + */ +BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType, + DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg) +{ + static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47, + 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; + static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47, + 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; + BOOL ret; + + TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, + pcbSignedDataMsg, pbSignedDataMsg); + + if (!memcmp(pSubjectInfo->pgSubjectType, &unknown, sizeof(unknown))) + ret = WINTRUST_GetSignedMsgFromPEFile(pSubjectInfo, pdwEncodingType, + dwIndex, pcbSignedDataMsg, pbSignedDataMsg); + else if (!memcmp(pSubjectInfo->pgSubjectType, &cabGUID, sizeof(cabGUID))) + ret = WINTRUST_GetSignedMsgFromCabFile(pSubjectInfo, pdwEncodingType, + dwIndex, pcbSignedDataMsg, pbSignedDataMsg); + else + { + FIXME("unimplemented for subject type %s\n", + debugstr_guid(pSubjectInfo->pgSubjectType)); + ret = FALSE; + } + TRACE("returning %d\n", ret); return ret; } diff --git a/dlls/wintrust/tests/softpub.c b/dlls/wintrust/tests/softpub.c index aa27333cdd0..01902dd09fb 100644 --- a/dlls/wintrust/tests/softpub.c +++ b/dlls/wintrust/tests/softpub.c @@ -437,7 +437,7 @@ static void test_wintrust(void) wtd.dwUIChoice = WTD_UI_NONE; wtd.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; wtd.dwUnionChoice = WTD_CHOICE_FILE; - wtd.pFile = &file; + U(wtd).pFile = &file; wtd.dwStateAction = WTD_STATEACTION_VERIFY; memset(&file, 0, sizeof(file)); file.cbStruct = sizeof(file); diff --git a/include/Makefile.in b/include/Makefile.in index 0adef3c3ba2..99b06d90fae 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -69,8 +69,6 @@ IDL_H_SRCS = \ urlhist.idl \ urlmon.idl \ vmr9.idl \ - wine/dcetypes.idl \ - wine/epm.idl \ wine/itss.idl \ wine/svcctl.idl \ wtypes.idl \ diff --git a/include/config.h.in b/include/config.h.in index c4f30c9fd57..1245197b54b 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -918,6 +918,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_VALGRIND_MEMCHECK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_VALGRIND_VALGRIND_H + /* Define if we have va_copy */ #undef HAVE_VA_COPY diff --git a/include/d3dx8mesh.h b/include/d3dx8mesh.h index f1eab5cd43c..d063f6d67af 100644 --- a/include/d3dx8mesh.h +++ b/include/d3dx8mesh.h @@ -19,7 +19,7 @@ #ifndef __WINE_D3DX8MESH_H #define __WINE_D3DX8MESH_H -#include +#include #include #ifdef __cplusplus @@ -28,6 +28,7 @@ extern "C" { HRESULT WINAPI D3DXCreateBuffer(DWORD,LPD3DXBUFFER*); UINT WINAPI D3DXGetFVFVertexSize(DWORD); +BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *,FLOAT,CONST D3DXVECTOR3 *,CONST D3DXVECTOR3 *); #ifdef __cplusplus } diff --git a/include/d3dx9math.h b/include/d3dx9math.h index 63f2be720d1..9801504a34c 100644 --- a/include/d3dx9math.h +++ b/include/d3dx9math.h @@ -302,6 +302,7 @@ D3DXPLANE* WINAPI D3DXPlaneFromPoints(D3DXPLANE *pout, CONST D3DXVECTOR3 *pv1, C D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine(D3DXVECTOR3 *pout, CONST D3DXPLANE *pp, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2); D3DXPLANE* WINAPI D3DXPlaneNormalize(D3DXPLANE *pout, CONST D3DXPLANE *pp); D3DXPLANE* WINAPI D3DXPlaneTransform(D3DXPLANE *pout, CONST D3DXPLANE *pplane, CONST D3DXMATRIX *pm); +D3DXPLANE* WINAPI D3DXPlaneTransformArray(D3DXPLANE *pout, UINT outstride, CONST D3DXPLANE *pplane, UINT pstride, CONST D3DXMATRIX *pm, UINT n); D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, FLOAT f, FLOAT g); D3DXQUATERNION* WINAPI D3DXQuaternionExp(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq); diff --git a/include/d3dx9shader.h b/include/d3dx9shader.h index 5eb4fe67587..6d2aa415d41 100644 --- a/include/d3dx9shader.h +++ b/include/d3dx9shader.h @@ -26,6 +26,7 @@ extern "C" { #endif UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code); +DWORD WINAPI D3DXGetShaderVersion(const DWORD *byte_code); #ifdef __cplusplus } diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index b2ca34ba90b..c82b69dc147 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -199,12 +199,16 @@ GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient*,GpWrapMode*); GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient*,GpRectF*); GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient*,GpRect*); GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient*,ARGB*); +GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient*,REAL*,REAL*,INT); +GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient*,INT*); GpStatus WINGDIPAPI GdipGetPathGradientCenterColor(GpPathGradient*,ARGB*); GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient*,GpPointF*); GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient*,GpPoint*); GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient*,REAL*,REAL*); GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient*,BOOL*); GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient*,INT*); +GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient*,GpRectF*); +GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient*,GpRect*); GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient*, ARGB*,INT*); GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient*,GpWrapMode*); @@ -411,11 +415,19 @@ GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily*, INT, UINT16*); GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily*, INT, UINT16*); GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily*, INT, UINT16*); GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily*, INT, UINT16*); +GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily *, INT, BOOL*); GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily**); GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily**); GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily**); +GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection**); +GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection**); +GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection*, GDIPCONST WCHAR*); +GpStatus WINGDIPAPI GdipGetFontCollectionFamilyCount(GpFontCollection*, INT*); +GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(GpFontCollection*, INT, + GpFontFamily*[], INT*); + GpStatus WINGDIPAPI GdipCreateStringFormat(INT,LANGID,GpStringFormat**); GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat*); GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **); diff --git a/include/mlang.idl b/include/mlang.idl index fabcc59fb43..2b236c75e66 100644 --- a/include/mlang.idl +++ b/include/mlang.idl @@ -222,6 +222,94 @@ interface IMLangFontLink2 : IMLangCodePages } [ + object, + uuid(c04d65ce-b70d-11d0-b188-00aa0038c969), + pointer_default(unique) +] +interface IMLangString : IUnknown +{ +#ifdef NEWMLSTR + HRESULT LockMLStr( + [in] long lPos, + [in] DWORD dwFlags, + [out] DWORD* pdwCookie, + [out] long* plActualPos, + [out] long* plActualLen); + + HRESULT UnlockMLStr( + [in] DWORD dwCookie); +#else + HRESULT Sync( + [in] BOOL fNoAccess); +#endif + HRESULT GetLength( + [out, retval] long* plLen); + HRESULT SetMLStr( + [in] long lDestPos, + [in] long lDestLen, + [in] IUnknown *pSrcMLStr, + [in] long lSrcPos, + [in] long lSrcLen); +#ifdef NEWMLSTR + HRESULT RegisterAttr( + [in] IUnknown *pUnk, + [out] DWORD* pdwCookie); + HRESULT UnregisterAttr( + [in] DWORD dwCookie); + HRESULT EnumAttr( + [out] IEnumUnknown **ppEnumUnk); + HRESULT FindAttr( + [in] REFIID riid, + [in] LPARAM lParam, + [out] IUnknown **ppUnk); +#else + HRESULT GetMLStr( + [in] long lSrcPos, + [in] long lSrcLen, + [in] IUnknown *pUnkOuter, + [in] DWORD dwClsContext, + [in] const IID* piid, + [out] IUnknown** ppDestMLStr, + [out] long* plDestPos, + [out] long* plDestLen); +#endif +} + +[ + object, + uuid(f5be2ee1-bfd7-11d0-b188-00aa0038c969), + pointer_default(unique) +] +interface IMLangLineBreakConsole : IUnknown +{ + HRESULT BreakLineML( + [in] IMLangString* pSrcMLStr, + [in] long lSrcPos, + [in] long lSrcLen, + [in] long cMinColumns, + [in] long cMaxColumns, + [out] long* plLineLen, + [out] long* plSkipLen); + + HRESULT BreakLineW( + [in] LCID locale, + [in, size_is(cchSrc)] const WCHAR* pszSrc, + [in] long cchSrc, + [in] long cMaxColumns, + [out] long* pcchLine, + [out] long* pcchSkip ); + + HRESULT BreakLineA( + [in] LCID locale, + [in] UINT uCodePage, + [in, size_is(cchSrc)] const CHAR* pszSrc, + [in] long cchSrc, + [in] long cMaxColumns, + [out] long* pcchLine, + [out] long* pcchSkip); +} + +[ object, uuid(275c23e3-3747-11d0-9fea-00aa003f8646), pointer_default(unique) diff --git a/include/msidefs.h b/include/msidefs.h index 12b607d866b..141e2034b2a 100644 --- a/include/msidefs.h +++ b/include/msidefs.h @@ -207,6 +207,14 @@ enum msidbAssemblyAttributes msidbAssemblyAttributesWin32 = 0x00000001, }; +enum msidbSumInfoSourceType +{ + msidbSumInfoSourceTypeSFN = 0x00000001, + msidbSumInfoSourceTypeCompressed = 0x00000002, + msidbSumInfoSourceTypeAdminImage = 0x00000004, + msidbSumInfoSourceTypeLUAPackage = 0x00000008, +}; + /* * Windows SDK braindamage alert * diff --git a/include/vmrender.idl b/include/vmrender.idl index edf9e1e431d..360b5fee729 100644 --- a/include/vmrender.idl +++ b/include/vmrender.idl @@ -268,7 +268,7 @@ typedef enum _VMRMode VMRMode_Windowed = 0x1, VMRMode_Windowless = 0x2, VMRMode_Renderless = 0x4, - VMRMODE_Mask = 0x7 + VMRMode_Mask = 0x7 } VMRMode; enum { MAX_NUMBER_OF_STREAMS = 16 }; diff --git a/include/winbase.h b/include/winbase.h index 0ee36c2ff60..cf0345baa0a 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1312,6 +1312,7 @@ WINBASEAPI BOOL WINAPI CallNamedPipeW(LPCWSTR,LPVOID,DWORD,LPVOID,DWORD,L #define CallNamedPipe WINELIB_NAME_AW(CallNamedPipe) WINBASEAPI BOOL WINAPI CancelIo(HANDLE); WINBASEAPI BOOL WINAPI CancelWaitableTimer(HANDLE); +WINBASEAPI BOOL WINAPI ChangeTimerQueueTimer(HANDLE,HANDLE,ULONG,ULONG); WINADVAPI BOOL WINAPI CheckTokenMembership(HANDLE,PSID,PBOOL); WINBASEAPI BOOL WINAPI ClearCommBreak(HANDLE); WINBASEAPI BOOL WINAPI ClearCommError(HANDLE,LPDWORD,LPCOMSTAT); diff --git a/dlls/dplayx/dplaysp.h b/include/wine/dplaysp.h similarity index 100% rename from dlls/dplayx/dplaysp.h rename to include/wine/dplaysp.h diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h index 04471df737b..ac4967d4670 100644 --- a/include/wine/wined3d_gl.h +++ b/include/wine/wined3d_gl.h @@ -2991,6 +2991,19 @@ typedef void (WINE_GLAPI *PGLFNSETFRAGMENTSHADERCONSTANTATI) (GLuint dst, const #define GL_NEGATE_BIT_ATI 0x00000004 #define GL_BIAS_BIT_ATI 0x00000008 #endif +/* GL_ATI_texture_compression_3dc */ +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 +#endif +/* GL_EXT_texture_compression_rgtc */ +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif /* GL_VERSION_2_0 */ #ifndef GL_VERSION_2_0 @@ -3322,6 +3335,7 @@ typedef enum _GL_SupportedExt { EXT_STENCIL_WRAP, EXT_TEXTURE3D, EXT_TEXTURE_COMPRESSION_S3TC, + EXT_TEXTURE_COMPRESSION_RGTC, EXT_TEXTURE_FILTER_ANISOTROPIC, EXT_TEXTURE_LOD, EXT_TEXTURE_LOD_BIAS, @@ -3357,6 +3371,7 @@ typedef enum _GL_SupportedExt { EXT_VERTEX_SHADER, ATI_ENVMAP_BUMPMAP, ATI_FRAGMENT_SHADER, + ATI_TEXTURE_COMPRESSION_3DC, /* APPLE */ APPLE_FENCE, APPLE_CLIENT_STORAGE, diff --git a/include/wine/wined3d_types.h b/include/wine/wined3d_types.h index 45a947d0da4..c67c3116280 100644 --- a/include/wine/wined3d_types.h +++ b/include/wine/wined3d_types.h @@ -303,6 +303,8 @@ typedef enum _WINED3DFORMAT { WINED3DFMT_CxV8U8 = 117, + /* Vendor specific formats */ + WINED3DFMT_ATI2N = WINEMAKEFOURCC('A', 'T', 'I', '2'), WINED3DFMT_FORCE_DWORD = 0xFFFFFFFF } WINED3DFORMAT; diff --git a/include/winhttp.h b/include/winhttp.h index c87ccd451f5..dab9bbaa7b9 100644 --- a/include/winhttp.h +++ b/include/winhttp.h @@ -58,6 +58,24 @@ typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; #define WINHTTP_NO_REFERER NULL #define WINHTTP_DEFAULT_ACCEPT_TYPES NULL +#define WINHTTP_NO_ADDITIONAL_HEADERS NULL +#define WINHTTP_NO_REQUEST_DATA NULL + +#define WINHTTP_HEADER_NAME_BY_INDEX NULL +#define WINHTTP_NO_OUTPUT_BUFFER NULL +#define WINHTTP_NO_HEADER_INDEX NULL + +#define WINHTTP_ADDREQ_INDEX_MASK 0x0000FFFF +#define WINHTTP_ADDREQ_FLAGS_MASK 0xFFFF0000 +#define WINHTTP_ADDREQ_FLAG_ADD_IF_NEW 0x10000000 +#define WINHTTP_ADDREQ_FLAG_ADD 0x20000000 +#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA 0x40000000 +#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON 0x01000000 +#define WINHTTP_ADDREQ_FLAG_COALESCE WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA +#define WINHTTP_ADDREQ_FLAG_REPLACE 0x80000000 + +#define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0 + /* flags for WinHttp{Set/Query}Options */ #define WINHTTP_FIRST_OPTION WINHTTP_OPTION_CALLBACK #define WINHTTP_OPTION_CALLBACK 1 @@ -116,6 +134,34 @@ typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; #define WINHTTP_OPTION_PROXY_USERNAME 0x1002 #define WINHTTP_OPTION_PROXY_PASSWORD 0x1003 +#define WINHTTP_CONNS_PER_SERVER_UNLIMITED 0xFFFFFFFF + +#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM 0 +#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW 1 +#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH 2 +#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM + +#define WINHTTP_OPTION_REDIRECT_POLICY_NEVER 0 +#define WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP 1 +#define WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS 2 +#define WINHTTP_OPTION_REDIRECT_POLICY_LAST WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS +#define WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP + +#define WINHTTP_DISABLE_PASSPORT_AUTH 0x00000000 +#define WINHTTP_ENABLE_PASSPORT_AUTH 0x10000000 +#define WINHTTP_DISABLE_PASSPORT_KEYRING 0x20000000 +#define WINHTTP_ENABLE_PASSPORT_KEYRING 0x40000000 + +#define WINHTTP_DISABLE_COOKIES 0x00000001 +#define WINHTTP_DISABLE_REDIRECTS 0x00000002 +#define WINHTTP_DISABLE_AUTHENTICATION 0x00000004 +#define WINHTTP_DISABLE_KEEP_ALIVE 0x00000008 +#define WINHTTP_ENABLE_SSL_REVOCATION 0x00000001 +#define WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION 0x00000002 +#define WINHTTP_DISABLE_SPN_SERVER_PORT 0x00000000 +#define WINHTTP_ENABLE_SPN_SERVER_PORT 0x00000001 +#define WINHTTP_OPTION_SPN_MASK WINHTTP_ENABLE_SPN_SERVER_PORT + /* Options for WinHttpOpenRequest */ #define WINHTTP_NO_REFERER NULL #define WINHTTP_DEFAULT_ACCEPT_TYPES NULL @@ -125,40 +171,55 @@ typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; #define WINHTTP_NO_REQUEST_DATA NULL /* WinHTTP error codes */ -#define WINHTTP_ERROR_BASE 12000 -#define ERROR_WINHTTP_OUT_OF_HANDLES (WINHTTP_ERROR_BASE + 1) -#define ERROR_WINHTTP_TIMEOUT (WINHTTP_ERROR_BASE + 2) -#define ERROR_WINHTTP_INTERNAL_ERROR (WINHTTP_ERROR_BASE + 4) -#define ERROR_WINHTTP_INVALID_URL (WINHTTP_ERROR_BASE + 5) -#define ERROR_WINHTTP_UNRECOGNIZED_SCHEME (WINHTTP_ERROR_BASE + 6) -#define ERROR_WINHTTP_NAME_NOT_RESOLVED (WINHTTP_ERROR_BASE + 7) -#define ERROR_WINHTTP_INVALID_OPTION (WINHTTP_ERROR_BASE + 9) -#define ERROR_WINHTTP_OPTION_NOT_SETTABLE (WINHTTP_ERROR_BASE + 11) -#define ERROR_WINHTTP_SHUTDOWN (WINHTTP_ERROR_BASE + 12) -#define ERROR_WINHTTP_LOGIN_FAILURE (WINHTTP_ERROR_BASE + 15) -#define ERROR_WINHTTP_OPERATION_CANCELLED (WINHTTP_ERROR_BASE + 17) -#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE (WINHTTP_ERROR_BASE + 18) -#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE (WINHTTP_ERROR_BASE + 19) -#define ERROR_WINHTTP_CANNOT_CONNECT (WINHTTP_ERROR_BASE + 29) -#define ERROR_WINHTTP_CONNECTION_ERROR (WINHTTP_ERROR_BASE + 30) -#define ERROR_WINHTTP_RESEND_REQUEST (WINHTTP_ERROR_BASE + 32) -#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED (WINHTTP_ERROR_BASE + 44) -#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN (WINHTTP_ERROR_BASE + 100) -#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND (WINHTTP_ERROR_BASE + 101) -#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND (WINHTTP_ERROR_BASE + 102) -#define ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN (WINHTTP_ERROR_BASE + 103) -#define ERROR_WINHTTP_HEADER_NOT_FOUND (WINHTTP_ERROR_BASE + 150) -#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE (WINHTTP_ERROR_BASE + 152) -#define ERROR_WINHTTP_INVALID_HEADER (WINHTTP_ERROR_BASE + 153) -#define ERROR_WINHTTP_INVALID_QUERY_REQUEST (WINHTTP_ERROR_BASE + 154) -#define ERROR_WINHTTP_HEADER_ALREADY_EXISTS (WINHTTP_ERROR_BASE + 155) -#define ERROR_WINHTTP_REDIRECT_FAILED (WINHTTP_ERROR_BASE + 156) -#define ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT (WINHTTP_ERROR_BASE + 166) -#define ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT (WINHTTP_ERROR_BASE + 167) -#define ERROR_WINHTTP_NOT_INITIALIZED (WINHTTP_ERROR_BASE + 172) -#define ERROR_WINHTTP_SECURE_FAILURE (WINHTTP_ERROR_BASE + 175) -#define ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR (WINHTTP_ERROR_BASE + 178) -#define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180) +#define WINHTTP_ERROR_BASE 12000 +#define ERROR_WINHTTP_OUT_OF_HANDLES (WINHTTP_ERROR_BASE + 1) +#define ERROR_WINHTTP_TIMEOUT (WINHTTP_ERROR_BASE + 2) +#define ERROR_WINHTTP_INTERNAL_ERROR (WINHTTP_ERROR_BASE + 4) +#define ERROR_WINHTTP_INVALID_URL (WINHTTP_ERROR_BASE + 5) +#define ERROR_WINHTTP_UNRECOGNIZED_SCHEME (WINHTTP_ERROR_BASE + 6) +#define ERROR_WINHTTP_NAME_NOT_RESOLVED (WINHTTP_ERROR_BASE + 7) +#define ERROR_WINHTTP_INVALID_OPTION (WINHTTP_ERROR_BASE + 9) +#define ERROR_WINHTTP_OPTION_NOT_SETTABLE (WINHTTP_ERROR_BASE + 11) +#define ERROR_WINHTTP_SHUTDOWN (WINHTTP_ERROR_BASE + 12) +#define ERROR_WINHTTP_LOGIN_FAILURE (WINHTTP_ERROR_BASE + 15) +#define ERROR_WINHTTP_OPERATION_CANCELLED (WINHTTP_ERROR_BASE + 17) +#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE (WINHTTP_ERROR_BASE + 18) +#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE (WINHTTP_ERROR_BASE + 19) +#define ERROR_WINHTTP_CANNOT_CONNECT (WINHTTP_ERROR_BASE + 29) +#define ERROR_WINHTTP_CONNECTION_ERROR (WINHTTP_ERROR_BASE + 30) +#define ERROR_WINHTTP_RESEND_REQUEST (WINHTTP_ERROR_BASE + 32) +#define ERROR_WINHTTP_SECURE_CERT_DATE_INVALID (WINHTTP_ERROR_BASE + 37) +#define ERROR_WINHTTP_SECURE_CERT_CN_INVALID (WINHTTP_ERROR_BASE + 38) +#define ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED (WINHTTP_ERROR_BASE + 44) +#define ERROR_WINHTTP_SECURE_INVALID_CA (WINHTTP_ERROR_BASE + 45) +#define ERROR_WINHTTP_SECURE_CERT_REV_FAILED (WINHTTP_ERROR_BASE + 57) +#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN (WINHTTP_ERROR_BASE + 100) +#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND (WINHTTP_ERROR_BASE + 101) +#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND (WINHTTP_ERROR_BASE + 102) +#define ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN (WINHTTP_ERROR_BASE + 103) +#define ERROR_WINHTTP_HEADER_NOT_FOUND (WINHTTP_ERROR_BASE + 150) +#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE (WINHTTP_ERROR_BASE + 152) +#define ERROR_WINHTTP_INVALID_HEADER (WINHTTP_ERROR_BASE + 153) +#define ERROR_WINHTTP_INVALID_QUERY_REQUEST (WINHTTP_ERROR_BASE + 154) +#define ERROR_WINHTTP_HEADER_ALREADY_EXISTS (WINHTTP_ERROR_BASE + 155) +#define ERROR_WINHTTP_REDIRECT_FAILED (WINHTTP_ERROR_BASE + 156) +#define ERROR_WINHTTP_SECURE_CHANNEL_ERROR (WINHTTP_ERROR_BASE + 157) +#define ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT (WINHTTP_ERROR_BASE + 166) +#define ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT (WINHTTP_ERROR_BASE + 167) +#define ERROR_WINHTTP_SECURE_INVALID_CERT (WINHTTP_ERROR_BASE + 169) +#define ERROR_WINHTTP_SECURE_CERT_REVOKED (WINHTTP_ERROR_BASE + 170) +#define ERROR_WINHTTP_NOT_INITIALIZED (WINHTTP_ERROR_BASE + 172) +#define ERROR_WINHTTP_SECURE_FAILURE (WINHTTP_ERROR_BASE + 175) +#define ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR (WINHTTP_ERROR_BASE + 178) +#define ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE (WINHTTP_ERROR_BASE + 179) +#define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180) +#define ERROR_WINHTTP_HEADER_COUNT_EXCEEDED (WINHTTP_ERROR_BASE + 181) +#define ERROR_WINHTTP_HEADER_SIZE_OVERFLOW (WINHTTP_ERROR_BASE + 182) +#define ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW (WINHTTP_ERROR_BASE + 183) +#define ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW (WINHTTP_ERROR_BASE + 184) +#define ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY (WINHTTP_ERROR_BASE + 185) +#define ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY (WINHTTP_ERROR_BASE + 186) +#define WINHTTP_ERROR_LAST (WINHTTP_ERROR_BASE + 186) /* WinHttp status codes */ #define HTTP_STATUS_CONTINUE 100 @@ -204,6 +265,178 @@ typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; #define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP +#define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100 +#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID 0x00002000 +#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID 0x00001000 +#define SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE 0x00000200 +#define SECURITY_FLAG_SECURE 0x00000001 +#define SECURITY_FLAG_STRENGTH_WEAK 0x10000000 +#define SECURITY_FLAG_STRENGTH_MEDIUM 0x40000000 +#define SECURITY_FLAG_STRENGTH_STRONG 0x20000000 + +#define ICU_NO_ENCODE 0x20000000 +#define ICU_DECODE 0x10000000 +#define ICU_NO_META 0x08000000 +#define ICU_ENCODE_SPACES_ONLY 0x04000000 +#define ICU_BROWSER_MODE 0x02000000 +#define ICU_ENCODE_PERCENT 0x00001000 + +/* Query flags */ +#define WINHTTP_QUERY_MIME_VERSION 0 +#define WINHTTP_QUERY_CONTENT_TYPE 1 +#define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2 +#define WINHTTP_QUERY_CONTENT_ID 3 +#define WINHTTP_QUERY_CONTENT_DESCRIPTION 4 +#define WINHTTP_QUERY_CONTENT_LENGTH 5 +#define WINHTTP_QUERY_CONTENT_LANGUAGE 6 +#define WINHTTP_QUERY_ALLOW 7 +#define WINHTTP_QUERY_PUBLIC 8 +#define WINHTTP_QUERY_DATE 9 +#define WINHTTP_QUERY_EXPIRES 10 +#define WINHTTP_QUERY_LAST_MODIFIED 11 +#define WINHTTP_QUERY_MESSAGE_ID 12 +#define WINHTTP_QUERY_URI 13 +#define WINHTTP_QUERY_DERIVED_FROM 14 +#define WINHTTP_QUERY_COST 15 +#define WINHTTP_QUERY_LINK 16 +#define WINHTTP_QUERY_PRAGMA 17 +#define WINHTTP_QUERY_VERSION 18 +#define WINHTTP_QUERY_STATUS_CODE 19 +#define WINHTTP_QUERY_STATUS_TEXT 20 +#define WINHTTP_QUERY_RAW_HEADERS 21 +#define WINHTTP_QUERY_RAW_HEADERS_CRLF 22 +#define WINHTTP_QUERY_CONNECTION 23 +#define WINHTTP_QUERY_ACCEPT 24 +#define WINHTTP_QUERY_ACCEPT_CHARSET 25 +#define WINHTTP_QUERY_ACCEPT_ENCODING 26 +#define WINHTTP_QUERY_ACCEPT_LANGUAGE 27 +#define WINHTTP_QUERY_AUTHORIZATION 28 +#define WINHTTP_QUERY_CONTENT_ENCODING 29 +#define WINHTTP_QUERY_FORWARDED 30 +#define WINHTTP_QUERY_FROM 31 +#define WINHTTP_QUERY_IF_MODIFIED_SINCE 32 +#define WINHTTP_QUERY_LOCATION 33 +#define WINHTTP_QUERY_ORIG_URI 34 +#define WINHTTP_QUERY_REFERER 35 +#define WINHTTP_QUERY_RETRY_AFTER 36 +#define WINHTTP_QUERY_SERVER 37 +#define WINHTTP_QUERY_TITLE 38 +#define WINHTTP_QUERY_USER_AGENT 39 +#define WINHTTP_QUERY_WWW_AUTHENTICATE 40 +#define WINHTTP_QUERY_PROXY_AUTHENTICATE 41 +#define WINHTTP_QUERY_ACCEPT_RANGES 42 +#define WINHTTP_QUERY_SET_COOKIE 43 +#define WINHTTP_QUERY_COOKIE 44 +#define WINHTTP_QUERY_REQUEST_METHOD 45 +#define WINHTTP_QUERY_REFRESH 46 +#define WINHTTP_QUERY_CONTENT_DISPOSITION 47 +#define WINHTTP_QUERY_AGE 48 +#define WINHTTP_QUERY_CACHE_CONTROL 49 +#define WINHTTP_QUERY_CONTENT_BASE 50 +#define WINHTTP_QUERY_CONTENT_LOCATION 51 +#define WINHTTP_QUERY_CONTENT_MD5 52 +#define WINHTTP_QUERY_CONTENT_RANGE 53 +#define WINHTTP_QUERY_ETAG 54 +#define WINHTTP_QUERY_HOST 55 +#define WINHTTP_QUERY_IF_MATCH 56 +#define WINHTTP_QUERY_IF_NONE_MATCH 57 +#define WINHTTP_QUERY_IF_RANGE 58 +#define WINHTTP_QUERY_IF_UNMODIFIED_SINCE 59 +#define WINHTTP_QUERY_MAX_FORWARDS 60 +#define WINHTTP_QUERY_PROXY_AUTHORIZATION 61 +#define WINHTTP_QUERY_RANGE 62 +#define WINHTTP_QUERY_TRANSFER_ENCODING 63 +#define WINHTTP_QUERY_UPGRADE 64 +#define WINHTTP_QUERY_VARY 65 +#define WINHTTP_QUERY_VIA 66 +#define WINHTTP_QUERY_WARNING 67 +#define WINHTTP_QUERY_EXPECT 68 +#define WINHTTP_QUERY_PROXY_CONNECTION 69 +#define WINHTTP_QUERY_UNLESS_MODIFIED_SINCE 70 +#define WINHTTP_QUERY_PROXY_SUPPORT 75 +#define WINHTTP_QUERY_AUTHENTICATION_INFO 76 +#define WINHTTP_QUERY_PASSPORT_URLS 77 +#define WINHTTP_QUERY_PASSPORT_CONFIG 78 +#define WINHTTP_QUERY_MAX 78 +#define WINHTTP_QUERY_CUSTOM 65535 +#define WINHTTP_QUERY_FLAG_REQUEST_HEADERS 0x80000000 +#define WINHTTP_QUERY_FLAG_SYSTEMTIME 0x40000000 +#define WINHTTP_QUERY_FLAG_NUMBER 0x20000000 + +/* Callback options */ +#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001 +#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002 +#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004 +#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008 +#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010 +#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020 +#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040 +#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080 +#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100 +#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200 +#define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400 +#define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800 +#define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000 +#define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000 +#define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000 +#define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000 +#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000 +#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000 +#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000 +#define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000 +#define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000 +#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000 +#define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED) +#define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER) +#define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT) +#define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED) +#define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED) +#define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) +#define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY +#define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT +#define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE +#define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE +#define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE +#define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE +#define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE +#define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE +#define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE +#define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR +#define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) +#define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff +#define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L)) + +#define API_RECEIVE_RESPONSE (1) +#define API_QUERY_DATA_AVAILABLE (2) +#define API_READ_DATA (3) +#define API_WRITE_DATA (4) +#define API_SEND_REQUEST (5) + +#define WINHTTP_HANDLE_TYPE_SESSION 1 +#define WINHTTP_HANDLE_TYPE_CONNECT 2 +#define WINHTTP_HANDLE_TYPE_REQUEST 3 + +#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED 0x00000001 +#define WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT 0x00000002 +#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED 0x00000004 +#define WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA 0x00000008 +#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID 0x00000010 +#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID 0x00000020 +#define WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE 0x00000040 +#define WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR 0x80000000 + +#define WINHTTP_AUTH_SCHEME_BASIC 0x00000001 +#define WINHTTP_AUTH_SCHEME_NTLM 0x00000002 +#define WINHTTP_AUTH_SCHEME_PASSPORT 0x00000004 +#define WINHTTP_AUTH_SCHEME_DIGEST 0x00000008 +#define WINHTTP_AUTH_SCHEME_NEGOTIATE 0x00000010 + +#define WINHTTP_AUTH_TARGET_SERVER 0x00000000 +#define WINHTTP_AUTH_TARGET_PROXY 0x00000001 + + typedef struct { DWORD dwStructSize; diff --git a/include/winnt.h b/include/winnt.h index f9ae9d4a4a5..e8a37f510e8 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -1913,6 +1913,7 @@ typedef CONTEXT *PCONTEXT; #define WT_EXECUTEINPERSISTENTTHREAD 0x80 #define WT_EXECUTEINLONGTHREAD 0x10 #define WT_EXECUTEDELETEWAIT 0x08 +#define WT_TRANSFER_IMPERSONATION 0x0100 #define EXCEPTION_CONTINUABLE 0 @@ -4565,6 +4566,9 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS { #define KEY_ENUMERATE_SUB_KEYS 0x00000008 #define KEY_NOTIFY 0x00000010 #define KEY_CREATE_LINK 0x00000020 +#define KEY_WOW64_64KEY 0x00000100 +#define KEY_WOW64_32KEY 0x00000200 +#define KEY_WOW64_RES 0x00000300 /* for RegKeyRestore flags */ #define REG_WHOLE_HIVE_VOLATILE 0x00000001 diff --git a/include/winternl.h b/include/winternl.h index fe2f83d3feb..2dc1fc2ba95 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2117,6 +2117,8 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*); NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEAP_DEFINITION); NTSYSAPI NTSTATUS WINAPI RtlCreateProcessParameters(RTL_USER_PROCESS_PARAMETERS**,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,PWSTR,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*); NTSYSAPI NTSTATUS WINAPI RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD); +NTSYSAPI NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE); +NTSYSAPI NTSTATUS WINAPI RtlCreateTimer(PHANDLE, HANDLE, RTL_WAITORTIMERCALLBACKFUNC, PVOID, DWORD, DWORD, ULONG); NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR); NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR); NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*); @@ -2127,6 +2129,8 @@ NTSYSAPI NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *); NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR); NTSYSAPI void WINAPI RtlDeleteResource(LPRTL_RWLOCK); NTSYSAPI NTSTATUS WINAPI RtlDeleteSecurityObject(PSECURITY_DESCRIPTOR*); +NTSYSAPI NTSTATUS WINAPI RtlDeleteTimer(HANDLE, HANDLE, HANDLE); +NTSYSAPI NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE, HANDLE); NTSYSAPI PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*); NTSYSAPI NTSTATUS WINAPI RtlDeregisterWait(HANDLE); NTSYSAPI NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE,HANDLE); @@ -2337,6 +2341,7 @@ NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING*,const NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString(STRING*,const UNICODE_STRING*,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeToOemN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); +NTSYSAPI NTSTATUS WINAPI RtlUpdateTimer(HANDLE, HANDLE, DWORD, DWORD); NTSYSAPI CHAR WINAPI RtlUpperChar(CHAR); NTSYSAPI void WINAPI RtlUpperString(STRING *,const STRING *); NTSYSAPI NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR); diff --git a/loader/kthread.c b/loader/kthread.c index efffd99f32a..cc51cc06038 100644 --- a/loader/kthread.c +++ b/loader/kthread.c @@ -52,8 +52,8 @@ struct _pthread_cleanup_buffer; #ifdef HAVE_RESOLV_H # include #endif -#ifdef HAVE_VALGRIND_MEMCHECK_H -#include +#ifdef HAVE_VALGRIND_VALGRIND_H +#include #endif #ifdef HAVE_SYS_SYSCALL_H # include diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index 2b2daf126ad..13bfc17c90c 100644 --- a/programs/regedit/regproc.c +++ b/programs/regedit/regproc.c @@ -1177,11 +1177,9 @@ BOOL import_registry_file(FILE* reg_file) { if (s[0] == 0xff && s[1] == 0xfe) { - printf("Trying to open unicode file\n"); processRegLinesW(reg_file); } else { - printf("ansi file\n"); rewind(reg_file); processRegLinesA(reg_file); } diff --git a/programs/winedbg/display.c b/programs/winedbg/display.c index a1fa89e8ffb..090196110ee 100644 --- a/programs/winedbg/display.c +++ b/programs/winedbg/display.c @@ -56,7 +56,7 @@ static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2) int display_add(struct expr *exp, int count, char format) { - int i; + unsigned i; BOOL local_binding = FALSE; for (i = 0; i < ndisplays; i++) @@ -98,7 +98,7 @@ int display_add(struct expr *exp, int count, char format) int display_info(void) { - int i; + unsigned i; char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* func; const char* info; @@ -163,7 +163,7 @@ static void print_one_display(int i) int display_print(void) { - int i; + unsigned i; char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* func; @@ -187,8 +187,6 @@ int display_print(void) int display_delete(int displaynum) { - int i; - if (displaynum > ndisplays || displaynum == 0 || displaynum < -1 || displaypoints[displaynum - 1].exp == NULL) { @@ -198,6 +196,8 @@ int display_delete(int displaynum) if (displaynum == -1) { + unsigned i; + for (i = 0; i < ndisplays; i++) { if (displaypoints[i].exp != NULL) diff --git a/programs/winetest/send.c b/programs/winetest/send.c index c8372f35b35..947f2c197e5 100644 --- a/programs/winetest/send.c +++ b/programs/winetest/send.c @@ -109,7 +109,7 @@ send_file (const char *name) #define BUFLEN 8192 char buffer[BUFLEN+1]; DWORD bytes_read, filesize; - size_t total; + size_t total, count; char *str; int ret; @@ -208,9 +208,9 @@ send_file (const char *name) return 1; } - str = strmake (&bytes_read, "Received %s (%d bytes).\n", + str = strmake (&count, "Received %s (%d bytes).\n", name, filesize); - ret = memcmp (str, buffer + total - bytes_read, bytes_read); + ret = memcmp (str, buffer + total - count, count); free (str); if (ret) { buffer[total] = 0; diff --git a/programs/wordpad/Nl.rc b/programs/wordpad/Nl.rc index d491b2173b7..73da63f28dd 100644 --- a/programs/wordpad/Nl.rc +++ b/programs/wordpad/Nl.rc @@ -237,4 +237,6 @@ BEGIN STRING_OLE_STORAGE_NOT_SUPPORTED, "OLE storage documenten zijn niet ondersteund" STRING_WRITE_FAILED, "Bestand kon niet opgeslagen worden." STRING_WRITE_ACCESS_DENIED, "Onvoldoende rechten om het bestand op te slaan." + STRING_OPEN_FAILED, "Bestand kon niet geopend worden." + STRING_OPEN_ACCESS_DENIED, "Onvoldoende rechten om het bestand te openen." END diff --git a/programs/wordpad/print.c b/programs/wordpad/print.c index c0cd182d17e..933c8b845d6 100644 --- a/programs/wordpad/print.c +++ b/programs/wordpad/print.c @@ -814,7 +814,7 @@ void update_preview(HWND hWnd) InvalidateRect(hWnd, &rc, TRUE); } -LRESULT preview_command(HWND hWnd, WPARAM wParam, LPARAM lParam) +LRESULT preview_command(HWND hWnd, WPARAM wParam) { switch(LOWORD(wParam)) { diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index be6bb8be55a..d98758aa880 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -2467,7 +2467,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_COMMAND: if(preview_isactive()) { - return preview_command( hWnd, wParam, lParam ); + return preview_command( hWnd, wParam ); } return OnCommand( hWnd, wParam, lParam ); diff --git a/programs/wordpad/wordpad.h b/programs/wordpad/wordpad.h index 96b2a25893f..9f093b32a79 100644 --- a/programs/wordpad/wordpad.h +++ b/programs/wordpad/wordpad.h @@ -204,7 +204,7 @@ void dialog_printsetup(HWND); void dialog_print(HWND, LPWSTR); void target_device(HWND, DWORD); void print_quick(LPWSTR); -LRESULT preview_command(HWND, WPARAM, LPARAM); +LRESULT preview_command(HWND, WPARAM); void init_preview(HWND, LPWSTR); void close_preview(HWND); BOOL preview_isactive(void); diff --git a/server/thread.c b/server/thread.c index 4929b4ab707..0c496db7103 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1160,8 +1160,7 @@ DECL_HANDLER(resume_thread) if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) { - if (thread->state == TERMINATED) set_error( STATUS_ACCESS_DENIED ); - else reply->count = resume_thread( thread ); + reply->count = resume_thread( thread ); release_object( thread ); } } diff --git a/tools/make_makefiles b/tools/make_makefiles index d87b3ce205a..8f15011fa52 100755 --- a/tools/make_makefiles +++ b/tools/make_makefiles @@ -104,30 +104,13 @@ my @ignore_srcs = ( [ 'IDL_S_SRCS', '\.idl', '_s.c' ], ); -my %private_headers = ( - "wine/irot.idl" => 1, - "wine/list.h" => 1, - "wine/mmsystem16.h" => 1, - "wine/mscvpdb.h" => 1, - "wine/port.h" => 1, - "wine/pthread.h" => 1, - "wine/rpcfc.h" => 1, - "wine/server.h" => 1, - "wine/server_protocol.h" => 1, - "wine/test.h" => 1, - "wine/wgl.h" => 1, - "wine/winaspi.h" => 1, - "wine/winbase16.h" => 1, - "wine/windef16.h" => 1, - "wine/wined3d_caps.h" => 1, - "wine/wined3d_gl.h" => 1, - "wine/wined3d_interface.h" => 1, - "wine/wined3d_types.h" => 1, - "wine/wingdi16.h" => 1, - "wine/winnet16.h" => 1, - "wine/winsock16.h" => 1, - "wine/winuser16.h" => 1, - "wine/wpp.h" => 1 +my %exported_wine_headers = ( + "wine/debug.h" => 1, + "wine/exception.h" => 1, + "wine/library.h" => 1, + "wine/unicode.h" => 1, + "wine/itss.idl" => 1, + "wine/svcctl.idl" => 1, ); my %private_idl_headers = ( @@ -654,7 +637,7 @@ sub update_includes() foreach my $incl (@includes) { if ($incl =~ /(.*)\//) { $subdirs{$1} = 1; } - next if ($private_headers{$incl}); + next if ($incl =~ /^wine\// && !$exported_wine_headers{$incl}); if ($incl =~ /stdole2\.idl$/) { push @tlb_srcs, $incl; } elsif ($private_idl_headers{$incl}) { push @h_srcs, $incl; } elsif ($incl =~ /\.h$/) { push @h_srcs, $incl; } diff --git a/tools/runtest b/tools/runtest index 43f513f9733..a3c9331c89b 100755 --- a/tools/runtest +++ b/tools/runtest @@ -118,4 +118,10 @@ fi WINETEST_PLATFORM=${platform:-wine} export WINETEST_PLATFORM WINETEST_DEBUG -exec "$topobjdir/wine" "$program" "$infile" "$@" +# WINETEST_WRAPPER is normally empty, but can be set by caller, e.g. +# WINETEST_WRAPPER=time +# would give data about how long each test takes, and +# WINETEST_WRAPPER=valgrind +# would run the tests under valgrind to look for memory errors. + +exec $WINETEST_WRAPPER "$topobjdir/wine" "$program" "$infile" "$@" diff --git a/tools/wine.inf.in b/tools/wine.inf.in index 3e3a62528ab..da5020d96be 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -2243,6 +2243,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,actxprxy.dll 11,,advapi32.dll 11,,advpack.dll +11,,appwiz.cpl 11,,cabinet.dll 11,,cmd.exe 11,,comctl32.dll diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 85309ad8a3a..b13b99406a4 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -116,7 +116,7 @@ enum target_cpu enum target_platform { - PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_WINDOWS + PLATFORM_UNSPECIFIED, PLATFORM_APPLE, PLATFORM_SOLARIS, PLATFORM_WINDOWS }; extern enum target_cpu target_cpu; diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 82ee59dc9bf..3f2dcf214e5 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -65,6 +65,8 @@ enum target_cpu target_cpu = CPU_POWERPC; #ifdef __APPLE__ enum target_platform target_platform = PLATFORM_APPLE; +#elif defined(__sun) +enum target_platform target_platform = PLATFORM_SOLARIS; #elif defined(_WINDOWS) enum target_platform target_platform = PLATFORM_WINDOWS; #else @@ -124,6 +126,7 @@ static const struct { { "macos", PLATFORM_APPLE }, { "darwin", PLATFORM_APPLE }, + { "solaris", PLATFORM_SOLARIS }, { "windows", PLATFORM_WINDOWS }, { "winnt", PLATFORM_WINDOWS } }; diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 5038579b0de..afcc7dad40e 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -358,15 +358,20 @@ void BuildSpec32File( DLLSPEC *spec ) /* Reserve some space for the PE header */ - if (target_platform == PLATFORM_APPLE) + switch (target_platform) { + case PLATFORM_APPLE: output( "\t.text\n" ); output( "\t.align %d\n", get_alignment(page_size) ); output( "__wine_spec_pe_header:\n" ); output( "\t.space 65536\n" ); - } - else - { + break; + case PLATFORM_SOLARIS: + output( "\n\t.section \".text\",\"ax\"\n" ); + output( "__wine_spec_pe_header:\n" ); + output( "\t.skip %u\n", 65536 + page_size ); + break; + default: output( "\n\t.section \".init\",\"ax\"\n" ); switch(target_cpu) { @@ -383,6 +388,7 @@ void BuildSpec32File( DLLSPEC *spec ) output( "__wine_spec_pe_header:\n" ); output( "\t.skip %u\n", 65536 + page_size ); output( "1:\n" ); + break; } /* Output the NT header */ diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index b4a314df3aa..113819d26cc 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -160,6 +160,7 @@ struct options const char* wine_objdir; const char* output_name; const char* image_base; + const char* section_align; strarray* prefix; strarray* lib_dirs; strarray* linker_args; @@ -640,6 +641,17 @@ static void build(struct options* opts) } #endif +#ifdef __sun + { + char *mapfile = get_temp_file( output_name, ".map" ); + const char *align = opts->section_align ? opts->section_align : "0x1000"; + + create_file( mapfile, 0644, "text = A%s;\ndata = A%s;\n", align, align ); + strarray_add(link_args, strmake("-Wl,-M,%s", mapfile)); + strarray_add(tmp_files, mapfile); + } +#endif + for ( j = 0; j < lib_dirs->size; j++ ) strarray_add(link_args, strmake("-L%s", lib_dirs->base[j])); @@ -971,6 +983,11 @@ int main(int argc, char **argv) opts.image_base = strdup( Wl->base[++j] ); continue; } + if (!strcmp(Wl->base[j], "--section-alignment") && j < Wl->size - 1) + { + opts.section_align = strdup( Wl->base[++j] ); + continue; + } if (!strcmp(Wl->base[j], "-static")) linking = -1; strarray_add(opts.linker_args, strmake("-Wl,%s",Wl->base[j])); } -- 2.11.4.GIT