From e61237200caa2298b779bb669e8980dfa9847c48 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Thu, 25 Sep 2008 00:11:14 +0200 Subject: [PATCH] push 4e98c31ec75caed2ea3040ac2e710b58ba1ca0e1 --- aclocal.m4 | 2 +- configure | 377 ++++++++++++++++++++++++------ configure.ac | 36 +-- dlls/Makefile.in | 5 + dlls/comctl32/syslink.c | 2 +- dlls/comctl32/tests/imagelist.c | 16 +- dlls/comctl32/tests/monthcal.c | 6 +- dlls/comctl32/tests/status.c | 6 +- dlls/comctl32/theming.c | 4 +- dlls/comdlg32/fontdlg.c | 4 +- dlls/comdlg32/printdlg.c | 2 +- dlls/credui/credui_main.c | 2 +- dlls/crypt32/encode.c | 14 +- dlls/crypt32/oid.c | 4 +- dlls/crypt32/str.c | 10 +- dlls/crypt32/tests/message.c | 46 ++-- dlls/cryptdlg/Makefile.in | 2 +- dlls/cryptdlg/main.c | 358 +++++++++++++++++++++++++++- dlls/cryptnet/cryptnet_main.c | 1 + dlls/cryptui/Makefile.in | 1 + dlls/cryptui/cryptui.spec | 2 +- dlls/cryptui/main.c | 35 +++ dlls/d3dxof/d3dxof.c | 180 +++++++------- dlls/d3dxof/d3dxof_private.h | 3 + dlls/ddraw/tests/ddrawmodes.c | 9 +- dlls/dsound/tests/dsound.c | 9 +- dlls/imm32/tests/imm32.c | 9 + dlls/inetcomm/inetcomm.spec | 4 +- dlls/inetcomm/mimeintl.c | 36 ++- dlls/inetcomm/mimeole.c | 63 ++++- dlls/inetcomm/tests/mimeintl.c | 3 + dlls/inetcomm/tests/mimeole.c | 5 + dlls/jscript/array.c | 477 ++++++++++++++++++++++++++++++++++++-- dlls/jscript/dispex.c | 50 ++-- dlls/jscript/engine.c | 24 +- dlls/jscript/engine.h | 7 +- dlls/jscript/function.c | 63 ++++- dlls/jscript/global.c | 77 +++++- dlls/jscript/jscript.c | 2 +- dlls/jscript/jscript.h | 16 ++ dlls/jscript/jsutils.c | 108 ++++++++- dlls/jscript/lex.c | 16 +- dlls/jscript/math.c | 158 ++++++++++++- dlls/jscript/number.c | 89 ++++++- dlls/jscript/object.c | 19 +- dlls/jscript/parser.y | 25 +- dlls/jscript/regexp.c | 78 ++++++- dlls/jscript/string.c | 342 +++++++++++++++++++++++++-- dlls/jscript/tests/api.js | 275 +++++++++++++++++++++- dlls/jscript/tests/lang.js | 18 +- dlls/jscript/tests/regexp.js | 24 ++ dlls/kernel32/profile.c | 1 + dlls/kernel32/tests/file.c | 10 +- dlls/kernel32/tests/loader.c | 2 +- dlls/kernel32/tests/module.c | 2 +- dlls/kernel32/tests/path.c | 8 + dlls/kernel32/tests/process.c | 32 ++- dlls/kernel32/tests/profile.c | 32 ++- dlls/mscms/mscms_priv.h | 1 + dlls/mshtml/dispex.c | 35 ++- dlls/mshtml/htmlbody.c | 19 +- dlls/mshtml/htmlelem.c | 15 +- dlls/mshtml/htmlnode.c | 45 ++-- dlls/mshtml/tests/dom.c | 32 +-- dlls/msi/automation.c | 2 +- dlls/msvcrt/dir.c | 4 +- dlls/msvcrt/locale.c | 3 +- dlls/msvcrt/process.c | 2 +- dlls/msxml3/node.c | 44 +++- dlls/msxml3/saxreader.c | 33 ++- dlls/msxml3/tests/saxreader.c | 21 ++ dlls/netapi32/access.c | 37 ++- dlls/ntdll/tests/atom.c | 4 + dlls/ntdll/tests/env.c | 5 + dlls/ntdll/tests/error.c | 3 + dlls/ntdll/tests/om.c | 52 +++-- dlls/ntdll/tests/path.c | 6 + dlls/ntdll/tests/port.c | 1 + dlls/oleaut32/tests/olefont.c | 4 +- dlls/oleaut32/tests/varformat.c | 4 +- dlls/oleaut32/tmarshal.c | 6 +- dlls/oleaut32/typelib.c | 55 ++--- dlls/quartz/avisplit.c | 6 +- dlls/quartz/filesource.c | 6 +- dlls/quartz/filtergraph.c | 6 +- dlls/quartz/parser.c | 2 + dlls/quartz/pin.c | 11 + dlls/riched20/paint.c | 2 +- dlls/rpcrt4/cstub.c | 8 +- dlls/rpcrt4/rpc_server.c | 34 +++ dlls/rpcrt4/rpcrt4.spec | 4 +- dlls/secur32/Makefile.in | 1 + dlls/secur32/schannel.c | 218 ++++++++++++++++- dlls/secur32/secur32.c | 2 + dlls/secur32/secur32_priv.h | 3 + dlls/secur32/tests/main.c | 3 +- dlls/secur32/tests/schannel.c | 26 +++ dlls/shdocvw/navigate.c | 3 +- dlls/shdocvw/shdocvw.inf | 5 +- dlls/shell32/tests/appbar.c | 329 +++++++++++++------------- dlls/user32/defwnd.c | 12 + dlls/user32/spy.c | 3 +- dlls/user32/tests/input.c | 28 +-- dlls/user32/tests/listbox.c | 37 ++- dlls/user32/tests/msg.c | 94 ++++++-- dlls/user32/tests/winstation.c | 10 +- dlls/user32/user_private.h | 1 + dlls/userenv/tests/userenv.c | 16 +- dlls/wined3d/arb_program_shader.c | 368 +++++++++++++++++------------ dlls/wined3d/baseshader.c | 11 +- dlls/wined3d/context.c | 45 +++- dlls/wined3d/device.c | 49 ++-- dlls/wined3d/drawprim.c | 17 +- dlls/wined3d/glsl_shader.c | 192 ++++++++++----- dlls/wined3d/pixelshader.c | 170 +++++++------- dlls/wined3d/surface.c | 29 ++- dlls/wined3d/swapchain.c | 7 + dlls/wined3d/vertexdeclaration.c | 90 ++++++- dlls/wined3d/vertexshader.c | 116 ++++----- dlls/wined3d/wined3d_private.h | 197 ++++++++-------- dlls/winex11.drv/window.c | 13 +- dlls/winhttp/Makefile.in | 3 +- dlls/winhttp/main.c | 38 --- dlls/winhttp/tests/Makefile.in | 1 + dlls/winhttp/tests/url.c | 275 ++++++++++++++++++++++ dlls/winhttp/url.c | 333 ++++++++++++++++++++++++++ dlls/wintrust/softpub.c | 132 +++++++++-- dlls/wintrust/wintrust_main.c | 282 +++++++++++++++++++--- include/Makefile.in | 1 + include/config.h.in | 3 + include/d3d8types.h | 2 + include/d3d9types.h | 2 + include/rpcdce.h | 6 + include/shdispid.h | 30 +++ include/shldisp.idl | 25 ++ include/wine/wined3d_types.h | 7 + include/winhttp.h | 2 + programs/regedit/regproc.c | 39 ++-- 138 files changed, 5635 insertions(+), 1364 deletions(-) create mode 100644 dlls/winhttp/tests/url.c create mode 100644 dlls/winhttp/url.c create mode 100644 include/shdispid.h diff --git a/aclocal.m4 b/aclocal.m4 index be9192ea54c..528c4d36d4d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -141,7 +141,7 @@ dnl AC_DEFUN([WINE_CHECK_MINGW_PROG], [AC_CHECK_PROGS([$1], m4_foreach([ac_wine_prefix], - [i586-mingw32msvc, i386-mingw32msvc, i686-mingw32, i586-mingw32, i386-mingw32, mingw32, mingw], + [i586-mingw32msvc, i386-mingw32msvc, i686-mingw32, i586-mingw32, i486-mingw32, i386-mingw32, mingw32, mingw], [ac_wine_prefix-$2 ]), [$3],[$4])]) diff --git a/configure b/configure index a19cea165b4..42048cab55c 100755 --- a/configure +++ b/configure @@ -743,6 +743,7 @@ XML2INCL XSLTLIBS XSLTINCL HALINCL +GNUTLSINCL sane_devel SANEINCL gphoto2_devel @@ -1403,6 +1404,7 @@ Optional Packages: --without-freetype do not use the FreeType library --without-gphoto do not use gphoto (Digital Camera support) --without-glu do not use the GLU library + --without-gnutls do not use GnuTLS (schannel support) --without-hal do not use HAL (dynamic device support) --without-jack do not use the Jack sound support --without-jpeg do not use JPEG @@ -1999,6 +2001,12 @@ if test "${with_glu+set}" = set; then fi +# Check whether --with-gnutls was given. +if test "${with_gnutls+set}" = set; then + withval=$with_gnutls; +fi + + # Check whether --with-hal was given. if test "${with_hal+set}" = set; then withval=$with_hal; @@ -9400,7 +9408,7 @@ echo "${ECHO_T}$ac_cv_c_dll_hpux" >&6; } if test "$cross_compiling" = "no" then - for ac_prog in i586-mingw32msvc-gcc i386-mingw32msvc-gcc i686-mingw32-gcc i586-mingw32-gcc i386-mingw32-gcc mingw32-gcc mingw-gcc + for ac_prog in i586-mingw32msvc-gcc i386-mingw32msvc-gcc i686-mingw32-gcc i586-mingw32-gcc i486-mingw32-gcc i386-mingw32-gcc mingw32-gcc mingw-gcc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -9443,7 +9451,7 @@ fi done test -n "$CROSSCC" || CROSSCC="false" - for ac_prog in i586-mingw32msvc-dlltool i386-mingw32msvc-dlltool i686-mingw32-dlltool i586-mingw32-dlltool i386-mingw32-dlltool mingw32-dlltool mingw-dlltool + for ac_prog in i586-mingw32msvc-dlltool i386-mingw32msvc-dlltool i686-mingw32-dlltool i586-mingw32-dlltool i486-mingw32-dlltool i386-mingw32-dlltool mingw32-dlltool mingw-dlltool do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -9486,7 +9494,7 @@ fi done test -n "$DLLTOOL" || DLLTOOL="false" - for ac_prog in i586-mingw32msvc-windres i386-mingw32msvc-windres i686-mingw32-windres i586-mingw32-windres i386-mingw32-windres mingw32-windres mingw-windres + for ac_prog in i586-mingw32msvc-windres i386-mingw32msvc-windres i686-mingw32-windres i586-mingw32-windres i486-mingw32-windres i386-mingw32-windres mingw32-windres mingw-windres do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -9529,7 +9537,7 @@ fi done test -n "$CROSSWINDRES" || CROSSWINDRES="false" - for ac_prog in i586-mingw32msvc-ar i386-mingw32msvc-ar i686-mingw32-ar i586-mingw32-ar i386-mingw32-ar mingw32-ar mingw-ar + for ac_prog in i586-mingw32msvc-ar i386-mingw32msvc-ar i686-mingw32-ar i586-mingw32-ar i486-mingw32-ar i386-mingw32-ar mingw32-ar mingw-ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -11395,6 +11403,11 @@ fi else opengl_msg="OpenGL development headers not found." fi + test -n "$opengl_msg" && enable_opengl32=${enable_opengl32:-no} + test "x$ac_cv_lib_soname_GLU" = "x" && enable_glu32=${enable_glu32:-no} + else + enable_opengl32=${enable_opengl32:-no} + enable_glu32=${enable_glu32:-no} fi if test -n "$opengl_msg"; then case "x$with_opengl" in @@ -11412,9 +11425,6 @@ esac fi - test -n "$opengl_msg" && enable_opengl32=${enable_opengl32:-no} - test "x$ac_cv_lib_soname_GLU" = "x" && enable_glu32=${enable_glu32:-no} - NASLIBS="" @@ -12745,6 +12755,240 @@ esac fi +if test "x$with_gnutls" != "xno" -a "$PKG_CONFIG" != "false" +then + ac_save_CPPFLAGS="$CPPFLAGS" + ac_gnutls_libs="`$PKG_CONFIG --libs gnutls 2>/dev/null`" + ac_gnutls_cflags="`$PKG_CONFIG --cflags gnutls 2>/dev/null`" + CPPFLAGS="$CPPFLAGS $ac_gnutls_cflags" + if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then + { echo "$as_me:$LINENO: checking for gnutls/gnutls.h" >&5 +echo $ECHO_N "checking for gnutls/gnutls.h... $ECHO_C" >&6; } +if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_gnutls_gnutls_h" >&5 +echo "${ECHO_T}$ac_cv_header_gnutls_gnutls_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking gnutls/gnutls.h usability" >&5 +echo $ECHO_N "checking gnutls/gnutls.h 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 +_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 gnutls/gnutls.h presence" >&5 +echo $ECHO_N "checking gnutls/gnutls.h 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 +_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: gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: gnutls/gnutls.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: gnutls/gnutls.h: 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 gnutls/gnutls.h" >&5 +echo $ECHO_N "checking for gnutls/gnutls.h... $ECHO_C" >&6; } +if test "${ac_cv_header_gnutls_gnutls_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_gnutls_gnutls_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_gnutls_gnutls_h" >&5 +echo "${ECHO_T}$ac_cv_header_gnutls_gnutls_h" >&6; } + +fi +if test $ac_cv_header_gnutls_gnutls_h = yes; then + { echo "$as_me:$LINENO: checking for -lgnutls" >&5 +echo $ECHO_N "checking for -lgnutls... $ECHO_C" >&6; } +if test "${ac_cv_lib_soname_gnutls+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_soname_save_LIBS=$LIBS +LIBS="-lgnutls $ac_gnutls_libs $LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gnutls_global_init (); +int +main () +{ +return gnutls_global_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +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_link") 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_exeext && + $as_test_x conftest$ac_exeext; then + case "$LIBEXT" in + dll) ;; + dylib) ac_cv_lib_soname_gnutls=`otool -L conftest$ac_exeext | grep "libgnutls\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libgnutls\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;; + *) ac_cv_lib_soname_gnutls=`$ac_cv_path_LDD conftest$ac_exeext | grep "libgnutls\\.$LIBEXT" | sed -e "s/^.*\(libgnutls\.$LIBEXT[^ ]*\).*$/\1/"';2,$d'` ;; + esac +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_soname_save_LIBS +fi +if test "x$ac_cv_lib_soname_gnutls" = "x"; then + { echo "$as_me:$LINENO: result: not found" >&5 +echo "${ECHO_T}not found" >&6; } + +else + { echo "$as_me:$LINENO: result: $ac_cv_lib_soname_gnutls" >&5 +echo "${ECHO_T}$ac_cv_lib_soname_gnutls" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBGNUTLS "$ac_cv_lib_soname_gnutls" +_ACEOF + + GNUTLSINCL="$ac_gnutls_cflags" + +fi + +fi + + + CPPFLAGS="$ac_save_CPPFLAGS" +fi +if test "x$ac_cv_lib_soname_gnutls" = "x"; then + case "x$with_gnutls" in + x) wine_notices="$wine_notices|libgnutls development files not found, no schannel support." ;; + xno) ;; + *) { { echo "$as_me:$LINENO: error: libgnutls development files not found, no schannel support. +This is an error since --with-gnutls was requested." >&5 +echo "$as_me: error: libgnutls development files not found, no schannel support. +This is an error since --with-gnutls was requested." >&2;} + { (exit 1); exit 1; }; } ;; +esac +fi + + CURSESLIBS="" if test "$ac_cv_header_ncurses_h" = "yes" then @@ -16282,6 +16526,65 @@ _ACEOF fi + { echo "$as_me:$LINENO: checking whether the compiler supports -fno-builtin" >&5 +echo $ECHO_N "checking whether the compiler supports -fno-builtin... $ECHO_C" >&6; } +if test "${ac_cv_cflags__fno_builtin+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_wine_try_cflags_saved=$CFLAGS +CFLAGS="$CFLAGS -fno-builtin" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +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_link") 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_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_cflags__fno_builtin=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_cflags__fno_builtin=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cflags__fno_builtin" >&5 +echo "${ECHO_T}$ac_cv_cflags__fno_builtin" >&6; } +if test $ac_cv_cflags__fno_builtin = yes; then + BUILTINFLAG="-fno-builtin" + +fi + { echo "$as_me:$LINENO: checking whether the compiler supports -fno-strict-aliasing" >&5 echo $ECHO_N "checking whether the compiler supports -fno-strict-aliasing... $ECHO_C" >&6; } if test "${ac_cv_cflags__fno_strict_aliasing+set}" = set; then @@ -16571,65 +16874,6 @@ echo "${ECHO_T}$ac_cv_c_string_h_warnings" >&6; } then EXTRACFLAGS="$EXTRACFLAGS -Wpointer-arith" fi - - BUILTINFLAG="" - - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror" - { echo "$as_me:$LINENO: checking for builtin wchar inlines" >&5 -echo $ECHO_N "checking for builtin wchar inlines... $ECHO_C" >&6; } -if test "${ac_cv_c_builtin_wchar_ctype+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -int iswlower(unsigned short); - ; - return 0; -} -_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_cv_c_builtin_wchar_ctype=no -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_builtin_wchar_ctype=yes -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_builtin_wchar_ctype" >&5 -echo "${ECHO_T}$ac_cv_c_builtin_wchar_ctype" >&6; } - CFLAGS="$saved_CFLAGS" - if test "$ac_cv_c_builtin_wchar_ctype" = "yes" - then - BUILTINFLAG="-fno-builtin" - fi fi @@ -26939,6 +27183,7 @@ XML2INCL!$XML2INCL$ac_delim XSLTLIBS!$XSLTLIBS$ac_delim XSLTINCL!$XSLTINCL$ac_delim HALINCL!$HALINCL$ac_delim +GNUTLSINCL!$GNUTLSINCL$ac_delim sane_devel!$sane_devel$ac_delim SANEINCL!$SANEINCL$ac_delim gphoto2_devel!$gphoto2_devel$ac_delim diff --git a/configure.ac b/configure.ac index 8a883ef4363..0aec4a1481e 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AC_ARG_WITH(freetype, AS_HELP_STRING([--without-freetype],[do not use the FreeT AC_ARG_WITH(gphoto, AS_HELP_STRING([--without-gphoto],[do not use gphoto (Digital Camera support)])) AC_ARG_WITH(glu, AS_HELP_STRING([--without-glu],[do not use the GLU library]), [if test "x$withval" = "xno"; then ac_cv_header_GL_glu_h=no; fi]) +AC_ARG_WITH(gnutls, AS_HELP_STRING([--without-gnutls],[do not use GnuTLS (schannel support)])) AC_ARG_WITH(hal, AS_HELP_STRING([--without-hal],[do not use HAL (dynamic device support)])) AC_ARG_WITH(jack, AS_HELP_STRING([--without-jack],[do not use the Jack sound support]), [if test "x$withval" = "xno"; then ac_cv_header_jack_jack_h=no; fi]) @@ -798,13 +799,15 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c else opengl_msg="OpenGL development headers not found." fi + test -n "$opengl_msg" && enable_opengl32=${enable_opengl32:-no} + test "x$ac_cv_lib_soname_GLU" = "x" && enable_glu32=${enable_glu32:-no} + else + enable_opengl32=${enable_opengl32:-no} + enable_glu32=${enable_glu32:-no} fi WINE_WARNING_WITH(opengl,[test -n "$opengl_msg"],[$opengl_msg OpenGL and Direct3D won't be supported.]) - test -n "$opengl_msg" && enable_opengl32=${enable_opengl32:-no} - test "x$ac_cv_lib_soname_GLU" = "x" && enable_glu32=${enable_glu32:-no} - dnl **** Check for NAS **** AC_SUBST(NASLIBS,"") AC_CHECK_HEADERS(audio/audiolib.h, @@ -916,6 +919,21 @@ fi WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x"], [libhal development files not found, no dynamic device support.]) +dnl **** Check for libgnutls **** +if test "x$with_gnutls" != "xno" -a "$PKG_CONFIG" != "false" +then + ac_save_CPPFLAGS="$CPPFLAGS" + ac_gnutls_libs="`$PKG_CONFIG --libs gnutls 2>/dev/null`" + ac_gnutls_cflags="`$PKG_CONFIG --cflags gnutls 2>/dev/null`" + CPPFLAGS="$CPPFLAGS $ac_gnutls_cflags" + AC_CHECK_HEADER(gnutls/gnutls.h, + [WINE_CHECK_SONAME(gnutls,gnutls_global_init, + [AC_SUBST(GNUTLSINCL,"$ac_gnutls_cflags")],,[$ac_gnutls_libs])]) + CPPFLAGS="$ac_save_CPPFLAGS" +fi +WINE_NOTICE_WITH(gnutls,[test "x$ac_cv_lib_soname_gnutls" = "x"], + [libgnutls development files not found, no schannel support.]) + dnl **** Check which curses lib to use *** CURSESLIBS="" if test "$ac_cv_header_ncurses_h" = "yes" @@ -1247,6 +1265,7 @@ then WINE_TRY_CFLAGS([-fshort-wchar], [AC_DEFINE(CC_FLAG_SHORT_WCHAR, "-fshort-wchar", [Specifies the compiler flag that forces a short wchar_t])]) + WINE_TRY_CFLAGS([-fno-builtin],[AC_SUBST(BUILTINFLAG,"-fno-builtin")]) WINE_TRY_CFLAGS([-fno-strict-aliasing]) WINE_TRY_CFLAGS([-Wdeclaration-after-statement]) WINE_TRY_CFLAGS([-Wwrite-strings]) @@ -1262,17 +1281,6 @@ then then EXTRACFLAGS="$EXTRACFLAGS -Wpointer-arith" fi - - AC_SUBST(BUILTINFLAG,"") - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror" - AC_CACHE_CHECK([for builtin wchar inlines], ac_cv_c_builtin_wchar_ctype, - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[int iswlower(unsigned short);]])],[ac_cv_c_builtin_wchar_ctype=no],[ac_cv_c_builtin_wchar_ctype=yes])) - CFLAGS="$saved_CFLAGS" - if test "$ac_cv_c_builtin_wchar_ctype" = "yes" - then - BUILTINFLAG="-fno-builtin" - fi fi dnl **** Check how to define a function in assembly code **** diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 66806737874..1ac4ee0b79f 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -195,6 +195,7 @@ IMPORT_LIBS = \ crypt32/libcrypt32.$(IMPLIBEXT) \ cryptdll/libcryptdll.$(IMPLIBEXT) \ cryptnet/libcryptnet.$(IMPLIBEXT) \ + cryptui/libcryptui.$(IMPLIBEXT) \ ctl3d32/libctl3d32.$(IMPLIBEXT) \ d3d8/libd3d8.$(IMPLIBEXT) \ d3d9/libd3d9.$(IMPLIBEXT) \ @@ -332,6 +333,7 @@ CROSS_IMPLIBS = \ crypt32/libcrypt32.a \ cryptdll/libcryptdll.a \ cryptnet/libcryptnet.a \ + cryptui/libcryptui.a \ ctl3d32/libctl3d32.a \ d3d8/libd3d8.a \ d3d9/libd3d9.a \ @@ -508,6 +510,9 @@ cryptdll/libcryptdll.def cryptdll/libcryptdll.a: cryptdll/cryptdll.spec $(WINEBU cryptnet/libcryptnet.def cryptnet/libcryptnet.a: cryptnet/cryptnet.spec $(WINEBUILD) @cd cryptnet && $(MAKE) `basename $@` +cryptui/libcryptui.def cryptui/libcryptui.a: cryptui/cryptui.spec $(WINEBUILD) + @cd cryptui && $(MAKE) `basename $@` + ctl3d32/libctl3d32.def ctl3d32/libctl3d32.a: ctl3d32/ctl3d32.spec $(WINEBUILD) @cd ctl3d32 && $(MAKE) `basename $@` diff --git a/dlls/comctl32/syslink.c b/dlls/comctl32/syslink.c index a78a00c60b7..7f74b36dccc 100644 --- a/dlls/comctl32/syslink.c +++ b/dlls/comctl32/syslink.c @@ -136,7 +136,7 @@ static PDOC_ITEM SYSLINK_AppendDocItem (SYSLINK_INFO *infoPtr, LPCWSTR Text, UIN { PDOC_ITEM Item; - textlen = min(textlen, lstrlenW(Text)); + textlen = min(textlen, strlenW(Text)); Item = Alloc(FIELD_OFFSET(DOC_ITEM, Text[textlen + 1])); if(Item == NULL) { diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index 0d1770b3cbc..03aaca180b7 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -835,10 +835,18 @@ static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy); ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor); ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags); - ok(ilh->ovls[0] == -1, "wrong ovls[0] %04x\n", ilh->ovls[0]); - ok(ilh->ovls[1] == -1, "wrong ovls[1] %04x\n", ilh->ovls[1]); - ok(ilh->ovls[2] == -1, "wrong ovls[2] %04x\n", ilh->ovls[2]); - ok(ilh->ovls[3] == -1, "wrong ovls[3] %04x\n", ilh->ovls[3]); + ok(ilh->ovls[0] == -1 || + ilh->ovls[0] == 0, /* win95 */ + "wrong ovls[0] %04x\n", ilh->ovls[0]); + ok(ilh->ovls[1] == -1 || + ilh->ovls[1] == 0, /* win95 */ + "wrong ovls[1] %04x\n", ilh->ovls[1]); + ok(ilh->ovls[2] == -1 || + ilh->ovls[2] == 0, /* win95 */ + "wrong ovls[2] %04x\n", ilh->ovls[2]); + ok(ilh->ovls[3] == -1 || + ilh->ovls[3] == 0, /* win95 */ + "wrong ovls[3] %04x\n", ilh->ovls[3]); } static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment) diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c index 26c1bc17e58..271dfd1b6f9 100644 --- a/dlls/comctl32/tests/monthcal.c +++ b/dlls/comctl32/tests/monthcal.c @@ -302,8 +302,10 @@ static const struct message destroy_parent_seq[] = { { 0x0090, sent|optional }, /* Vista */ { WM_WINDOWPOSCHANGING, sent|wparam, 0}, { WM_WINDOWPOSCHANGED, sent|wparam, 0}, - { WM_NCACTIVATE, sent|wparam|lparam, 0, 0}, - { WM_ACTIVATE, sent|wparam|lparam, 0, 0}, + { WM_NCACTIVATE, sent|wparam, 0}, + { WM_ACTIVATE, sent|wparam, 0}, + { WM_NCACTIVATE, sent|wparam|lparam|optional, 0, 0}, + { WM_ACTIVATE, sent|wparam|lparam|optional, 0, 0}, { WM_ACTIVATEAPP, sent|wparam, 0}, { WM_KILLFOCUS, sent|wparam|lparam, 0, 0}, { WM_IME_SETCONTEXT, sent|wparam|optional, 0}, diff --git a/dlls/comctl32/tests/status.c b/dlls/comctl32/tests/status.c index 0418c8d1700..e2ec11d2aac 100644 --- a/dlls/comctl32/tests/status.c +++ b/dlls/comctl32/tests/status.c @@ -168,7 +168,7 @@ static void test_height(void) SendMessage(hwndStatus, WM_SETFONT, (WPARAM)hFont, TRUE); if (!g_wmsize_count) { - skip("Status control not resized in win95, skipping broken tests."); + skip("Status control not resized in win95, skipping broken tests.\n"); return; } ok(g_wmsize_count > 0, "WM_SETFONT should issue WM_SIZE\n"); @@ -376,7 +376,9 @@ static void test_status_control(void) /* Make simple */ SendMessage(hWndStatus, SB_SIMPLE, TRUE, 0); r = SendMessage(hWndStatus, SB_ISSIMPLE, 0, 0); - expect(TRUE,r); + ok(r == TRUE || + broken(r == FALSE), /* win95 */ + "Expected TRUE, got %d\n", r); DestroyWindow(hWndStatus); } diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c index 090fe27ab51..bab87ccabf7 100644 --- a/dlls/comctl32/theming.c +++ b/dlls/comctl32/theming.c @@ -113,7 +113,7 @@ static const WNDPROC subclassProcs[NUM_SUBCLASSES] = { */ void THEMING_Initialize (void) { - int i; + unsigned int i; static const WCHAR subclassPropName[] = { 'C','C','3','2','T','h','e','m','i','n','g','S','u','b','C','l',0 }; static const WCHAR refDataPropName[] = @@ -161,7 +161,7 @@ void THEMING_Initialize (void) */ void THEMING_Uninitialize (void) { - int i; + unsigned int i; if (!atSubclassProp) return; /* not initialized */ diff --git a/dlls/comdlg32/fontdlg.c b/dlls/comdlg32/fontdlg.c index 9174ce00d61..b893282d0b1 100644 --- a/dlls/comdlg32/fontdlg.c +++ b/dlls/comdlg32/fontdlg.c @@ -150,7 +150,7 @@ static const struct { void _dump_cf_flags(DWORD cflags) { - int i; + unsigned int i; for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++) if (cfflags[i].mask & cflags) @@ -428,7 +428,7 @@ static int AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf) static int SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf) { static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72}; - int i; + unsigned int i; for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++) if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return 1; diff --git a/dlls/comdlg32/printdlg.c b/dlls/comdlg32/printdlg.c index ccf5145b74e..d8d208283e3 100644 --- a/dlls/comdlg32/printdlg.c +++ b/dlls/comdlg32/printdlg.c @@ -1040,7 +1040,7 @@ BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, HWND hQuality = GetDlgItem(hDlg, cmb1); LONG* Resolutions; char buf[255]; - int i; + DWORD i; int dpiX, dpiY; HDC hPrinterDC = CreateDCA(PrintStructures->lpPrinterInfo->pDriverName, PrintStructures->lpPrinterInfo->pPrinterName, diff --git a/dlls/credui/credui_main.c b/dlls/credui/credui_main.c index 42316d6100a..7e3c8a02ab9 100644 --- a/dlls/credui/credui_main.c +++ b/dlls/credui/credui_main.c @@ -441,7 +441,7 @@ static void CredDialogCommandOk(HWND hwndDlg, struct cred_dialog_params *params) if (!strchrW(user, '\\') && !strchrW(user, '@')) { - INT len_target = strlenW(params->pszTargetName); + ULONG len_target = strlenW(params->pszTargetName); memcpy(params->pszUsername, params->pszTargetName, min(len_target, params->ulUsernameMaxChars) * sizeof(WCHAR)); if (len_target + 1 < params->ulUsernameMaxChars) diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 9e7ed447ffc..e474ff700ad 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -900,7 +900,7 @@ static BOOL CRYPT_AsnEncodeStringCoerce(const CERT_NAME_VALUE *value, LPCSTR str = (LPCSTR)value->Value.pbData; DWORD bytesNeeded, lenBytes, encodedLen; - encodedLen = value->Value.cbData ? value->Value.cbData : lstrlenA(str); + encodedLen = value->Value.cbData ? value->Value.cbData : strlen(str); CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); bytesNeeded = 1 + lenBytes + encodedLen; if (!pbEncoded) @@ -970,7 +970,7 @@ static BOOL CRYPT_AsnEncodeUTF8String(const CERT_NAME_VALUE *value, DWORD bytesNeeded, lenBytes, encodedLen, strLen; strLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) : - lstrlenW(str); + strlenW(str); encodedLen = WideCharToMultiByte(CP_UTF8, 0, str, strLen, NULL, 0, NULL, NULL); CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); @@ -1830,7 +1830,7 @@ static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value, DWORD bytesNeeded, lenBytes, encodedLen; encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) : - lstrlenW(str); + strlenW(str); CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); bytesNeeded = 1 + lenBytes + encodedLen; if (!pbEncoded) @@ -1871,7 +1871,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value, DWORD bytesNeeded, lenBytes, encodedLen; encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) : - lstrlenW(str); + strlenW(str); CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); bytesNeeded = 1 + lenBytes + encodedLen; if (!pbEncoded) @@ -1925,7 +1925,7 @@ static BOOL CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE *value, DWORD bytesNeeded, lenBytes, encodedLen; encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) : - lstrlenW(str); + strlenW(str); CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); bytesNeeded = 1 + lenBytes + encodedLen; if (!pbEncoded) @@ -1972,7 +1972,7 @@ static BOOL CRYPT_AsnEncodeIA5String(const CERT_NAME_VALUE *value, DWORD bytesNeeded, lenBytes, encodedLen; encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) : - lstrlenW(str); + strlenW(str); CRYPT_EncodeLen(encodedLen, NULL, &lenBytes); bytesNeeded = 1 + lenBytes + encodedLen; if (!pbEncoded) @@ -2020,7 +2020,7 @@ static BOOL CRYPT_AsnEncodeUniversalString(const CERT_NAME_VALUE *value, /* FIXME: doesn't handle composite characters */ strLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) : - lstrlenW(str); + strlenW(str); CRYPT_EncodeLen(strLen * 4, NULL, &lenBytes); bytesNeeded = 1 + lenBytes + strLen * 4; if (!pbEncoded) diff --git a/dlls/crypt32/oid.c b/dlls/crypt32/oid.c index 5a71c74b0bd..69ea7a5b66d 100644 --- a/dlls/crypt32/oid.c +++ b/dlls/crypt32/oid.c @@ -995,7 +995,7 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, static void oid_init_localizednames(HINSTANCE hInstance) { - int i; + unsigned int i; for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++) { @@ -1008,7 +1008,7 @@ static void oid_init_localizednames(HINSTANCE hInstance) */ LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName) { - int i; + unsigned int i; for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++) { diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c index 7a739a87e96..b1ccc91fc7e 100644 --- a/dlls/crypt32/str.c +++ b/dlls/crypt32/str.c @@ -167,7 +167,7 @@ static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz) if (psz) { - chars = min(lstrlenA(prefix), csz); + chars = min(strlen(prefix), csz); memcpy(psz, prefix, chars); *(psz + chars) = '='; chars++; @@ -304,7 +304,7 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz) { DWORD i; - chars = min(lstrlenA(prefix), csz); + chars = min(strlen(prefix), csz); for (i = 0; i < chars; i++) *(psz + i) = prefix[i]; *(psz + chars) = '='; @@ -328,7 +328,7 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz) if (psz) { - chars = min(lstrlenW(prefix), csz); + chars = min(strlenW(prefix), csz); memcpy(psz, prefix, chars * sizeof(WCHAR)); *(psz + chars) = '='; chars++; @@ -478,7 +478,7 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, { if (!ret) { - DWORD i; + LONG i; *ppszError = pszX500; for (i = 0; i < errorStr - x500; i++) @@ -665,7 +665,7 @@ static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType, { if (value->end > value->start) { - DWORD i; + LONG i; LPWSTR ptr = (LPWSTR)nameValue.Value.pbData; for (i = 0; i < value->end - value->start; i++) diff --git a/dlls/crypt32/tests/message.c b/dlls/crypt32/tests/message.c index 28f9a4eb8ec..fa8df0e5951 100644 --- a/dlls/crypt32/tests/message.c +++ b/dlls/crypt32/tests/message.c @@ -220,8 +220,10 @@ static void test_verify_message_hash(void) para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; SetLastError(0xdeadbeef); ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, - "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == CRYPT_E_ASN1_EOD || + GetLastError() == OSS_BAD_ARG, /* win98 */ + "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); /* Verifying the hash of a detached message succeeds? */ ret = CryptVerifyMessageHash(¶, detachedHashContent, sizeof(detachedHashContent), NULL, NULL, NULL, NULL); @@ -358,39 +360,51 @@ static void test_verify_detached_message_signature(void) SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, - "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == CRYPT_E_ASN1_EOD || + GetLastError() == OSS_BAD_ARG, /* win98 */ + "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); /* None of these messages contains a cert in the message itself, so the * default callback isn't able to verify their signature. */ SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, signedWithCertContent, sizeof(signedWithCertContent), 0, NULL, NULL, NULL); + ok(!ret, "Expected 0, got %d\n", ret); todo_wine - ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, - "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + ok(GetLastError() == CRYPT_E_NOT_FOUND || + GetLastError() == OSS_DATA_ERROR, /* win98 */ + "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent, sizeof(signedContent), 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, - "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == CRYPT_E_NOT_FOUND || + GetLastError() == OSS_DATA_ERROR, /* win98 */ + "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, - "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == CRYPT_E_NOT_FOUND || + GetLastError() == OSS_DATA_ERROR, /* win98 */ + "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); pContent = msgData; cbContent = sizeof(msgData); ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); - ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, - "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == CRYPT_E_NOT_FOUND || + GetLastError() == OSS_DATA_ERROR, /* win98 */ + "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); /* Passing the correct callback results in success */ para.pfnGetSignerCertificate = msg_get_signer_callback; ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); - ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n", + ok(ret || + broken(!ret), /* win98 */ + "CryptVerifyDetachedMessageSignature failed: %08x\n", GetLastError()); /* Not passing the correct data to be signed results in the signature not * matching. @@ -398,8 +412,10 @@ static void test_verify_detached_message_signature(void) SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == NTE_BAD_SIGNATURE, - "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError()); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == NTE_BAD_SIGNATURE || + GetLastError() == OSS_DATA_ERROR, /* win98 */ + "Expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n", GetLastError()); } static const BYTE signedWithCertEmptyContent[] = { diff --git a/dlls/cryptdlg/Makefile.in b/dlls/cryptdlg/Makefile.in index bb06a0bbe3d..0271fa3cc00 100644 --- a/dlls/cryptdlg/Makefile.in +++ b/dlls/cryptdlg/Makefile.in @@ -3,7 +3,7 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cryptdlg.dll -IMPORTS = crypt32 wintrust kernel32 +IMPORTS = cryptui crypt32 wintrust advapi32 kernel32 C_SRCS = \ main.c diff --git a/dlls/cryptdlg/main.c b/dlls/cryptdlg/main.c index 2447c3887b3..d87d480f038 100644 --- a/dlls/cryptdlg/main.c +++ b/dlls/cryptdlg/main.c @@ -22,10 +22,13 @@ #include "windef.h" #include "winbase.h" +#include "winnls.h" +#include "winreg.h" #include "wincrypt.h" #include "wintrust.h" #include "winuser.h" #include "cryptdlg.h" +#include "cryptuiapi.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(cryptdlg); @@ -74,8 +77,15 @@ DWORD WINAPI GetFriendlyNameOfCertW(PCCERT_CONTEXT pccert, LPWSTR pchBuffer, */ HRESULT WINAPI CertTrustInit(CRYPT_PROVIDER_DATA *pProvData) { - FIXME("(%p)\n", pProvData); - return E_NOTIMPL; + HRESULT ret = S_FALSE; + + TRACE("(%p)\n", pProvData); + + if (pProvData->padwTrustStepErrors && + !pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT]) + ret = S_OK; + TRACE("returning %08x\n", ret); + return ret; } /*********************************************************************** @@ -96,13 +106,265 @@ HRESULT WINAPI CertTrustCleanup(CRYPT_PROVIDER_DATA *pProvData) return E_NOTIMPL; } +static BOOL CRYPTDLG_CheckOnlineCRL(void) +{ + static const WCHAR policyFlagsKey[] = { 'S','o','f','t','w','a','r','e', + '\\','M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g', + 'r','a','p','h','y','\\','{','7','8','0','1','e','b','d','0','-','c','f', + '4','b','-','1','1','d','0','-','8','5','1','f','-','0','0','6','0','9', + '7','9','3','8','7','e','a','}',0 }; + static const WCHAR policyFlags[] = { 'P','o','l','i','c','y','F','l','a', + 'g','s',0 }; + HKEY key; + BOOL ret = FALSE; + + if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, policyFlagsKey, 0, KEY_READ, &key)) + { + DWORD type, flags, size = sizeof(flags); + + if (!RegQueryValueExW(key, policyFlags, NULL, &type, (BYTE *)&flags, + &size) && type == REG_DWORD) + { + /* The flag values aren't defined in any header I'm aware of, but + * this value is well documented on the net. + */ + if (flags & 0x00010000) + ret = TRUE; + } + RegCloseKey(key); + } + return ret; +} + +/* Returns TRUE if pCert is not in the Disallowed system store, or FALSE if it + * is. + */ +static BOOL CRYPTDLG_IsCertAllowed(PCCERT_CONTEXT pCert) +{ + BOOL ret; + BYTE hash[20]; + DWORD size = sizeof(hash); + + if ((ret = CertGetCertificateContextProperty(pCert, + CERT_SIGNATURE_HASH_PROP_ID, hash, &size))) + { + static const WCHAR disallowedW[] = + { 'D','i','s','a','l','l','o','w','e','d',0 }; + HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, + X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, disallowedW); + + if (disallowed) + { + PCCERT_CONTEXT found = CertFindCertificateInStore(disallowed, + X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, hash, NULL); + + if (found) + { + ret = FALSE; + CertFreeCertificateContext(found); + } + CertCloseStore(disallowed, 0); + } + } + return ret; +} + +static DWORD CRYPTDLG_TrustStatusToConfidence(DWORD errorStatus) +{ + DWORD confidence = 0; + + confidence = 0; + if (!(errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID)) + confidence |= CERT_CONFIDENCE_SIG; + if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_VALID)) + confidence |= CERT_CONFIDENCE_TIME; + if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED)) + confidence |= CERT_CONFIDENCE_TIMENEST; + return confidence; +} + +static BOOL CRYPTDLG_CopyChain(CRYPT_PROVIDER_DATA *data, + PCCERT_CHAIN_CONTEXT chain) +{ + BOOL ret; + CRYPT_PROVIDER_SGNR signer; + PCERT_SIMPLE_CHAIN simpleChain = chain->rgpChain[0]; + DWORD i; + + memset(&signer, 0, sizeof(signer)); + signer.cbStruct = sizeof(signer); + ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer); + if (ret) + { + CRYPT_PROVIDER_SGNR *sgnr = WTHelperGetProvSignerFromChain(data, 0, + FALSE, 0); + + if (sgnr) + { + sgnr->dwError = simpleChain->TrustStatus.dwErrorStatus; + sgnr->pChainContext = CertDuplicateCertificateChain(chain); + } + else + ret = FALSE; + for (i = 0; ret && i < simpleChain->cElement; i++) + { + ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0, + simpleChain->rgpElement[i]->pCertContext); + if (ret) + { + CRYPT_PROVIDER_CERT *cert; + + if ((cert = WTHelperGetProvCertFromChain(sgnr, i))) + { + CERT_CHAIN_ELEMENT *element = simpleChain->rgpElement[i]; + + cert->dwConfidence = CRYPTDLG_TrustStatusToConfidence( + element->TrustStatus.dwErrorStatus); + cert->dwError = element->TrustStatus.dwErrorStatus; + cert->pChainElement = element; + } + else + ret = FALSE; + } + } + } + return ret; +} + +static CERT_VERIFY_CERTIFICATE_TRUST *CRYPTDLG_GetVerifyData( + CRYPT_PROVIDER_DATA *data) +{ + CERT_VERIFY_CERTIFICATE_TRUST *pCert = NULL; + + /* This should always be true, but just in case the calling function is + * called directly: + */ + if (data->pWintrustData->dwUnionChoice == WTD_CHOICE_BLOB && + data->pWintrustData->pBlob && data->pWintrustData->pBlob->cbMemObject == + sizeof(CERT_VERIFY_CERTIFICATE_TRUST) && + data->pWintrustData->pBlob->pbMemObject) + pCert = (CERT_VERIFY_CERTIFICATE_TRUST *) + data->pWintrustData->pBlob->pbMemObject; + return pCert; +} + +static HCERTCHAINENGINE CRYPTDLG_MakeEngine(CERT_VERIFY_CERTIFICATE_TRUST *cert) +{ + HCERTCHAINENGINE engine = NULL; + HCERTSTORE root = NULL, trust = NULL; + DWORD i; + + if (cert->cRootStores) + { + root = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + if (root) + { + for (i = 0; i < cert->cRootStores; i++) + CertAddStoreToCollection(root, cert->rghstoreRoots[i], 0, 0); + } + } + if (cert->cTrustStores) + { + trust = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + if (root) + { + for (i = 0; i < cert->cTrustStores; i++) + CertAddStoreToCollection(trust, cert->rghstoreTrust[i], 0, 0); + } + } + if (cert->cRootStores || cert->cStores || cert->cTrustStores) + { + CERT_CHAIN_ENGINE_CONFIG config; + + memset(&config, 0, sizeof(config)); + config.cbSize = sizeof(config); + config.hRestrictedRoot = root; + config.hRestrictedTrust = trust; + config.cAdditionalStore = cert->cStores; + config.rghAdditionalStore = cert->rghstoreCAs; + config.hRestrictedRoot = root; + CertCreateCertificateChainEngine(&config, &engine); + CertCloseStore(root, 0); + CertCloseStore(trust, 0); + } + return engine; +} + /*********************************************************************** * CertTrustFinalPolicy (CRYPTDLG.@) */ -HRESULT WINAPI CertTrustFinalPolicy(CRYPT_PROVIDER_DATA *pProvData) +HRESULT WINAPI CertTrustFinalPolicy(CRYPT_PROVIDER_DATA *data) { - FIXME("(%p)\n", pProvData); - return E_NOTIMPL; + BOOL ret; + DWORD err = S_OK; + CERT_VERIFY_CERTIFICATE_TRUST *pCert = CRYPTDLG_GetVerifyData(data); + + TRACE("(%p)\n", data); + + if (data->pWintrustData->dwUIChoice != WTD_UI_NONE) + FIXME("unimplemented for UI choice %d\n", + data->pWintrustData->dwUIChoice); + if (pCert) + { + DWORD flags = 0; + CERT_CHAIN_PARA chainPara; + HCERTCHAINENGINE engine; + + memset(&chainPara, 0, sizeof(chainPara)); + chainPara.cbSize = sizeof(chainPara); + if (CRYPTDLG_CheckOnlineCRL()) + flags |= CERT_CHAIN_REVOCATION_CHECK_END_CERT; + engine = CRYPTDLG_MakeEngine(pCert); + GetSystemTimeAsFileTime(&data->sftSystemTime); + ret = CRYPTDLG_IsCertAllowed(pCert->pccert); + if (ret) + { + PCCERT_CHAIN_CONTEXT chain; + + ret = CertGetCertificateChain(engine, pCert->pccert, + &data->sftSystemTime, NULL, &chainPara, flags, NULL, &chain); + if (ret) + { + if (chain->cChain != 1) + { + FIXME("unimplemented for more than 1 simple chain\n"); + err = TRUST_E_SUBJECT_FORM_UNKNOWN; + ret = FALSE; + } + else if ((ret = CRYPTDLG_CopyChain(data, chain))) + { + if (CertVerifyTimeValidity(&data->sftSystemTime, + pCert->pccert->pCertInfo)) + { + ret = FALSE; + err = CERT_E_EXPIRED; + } + } + else + err = TRUST_E_SYSTEM_ERROR; + CertFreeCertificateChain(chain); + } + else + err = TRUST_E_SUBJECT_NOT_TRUSTED; + } + CertFreeCertificateChainEngine(engine); + } + else + { + ret = FALSE; + err = TRUST_E_NOSIGNATURE; + } + /* Oddly, native doesn't set the error in the trust step error location, + * probably because this action is more advisory than anything else. + * Instead it stores it as the final error, but the function "succeeds" in + * any case. + */ + if (!ret) + data->dwFinalError = err; + TRACE("returning %d (%08x)\n", S_OK, data->dwFinalError); + return S_OK; } /*********************************************************************** @@ -110,8 +372,33 @@ HRESULT WINAPI CertTrustFinalPolicy(CRYPT_PROVIDER_DATA *pProvData) */ BOOL WINAPI CertViewPropertiesA(CERT_VIEWPROPERTIES_STRUCT_A *info) { - FIXME("(%p): stub\n", info); - return FALSE; + CERT_VIEWPROPERTIES_STRUCT_W infoW; + LPWSTR title = NULL; + BOOL ret; + + TRACE("(%p)\n", info); + + memcpy(&infoW, info, sizeof(infoW)); + if (info->szTitle) + { + int len = MultiByteToWideChar(CP_ACP, 0, info->szTitle, -1, NULL, 0); + + title = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (title) + { + MultiByteToWideChar(CP_ACP, 0, info->szTitle, -1, title, len); + infoW.szTitle = title; + } + else + { + ret = FALSE; + goto error; + } + } + ret = CertViewPropertiesW(&infoW); + HeapFree(GetProcessHeap(), 0, title); +error: + return ret; } /*********************************************************************** @@ -119,8 +406,61 @@ BOOL WINAPI CertViewPropertiesA(CERT_VIEWPROPERTIES_STRUCT_A *info) */ BOOL WINAPI CertViewPropertiesW(CERT_VIEWPROPERTIES_STRUCT_W *info) { - FIXME("(%p): stub\n", info); - return FALSE; + static GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY; + CERT_VERIFY_CERTIFICATE_TRUST trust; + WINTRUST_BLOB_INFO blob; + WINTRUST_DATA wtd; + LONG err; + BOOL ret; + + TRACE("(%p)\n", info); + + memset(&trust, 0, sizeof(trust)); + trust.cbSize = sizeof(trust); + trust.pccert = info->pCertContext; + trust.cRootStores = info->cRootStores; + trust.rghstoreRoots = info->rghstoreRoots; + trust.cStores = info->cStores; + trust.rghstoreCAs = info->rghstoreCAs; + trust.cTrustStores = info->cTrustStores; + trust.rghstoreTrust = info->rghstoreTrust; + memset(&blob, 0, sizeof(blob)); + blob.cbStruct = sizeof(blob); + blob.cbMemObject = sizeof(trust); + blob.pbMemObject = (BYTE *)&trust; + memset(&wtd, 0, sizeof(wtd)); + wtd.cbStruct = sizeof(wtd); + wtd.dwUIChoice = WTD_UI_NONE; + wtd.dwUnionChoice = WTD_CHOICE_BLOB; + wtd.pBlob = &blob; + wtd.dwStateAction = WTD_STATEACTION_VERIFY; + err = WinVerifyTrust(NULL, &cert_action_verify, &wtd); + if (err == ERROR_SUCCESS) + { + CRYPTUI_VIEWCERTIFICATE_STRUCTW uiInfo; + BOOL propsChanged = FALSE; + + memset(&uiInfo, 0, sizeof(uiInfo)); + uiInfo.dwSize = sizeof(uiInfo); + uiInfo.hwndParent = info->hwndParent; + uiInfo.dwFlags = + CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_ENABLE_EDITPROPERTIES; + uiInfo.szTitle = info->szTitle; + uiInfo.pCertContext = info->pCertContext; + uiInfo.cPurposes = info->cArrayPurposes; + uiInfo.rgszPurposes = (LPCSTR *)info->arrayPurposes; + uiInfo.hWVTStateData = wtd.hWVTStateData; + uiInfo.fpCryptProviderDataTrustedUsage = TRUE; + uiInfo.cPropSheetPages = info->cArrayPropSheetPages; + uiInfo.rgPropSheetPages = info->arrayPropSheetPages; + uiInfo.nStartPage = info->nStartPage; + ret = CryptUIDlgViewCertificateW(&uiInfo, &propsChanged); + wtd.dwStateAction = WTD_STATEACTION_CLOSE; + WinVerifyTrust(NULL, &cert_action_verify, &wtd); + } + else + ret = FALSE; + return ret; } /*********************************************************************** diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c index 049d577f33c..0395e0aaaea 100644 --- a/dlls/cryptnet/cryptnet_main.c +++ b/dlls/cryptnet/cryptnet_main.c @@ -26,6 +26,7 @@ #define CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS #include +#include #include "windef.h" #include "winbase.h" diff --git a/dlls/cryptui/Makefile.in b/dlls/cryptui/Makefile.in index 2ab5e165dbb..996711a3ade 100644 --- a/dlls/cryptui/Makefile.in +++ b/dlls/cryptui/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cryptui.dll IMPORTS = kernel32 +IMPORTLIB = cryptui C_SRCS = \ main.c diff --git a/dlls/cryptui/cryptui.spec b/dlls/cryptui/cryptui.spec index ad5cb4ba8d2..088d08793c9 100644 --- a/dlls/cryptui/cryptui.spec +++ b/dlls/cryptui/cryptui.spec @@ -11,7 +11,7 @@ 11 stub CryptUIDlgViewCRLW 12 stub CryptUIDlgViewCTLA 13 stub CryptUIDlgViewCTLW -14 stub CryptUIDlgViewCertificateA +14 stdcall CryptUIDlgViewCertificateA(ptr ptr) 15 stub CryptUIDlgViewCertificatePropertiesA 16 stub CryptUIDlgViewCertificatePropertiesW 17 stdcall CryptUIDlgViewCertificateW(ptr ptr) diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index 4bf456a1575..00e86831464 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -22,6 +22,7 @@ #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winuser.h" #include "cryptuiapi.h" #include "wine/debug.h" @@ -56,6 +57,40 @@ BOOL WINAPI CryptUIDlgCertMgr(PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr) return FALSE; } +BOOL WINAPI CryptUIDlgViewCertificateA( + PCCRYPTUI_VIEWCERTIFICATE_STRUCTA pCertViewInfo, BOOL *pfPropertiesChanged) +{ + CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo; + LPWSTR title = NULL; + BOOL ret; + + TRACE("(%p, %p)\n", pCertViewInfo, pfPropertiesChanged); + + memcpy(&viewInfo, pCertViewInfo, sizeof(viewInfo)); + if (pCertViewInfo->szTitle) + { + int len = MultiByteToWideChar(CP_ACP, 0, pCertViewInfo->szTitle, -1, + NULL, 0); + + title = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (title) + { + MultiByteToWideChar(CP_ACP, 0, pCertViewInfo->szTitle, -1, title, + len); + viewInfo.szTitle = title; + } + else + { + ret = FALSE; + goto error; + } + } + ret = CryptUIDlgViewCertificateW(&viewInfo, pfPropertiesChanged); + HeapFree(GetProcessHeap(), 0, title); +error: + return ret; +} + BOOL WINAPI CryptUIDlgViewCertificateW(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo, BOOL *pfPropertiesChanged) { diff --git a/dlls/d3dxof/d3dxof.c b/dlls/d3dxof/d3dxof.c index 23e4847a140..706662d3ec3 100644 --- a/dlls/d3dxof/d3dxof.c +++ b/dlls/d3dxof/d3dxof.c @@ -161,7 +161,7 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV DWORD size; HANDLE hFile = INVALID_HANDLE_VALUE; - FIXME("(%p/%p)->(%p,%x,%p) partial stub!\n", This, iface, pvSource, dwLoadOptions, ppEnumObj); + TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj); if (!ppEnumObj) return DXFILEERR_BADVALUE; @@ -253,6 +253,7 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV object->pDirectXFile = This; object->buf.pdxf = This; object->buf.txt = TRUE; + object->buf.token_present = FALSE; object->buf.cur_subobject = 0; object->buf.buffer = HeapAlloc(GetProcessHeap(), 0, MAX_INPUT_SIZE+1); @@ -596,7 +597,7 @@ static BOOL is_integer(parse_buffer* buf) return TRUE; } -static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token) +static WORD parse_TOKEN(parse_buffer * buf) { WORD token; @@ -754,8 +755,7 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token) } } - if (show_token) - dump_TOKEN(token); + dump_TOKEN(token); return token; } @@ -794,34 +794,28 @@ static const char* get_primitive_string(WORD token) return NULL; } -static inline WORD parse_TOKEN(parse_buffer * buf) +static WORD get_TOKEN(parse_buffer * buf) { - return parse_TOKEN_dbg_opt(buf, TRUE); + if (buf->token_present) + { + buf->token_present = FALSE; + return buf->current_token; + } + + buf->current_token = parse_TOKEN(buf); + + return buf->current_token; } static WORD check_TOKEN(parse_buffer * buf) { - WORD token; + if (buf->token_present) + return buf->current_token; - if (buf->txt) - { - parse_buffer save = *buf; - /*TRACE("check: ");*/ - token = parse_TOKEN_dbg_opt(buf, FALSE); - *buf = save; - return token; - } + buf->current_token = parse_TOKEN(buf); + buf->token_present = TRUE; - if (!read_bytes(buf, &token, 2)) - return 0; - buf->buffer -= 2; - buf->rem_bytes += 2; - if (0) - { - TRACE("check: "); - dump_TOKEN(token); - } - return token; + return buf->current_token; } static inline BOOL is_primitive_type(WORD token) @@ -855,10 +849,10 @@ static BOOL parse_template_option_info(parse_buffer * buf) if (check_TOKEN(buf) == TOKEN_DOT) { - parse_TOKEN(buf); - if (parse_TOKEN(buf) != TOKEN_DOT) + get_TOKEN(buf); + if (get_TOKEN(buf) != TOKEN_DOT) return FALSE; - if (parse_TOKEN(buf) != TOKEN_DOT) + if (get_TOKEN(buf) != TOKEN_DOT) return FALSE; cur_template->open = TRUE; } @@ -866,15 +860,15 @@ static BOOL parse_template_option_info(parse_buffer * buf) { while (1) { - if (parse_TOKEN(buf) != TOKEN_NAME) + if (get_TOKEN(buf) != TOKEN_NAME) return FALSE; strcpy(cur_template->childs[cur_template->nb_childs], (char*)buf->value); if (check_TOKEN(buf) == TOKEN_GUID) - parse_TOKEN(buf); + get_TOKEN(buf); cur_template->nb_childs++; if (check_TOKEN(buf) != TOKEN_COMMA) break; - parse_TOKEN(buf); + get_TOKEN(buf); } cur_template->open = FALSE; } @@ -895,13 +889,13 @@ static BOOL parse_template_members_list(parse_buffer * buf) if (check_TOKEN(buf) == TOKEN_ARRAY) { - parse_TOKEN(buf); + get_TOKEN(buf); array = 1; } if (check_TOKEN(buf) == TOKEN_NAME) { - cur_member->type = parse_TOKEN(buf); + cur_member->type = get_TOKEN(buf); cur_member->idx_template = 0; while (cur_member->idx_template < buf->pdxf->nb_xtemplates) { @@ -916,11 +910,11 @@ static BOOL parse_template_members_list(parse_buffer * buf) } } else if (is_primitive_type(check_TOKEN(buf))) - cur_member->type = parse_TOKEN(buf); + cur_member->type = get_TOKEN(buf); else break; - if (parse_TOKEN(buf) != TOKEN_NAME) + if (get_TOKEN(buf) != TOKEN_NAME) return FALSE; strcpy(cur_member->name, (char*)buf->value); @@ -933,22 +927,22 @@ static BOOL parse_template_members_list(parse_buffer * buf) FIXME("No support for multi-dimensional array yet\n"); return FALSE; } - parse_TOKEN(buf); + get_TOKEN(buf); if (check_TOKEN(buf) == TOKEN_INTEGER) { - parse_TOKEN(buf); + get_TOKEN(buf); cur_member->dim_fixed[nb_dims] = TRUE; cur_member->dim_value[nb_dims] = *(DWORD*)buf->value; } else { - if (parse_TOKEN(buf) != TOKEN_NAME) + if (get_TOKEN(buf) != TOKEN_NAME) return FALSE; cur_member->dim_fixed[nb_dims] = FALSE; /* Hack: Assume array size is specified in previous member */ cur_member->dim_value[nb_dims] = idx_member - 1; } - if (parse_TOKEN(buf) != TOKEN_CBRACKET) + if (get_TOKEN(buf) != TOKEN_CBRACKET) return FALSE; nb_dims++; } @@ -956,7 +950,7 @@ static BOOL parse_template_members_list(parse_buffer * buf) return FALSE; cur_member->nb_dims = nb_dims; } - if (parse_TOKEN(buf) != TOKEN_SEMICOLON) + if (get_TOKEN(buf) != TOKEN_SEMICOLON) return FALSE; idx_member++; @@ -973,10 +967,10 @@ static BOOL parse_template_parts(parse_buffer * buf) return FALSE; if (check_TOKEN(buf) == TOKEN_OBRACKET) { - parse_TOKEN(buf); + get_TOKEN(buf); if (!parse_template_option_info(buf)) return FALSE; - if (parse_TOKEN(buf) != TOKEN_CBRACKET) + if (get_TOKEN(buf) != TOKEN_CBRACKET) return FALSE; } @@ -985,19 +979,19 @@ static BOOL parse_template_parts(parse_buffer * buf) static BOOL parse_template(parse_buffer * buf) { - if (parse_TOKEN(buf) != TOKEN_TEMPLATE) + if (get_TOKEN(buf) != TOKEN_TEMPLATE) return FALSE; - if (parse_TOKEN(buf) != TOKEN_NAME) + if (get_TOKEN(buf) != TOKEN_NAME) return FALSE; strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value); - if (parse_TOKEN(buf) != TOKEN_OBRACE) + if (get_TOKEN(buf) != TOKEN_OBRACE) return FALSE; - if (parse_TOKEN(buf) != TOKEN_GUID) + if (get_TOKEN(buf) != TOKEN_GUID) return FALSE; buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value; if (!parse_template_parts(buf)) return FALSE; - if (parse_TOKEN(buf) != TOKEN_CBRACE) + if (get_TOKEN(buf) != TOKEN_CBRACE) return FALSE; if (buf->txt) { @@ -1024,6 +1018,7 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP buf.buffer = (LPBYTE)pvData; buf.rem_bytes = cbSize; buf.txt = FALSE; + buf.token_present = FALSE; buf.pdxf = This; TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize); @@ -1182,7 +1177,11 @@ static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* return S_OK; } - ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + /* Do not print an error for interfaces that can be queried to retrieve the type of the object */ + if (!IsEqualGUID(riid, &IID_IDirectXFileData) + && !IsEqualGUID(riid, &IID_IDirectXFileDataReference)) + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + return E_NOINTERFACE; } @@ -1301,7 +1300,11 @@ static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* ifac return S_OK; } - ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + /* Do not print an error for interfaces that can be queried to retreive the type of the object */ + if (!IsEqualGUID(riid, &IID_IDirectXFileBinary) + && !IsEqualGUID(riid, &IID_IDirectXFileDataReference)) + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + return E_NOINTERFACE; } @@ -1398,14 +1401,25 @@ static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, cons static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj) { + HRESULT hr; IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface; + IDirectXFileDataImpl *object; - FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppChildObj); + TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj); if (This->cur_enum_object >= This->pobj->nb_childs) return DXFILEERR_NOMOREOBJECTS; - return DXFILEERR_BADVALUE; + hr = IDirectXFileDataImpl_Create(&object); + if (hr != S_OK) + return DXFILEERR_BADVALUE; + + object->pobj = This->pobj->childs[This->cur_enum_object++]; + object->cur_enum_object = 0; + + *ppChildObj = (LPDIRECTXFILEOBJECT)object; + + return DXFILE_OK; } static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj) @@ -1482,7 +1496,11 @@ static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileD return S_OK; } - ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + /* Do not print an error for interfaces that can be queried to retreive the type of the object */ + if (!IsEqualGUID(riid, &IID_IDirectXFileData) + && !IsEqualGUID(riid, &IID_IDirectXFileBinary)) + ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); + return E_NOINTERFACE; } @@ -1645,7 +1663,7 @@ static BOOL parse_object_members_list(parse_buffer * buf) { if (k) { - if (parse_TOKEN(buf) != TOKEN_COMMA) + if (get_TOKEN(buf) != TOKEN_COMMA) return FALSE; } @@ -1677,7 +1695,7 @@ static BOOL parse_object_members_list(parse_buffer * buf) return FALSE; } buf->level--; - /*if (parse_TOKEN(buf) != TOKEN_SEMICOLON) + /*if (get_TOKEN(buf) != TOKEN_SEMICOLON) return FALSE;*/ } else @@ -1685,7 +1703,7 @@ static BOOL parse_object_members_list(parse_buffer * buf) token = check_TOKEN(buf); if (token == TOKEN_INTEGER) { - parse_TOKEN(buf); + get_TOKEN(buf); last_dword = *(DWORD*)buf->value; TRACE("%s = %d\n", pt->members[i].name, *(DWORD*)buf->value); /* Assume larger size */ @@ -1712,7 +1730,7 @@ static BOOL parse_object_members_list(parse_buffer * buf) } else if (token == TOKEN_FLOAT) { - parse_TOKEN(buf); + get_TOKEN(buf); TRACE("%s = %f\n", pt->members[i].name, *(float*)buf->value); /* Assume larger size */ if ((buf->cur_pdata - buf->pxo->pdata + 4) > MAX_DATA_SIZE) @@ -1736,7 +1754,7 @@ static BOOL parse_object_members_list(parse_buffer * buf) } } - token = parse_TOKEN(buf); + token = get_TOKEN(buf); if (token != TOKEN_SEMICOLON) { /* Allow comma instead of semicolon in some specific cases */ @@ -1756,22 +1774,27 @@ static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional) if (allow_optional) { + buf->pxo->size = buf->cur_pdata - buf->pxo->pdata; + /* Skip trailing semicolon */ while (check_TOKEN(buf) == TOKEN_SEMICOLON) - parse_TOKEN(buf); + get_TOKEN(buf); while (1) { if (check_TOKEN(buf) == TOKEN_OBRACE) { - parse_TOKEN(buf); - if (parse_TOKEN(buf) != TOKEN_NAME) + get_TOKEN(buf); + if (get_TOKEN(buf) != TOKEN_NAME) return FALSE; - if (parse_TOKEN(buf) != TOKEN_CBRACE) + if (get_TOKEN(buf) != TOKEN_CBRACE) return FALSE; } else if (check_TOKEN(buf) == TOKEN_NAME) { + xobject* pxo = buf->pxo; + buf->pxo = buf->pxo->childs[buf->pxo->nb_childs] = &buf->pxo_tab[buf->cur_subobject++]; + TRACE("Enter optional %s\n", (char*)buf->value); buf->level++; if (!parse_object(buf)) @@ -1780,6 +1803,8 @@ static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional) return FALSE; } buf->level--; + buf->pxo = pxo; + buf->pxo->nb_childs++; } else break; @@ -1793,7 +1818,9 @@ static BOOL parse_object(parse_buffer * buf) { int i; - if (parse_TOKEN(buf) != TOKEN_NAME) + buf->pxo->pdata = buf->cur_pdata; + + if (get_TOKEN(buf) != TOKEN_NAME) return FALSE; /* To do template lookup */ @@ -1814,17 +1841,17 @@ static BOOL parse_object(parse_buffer * buf) if (check_TOKEN(buf) == TOKEN_NAME) { - parse_TOKEN(buf); + get_TOKEN(buf); strcpy(buf->pxo->name, (char*)buf->value); } else buf->pxo->name[0] = 0; - if (parse_TOKEN(buf) != TOKEN_OBRACE) + if (get_TOKEN(buf) != TOKEN_OBRACE) return FALSE; if (check_TOKEN(buf) == TOKEN_GUID) { - parse_TOKEN(buf); + get_TOKEN(buf); memcpy(&buf->pxo->class_id, buf->value, 16); } else @@ -1832,7 +1859,7 @@ static BOOL parse_object(parse_buffer * buf) if (!parse_object_parts(buf, TRUE)) return FALSE; - if (parse_TOKEN(buf) != TOKEN_CBRACE) + if (get_TOKEN(buf) != TOKEN_CBRACE) return FALSE; if (buf->txt) @@ -1854,10 +1881,9 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface; IDirectXFileDataImpl* object; HRESULT hr; + LPBYTE pdata; - FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj); - - /*printf("%d\n", This->buf.rem_bytes);*/ + TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj); if (!This->buf.rem_bytes) return DXFILEERR_NOMOREOBJECTS; @@ -1866,20 +1892,19 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE if (!SUCCEEDED(hr)) return hr; - This->buf.pxo = &This->xobjects[This->nb_xobjects][This->buf.cur_subobject]; - TRACE("Start %d %d\n", This->nb_xobjects, This->buf.cur_subobject); + This->buf.pxo_tab = &This->xobjects[This->nb_xobjects][0]; + This->buf.cur_subobject = 0; + This->buf.pxo = &This->buf.pxo_tab[This->buf.cur_subobject++]; - This->buf.pxo->pdata = HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE); - if (!This->buf.pxo->pdata) + pdata = HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE); + if (!pdata) { WARN("Out of memory\n"); return DXFILEERR_BADALLOC; } - This->buf.cur_pdata = This->buf.pxo->pdata; + This->buf.cur_pdata = pdata; This->buf.level = 0; - This->buf.pxo->pdata = This->buf.cur_pdata; - if (!parse_object(&This->buf)) { TRACE("Object is not correct\n"); @@ -1887,9 +1912,8 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE return DXFILEERR_PARSEERROR; } - This->buf.pxo->size = This->buf.cur_pdata - This->buf.pxo->pdata; - object->pobj = This->buf.pxo; + object->cur_enum_object = 0; *ppDataObj = (LPDIRECTXFILEDATA)object; diff --git a/dlls/d3dxof/d3dxof_private.h b/dlls/d3dxof/d3dxof_private.h index d8e6977bb94..14542f20f2a 100644 --- a/dlls/d3dxof/d3dxof_private.h +++ b/dlls/d3dxof/d3dxof_private.h @@ -114,10 +114,13 @@ typedef struct { LPBYTE buffer; DWORD rem_bytes; /* Misc info */ + WORD current_token; + BOOL token_present; BOOL txt; ULONG cur_subobject; LPBYTE cur_pdata; BYTE value[100]; + xobject* pxo_tab; IDirectXFileImpl* pdxf; xobject* pxo; xtemplate* pxt[MAX_SUBOBJECTS]; diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c index 95e865715f0..dcde97d6a45 100644 --- a/dlls/ddraw/tests/ddrawmodes.c +++ b/dlls/ddraw/tests/ddrawmodes.c @@ -284,8 +284,13 @@ static void testcooperativelevels_normal(void) /* Try creating a double buffered primary in normal mode */ rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL); - ok(rc == DDERR_NOEXCLUSIVEMODE, "IDirectDraw_CreateSurface returned %08x\n", rc); - ok(surface == NULL, "Returned surface pointer is %p\n", surface); + if (rc == DDERR_UNSUPPORTEDMODE) + skip("Unsupported mode\n"); + else + { + ok(rc == DDERR_NOEXCLUSIVEMODE, "IDirectDraw_CreateSurface returned %08x\n", rc); + ok(surface == NULL, "Returned surface pointer is %p\n", surface); + } if(surface && surface != (IDirectDrawSurface *)0xdeadbeef) IDirectDrawSurface_Release(surface); /* Set the focus window */ diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index 256f086859c..10a3fa813be 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -1068,8 +1068,15 @@ START_TEST(dsound) hDsound = LoadLibrary("dsound.dll"); if (hDsound) { + BOOL ret; + ok( FreeLibrary(hDsound), "FreeLibrary(1) returned %d\n", GetLastError()); - ok( FreeLibrary(hDsound), "FreeLibrary(2) returned %d\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = FreeLibrary(hDsound); + ok( ret || + broken(!ret && GetLastError() == ERROR_MOD_NOT_FOUND) || /* NT4 */ + broken(!ret && GetLastError() == ERROR_INVALID_HANDLE), /* Win9x */ + "FreeLibrary(2) returned %d\n", GetLastError()); ok(!FreeLibrary(hDsound), "DirectSound DLL still loaded\n"); } diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index d0ced5f9215..72080924779 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -135,6 +135,7 @@ static HWND hwnd; static int init(void) { WNDCLASSEX wc; + HIMC imc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; @@ -158,6 +159,14 @@ static int init(void) { if (!hwnd) return 0; + imc = ImmGetContext(hwnd); + if (!imc) + { + skip("IME support not implemented\n"); + return 0; + } + ImmReleaseContext(hwnd, imc); + ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); diff --git a/dlls/inetcomm/inetcomm.spec b/dlls/inetcomm/inetcomm.spec index 4db2c7dbbd2..86669c85e03 100644 --- a/dlls/inetcomm/inetcomm.spec +++ b/dlls/inetcomm/inetcomm.spec @@ -59,7 +59,7 @@ @ stub MimeOleDecodeHeader @ stub MimeOleEncodeHeader @ stub MimeOleFileTimeToInetDate -@ stub MimeOleFindCharset +@ stdcall MimeOleFindCharset(str ptr) @ stub MimeOleGenerateCID @ stub MimeOleGenerateFileName @ stub MimeOleGenerateMID @@ -71,7 +71,7 @@ @ stub MimeOleGetCodePageCharset @ stub MimeOleGetCodePageInfo @ stub MimeOleGetContentTypeExt -@ stub MimeOleGetDefaultCharset +@ stdcall MimeOleGetDefaultCharset(ptr) @ stub MimeOleGetExtContentType @ stub MimeOleGetFileExtension @ stub MimeOleGetFileInfo diff --git a/dlls/inetcomm/mimeintl.c b/dlls/inetcomm/mimeintl.c index 262bdc5fdce..6d37147e2bf 100644 --- a/dlls/inetcomm/mimeintl.c +++ b/dlls/inetcomm/mimeintl.c @@ -250,7 +250,7 @@ static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry) { - if(!strcmp(charset->cs_info.szName, pszCharset)) + if(!lstrcmpiA(charset->cs_info.szName, pszCharset)) { *phCharset = charset->cs_info.hCharset; hr = S_OK; @@ -547,6 +547,22 @@ HRESULT WINAPI MimeOleGetInternat(IMimeInternational **internat) return S_OK; } +HRESULT WINAPI MimeOleFindCharset(LPCSTR name, LPHCHARSET charset) +{ + IMimeInternational *internat; + HRESULT hr; + + TRACE("(%s, %p)\n", debugstr_a(name), charset); + + hr = MimeOleGetInternat(&internat); + if(SUCCEEDED(hr)) + { + hr = IMimeInternational_FindCharset(internat, name, charset); + IMimeInternational_Release(internat); + } + return hr; +} + HRESULT WINAPI MimeOleGetCharsetInfo(HCHARSET hCharset, LPINETCSETINFO pCsetInfo) { IMimeInternational *internat; @@ -560,5 +576,21 @@ HRESULT WINAPI MimeOleGetCharsetInfo(HCHARSET hCharset, LPINETCSETINFO pCsetInfo hr = IMimeInternational_GetCharsetInfo(internat, hCharset, pCsetInfo); IMimeInternational_Release(internat); } - return S_OK; + return hr; +} + +HRESULT WINAPI MimeOleGetDefaultCharset(LPHCHARSET charset) +{ + IMimeInternational *internat; + HRESULT hr; + + TRACE("(%p)\n", charset); + + hr = MimeOleGetInternat(&internat); + if(SUCCEEDED(hr)) + { + hr = IMimeInternational_GetDefaultCharset(internat, charset); + IMimeInternational_Release(internat); + } + return hr; } diff --git a/dlls/inetcomm/mimeole.c b/dlls/inetcomm/mimeole.c index 617286cb417..10c66850356 100644 --- a/dlls/inetcomm/mimeole.c +++ b/dlls/inetcomm/mimeole.c @@ -69,7 +69,7 @@ static const property_t default_props[] = {"Content-Type", PID_HDR_CNTTYPE, MPF_MIME | MPF_HASPARAMS, VT_LPSTR}, {"Content-Transfer-Encoding", PID_HDR_CNTXFER, MPF_MIME, VT_LPSTR}, {"Content-ID", PID_HDR_CNTID, MPF_MIME, VT_LPSTR}, - {"Content-Disposition", PID_HDR_CNTDISP, MPF_MIME, VT_LPSTR}, + {"Content-Disposition", PID_HDR_CNTDISP, MPF_MIME | MPF_HASPARAMS, VT_LPSTR}, {"To", PID_HDR_TO, MPF_ADDRESS, VT_LPSTR}, {"Cc", PID_HDR_CC, MPF_ADDRESS, VT_LPSTR}, {"Sender", PID_HDR_SENDER, MPF_ADDRESS, VT_LPSTR}, @@ -820,8 +820,26 @@ static HRESULT WINAPI MimeBody_SetOption( const TYPEDID oid, LPCPROPVARIANT pValue) { - FIXME("(%p)->(%08x, %p): stub\n", iface, oid, pValue); - return E_NOTIMPL; + HRESULT hr = E_NOTIMPL; + TRACE("(%p)->(%08x, %p)\n", iface, oid, pValue); + + if(pValue->vt != TYPEDID_TYPE(oid)) + { + WARN("Called with vartype %04x and oid %08x\n", pValue->vt, oid); + return E_INVALIDARG; + } + + switch(oid) + { + case OID_SECURITY_HWND_OWNER: + FIXME("OID_SECURITY_HWND_OWNER (value %08x): ignoring\n", pValue->u.ulVal); + hr = S_OK; + break; + default: + FIXME("Unhandled oid %08x\n", oid); + } + + return hr; } static HRESULT WINAPI MimeBody_GetOption( @@ -846,8 +864,17 @@ static HRESULT WINAPI MimeBody_IsType( IMimeBody* iface, IMSGBODYTYPE bodytype) { - FIXME("(%p)->(%d): stub\n", iface, bodytype); - return E_NOTIMPL; + MimeBody *This = impl_from_IMimeBody(iface); + + TRACE("(%p)->(%d)\n", iface, bodytype); + switch(bodytype) + { + case IBT_EMPTY: + return This->data ? S_FALSE : S_OK; + default: + FIXME("Unimplemented bodytype %d - returning S_OK\n", bodytype); + } + return S_OK; } static HRESULT WINAPI MimeBody_SetDisplayName( @@ -2172,8 +2199,30 @@ static HRESULT WINAPI MimeMessage_SetOption( const TYPEDID oid, LPCPROPVARIANT pValue) { - FIXME("(%p)->(%08x, %p)\n", iface, oid, pValue); - return E_NOTIMPL; + HRESULT hr = E_NOTIMPL; + TRACE("(%p)->(%08x, %p)\n", iface, oid, pValue); + + if(pValue->vt != TYPEDID_TYPE(oid)) + { + WARN("Called with vartype %04x and oid %08x\n", pValue->vt, oid); + return E_INVALIDARG; + } + + switch(oid) + { + case OID_HIDE_TNEF_ATTACHMENTS: + FIXME("OID_HIDE_TNEF_ATTACHMENTS (value %d): ignoring\n", pValue->u.boolVal); + hr = S_OK; + break; + case OID_SHOW_MACBINARY: + FIXME("OID_SHOW_MACBINARY (value %d): ignoring\n", pValue->u.boolVal); + hr = S_OK; + break; + default: + FIXME("Unhandled oid %08x\n", oid); + } + + return hr; } static HRESULT WINAPI MimeMessage_GetOption( diff --git a/dlls/inetcomm/tests/mimeintl.c b/dlls/inetcomm/tests/mimeintl.c index e7cdd87a28b..d82c191fd16 100644 --- a/dlls/inetcomm/tests/mimeintl.c +++ b/dlls/inetcomm/tests/mimeintl.c @@ -149,6 +149,9 @@ static void test_charset(void) hr = IMimeInternational_FindCharset(internat, "windows-1252", &hcs); ok(hr == S_OK, "got %08x\n", hr); ok(hcs_windows_1252 == hcs, "got different hcharsets for the same name\n"); + hr = IMimeInternational_FindCharset(internat, "WiNdoWs-1252", &hcs); + ok(hr == S_OK, "got %08x\n", hr); + ok(hcs_windows_1252 == hcs, "got different hcharsets for the same name\n"); hr = IMimeInternational_FindCharset(internat, "windows-1251", &hcs_windows_1251); ok(hr == S_OK, "got %08x\n", hr); diff --git a/dlls/inetcomm/tests/mimeole.c b/dlls/inetcomm/tests/mimeole.c index 8200400e90e..1f29abb622e 100644 --- a/dlls/inetcomm/tests/mimeole.c +++ b/dlls/inetcomm/tests/mimeole.c @@ -130,6 +130,8 @@ static void test_CreateBody(void) ok(hr == S_FALSE, "ret %08x\n", hr); hr = IMimeBody_IsContentType(body, NULL, "mixed"); ok(hr == S_OK, "ret %08x\n", hr); + hr = IMimeBody_IsType(body, IBT_EMPTY); + ok(hr == S_OK, "got %08x\n", hr); hr = IMimeBody_SetData(body, IET_8BIT, "text", "plain", &IID_IStream, in); ok(hr == S_OK, "ret %08x\n", hr); @@ -148,6 +150,9 @@ static void test_CreateBody(void) ok(offsets.cbBodyStart == 0, "got %d\n", offsets.cbBodyStart); ok(offsets.cbBodyEnd == 0, "got %d\n", offsets.cbBodyEnd); + hr = IMimeBody_IsType(body, IBT_EMPTY); + ok(hr == S_FALSE, "got %08x\n", hr); + hr = MimeOleGetAllocator(&alloc); ok(hr == S_OK, "ret %08x\n", hr); diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c index c131865be11..11c8b95929e 100644 --- a/dlls/jscript/array.c +++ b/dlls/jscript/array.c @@ -47,6 +47,7 @@ static const WCHAR propertyIsEnumerableW[] = {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; +const WCHAR default_separatorW[] = {',',0}; static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) @@ -68,18 +69,220 @@ static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM return S_OK; } +static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len, LCID lcid, + jsexcept_t *ei, IServiceProvider *caller) +{ + VARIANT var; + DWORD i; + HRESULT hres; + + for(i=0; i < obj->length; i++) { + hres = jsdisp_propget_idx(&obj->dispex, i, lcid, &var, ei, caller); + if(hres == DISP_E_UNKNOWNNAME) + continue; + if(FAILED(hres)) + return hres; + + hres = jsdisp_propput_idx(array, *len+i, lcid, &var, ei, caller); + VariantClear(&var); + if(FAILED(hres)) + return hres; + } + + *len += obj->length; + return S_OK; +} + +static HRESULT concat_obj(DispatchEx *array, IDispatch *obj, DWORD *len, LCID lcid, jsexcept_t *ei, IServiceProvider *caller) +{ + DispatchEx *jsobj; + VARIANT var; + HRESULT hres; + + jsobj = iface_to_jsdisp((IUnknown*)obj); + if(jsobj) { + if(is_class(jsobj, JSCLASS_ARRAY)) { + hres = concat_array(array, (ArrayInstance*)jsobj, len, lcid, ei, caller); + jsdisp_release(jsobj); + return hres; + } + jsdisp_release(jsobj); + } + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = obj; + return jsdisp_propput_idx(array, (*len)++, lcid, &var, ei, caller); +} + static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { - FIXME("\n"); - return E_NOTIMPL; + DispatchEx *ret; + DWORD len = 0; + HRESULT hres; + + TRACE("\n"); + + hres = create_array(dispex->ctx, 0, &ret); + if(FAILED(hres)) + return hres; + + hres = concat_obj(ret, (IDispatch*)_IDispatchEx_(dispex), &len, lcid, ei, caller); + if(SUCCEEDED(hres)) { + VARIANT *arg; + DWORD i; + + for(i=0; i < arg_cnt(dp); i++) { + arg = get_arg(dp, i); + if(V_VT(arg) == VT_DISPATCH) + hres = concat_obj(ret, V_DISPATCH(arg), &len, lcid, ei, caller); + else + hres = jsdisp_propput_idx(ret, len++, lcid, arg, ei, caller); + if(FAILED(hres)) + break; + } + } + + if(FAILED(hres)) + return hres; + + if(retv) { + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret); + }else { + jsdisp_release(ret); + } + return S_OK; +} + +static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHAR *sep, VARIANT *retv, + jsexcept_t *ei, IServiceProvider *caller) +{ + BSTR *str_tab, ret = NULL; + VARIANT var; + DWORD i; + HRESULT hres = E_FAIL; + + if(!length) { + if(retv) { + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = SysAllocStringLen(NULL, 0); + if(!V_BSTR(retv)) + return E_OUTOFMEMORY; + } + return S_OK; + } + + str_tab = heap_alloc_zero(length * sizeof(BSTR)); + if(!str_tab) + return E_OUTOFMEMORY; + + for(i=0; i < length; i++) { + hres = jsdisp_propget_idx(array, i, lcid, &var, ei, caller); + if(FAILED(hres)) + break; + + if(V_VT(&var) != VT_EMPTY && V_VT(&var) != VT_NULL) + hres = to_string(array->ctx, &var, ei, str_tab+i); + VariantClear(&var); + if(FAILED(hres)) + break; + } + + if(SUCCEEDED(hres)) { + DWORD seplen = 0, len = 0; + WCHAR *ptr; + + seplen = strlenW(sep); + + if(str_tab[0]) + len = SysStringLen(str_tab[0]); + for(i=1; i < length; i++) + len += seplen + SysStringLen(str_tab[i]); + + ret = SysAllocStringLen(NULL, len); + if(ret) { + DWORD tmplen = 0; + + if(str_tab[0]) { + tmplen = SysStringLen(str_tab[0]); + memcpy(ret, str_tab[0], tmplen*sizeof(WCHAR)); + } + + ptr = ret + tmplen; + for(i=1; i < length; i++) { + if(seplen) { + memcpy(ptr, sep, seplen*sizeof(WCHAR)); + ptr += seplen; + } + + if(str_tab[i]) { + tmplen = SysStringLen(str_tab[i]); + memcpy(ptr, str_tab[i], tmplen*sizeof(WCHAR)); + ptr += tmplen; + } + } + *ptr=0; + }else { + hres = E_OUTOFMEMORY; + } + } + + for(i=0; i < length; i++) + SysFreeString(str_tab[i]); + heap_free(str_tab); + if(FAILED(hres)) + return hres; + + TRACE("= %s\n", debugstr_w(ret)); + + if(retv) { + if(!ret) { + ret = SysAllocStringLen(NULL, 0); + if(!ret) + return E_OUTOFMEMORY; + } + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + }else { + SysFreeString(ret); + } + + return S_OK; } +/* ECMA-262 3rd Edition 15.4.4.5 */ static HRESULT Array_join(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { - FIXME("\n"); - return E_NOTIMPL; + DWORD length; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_ARRAY)) { + length = ((ArrayInstance*)dispex)->length; + }else { + FIXME("dispid is not Array\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp)) { + BSTR sep; + + hres = to_string(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &sep); + if(FAILED(hres)) + return hres; + + hres = array_join(dispex, lcid, length, sep, retv, ei, caller); + + SysFreeString(sep); + }else { + hres = array_join(dispex, lcid, length, default_separatorW, retv, ei, caller); + } + + return hres; } static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -89,11 +292,35 @@ static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS * return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.4.4.7 */ static HRESULT Array_push(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + DWORD length = 0; + int i, n; + HRESULT hres; + + TRACE("\n"); + + if(dispex->builtin_info->class == JSCLASS_ARRAY) { + length = ((ArrayInstance*)dispex)->length; + }else { + FIXME("not Array this\n"); + return E_NOTIMPL; + } + + n = dp->cArgs - dp->cNamedArgs; + for(i=0; i < n; i++) { + hres = jsdisp_propput_idx(dispex, length+i, lcid, get_arg(dp, i), ei, sp); + if(FAILED(hres)) + return hres; + } + + if(retv) { + V_VT(retv) = VT_I4; + V_I4(retv) = length+n; + } + return S_OK; } static HRESULT Array_reverse(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -117,11 +344,215 @@ static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS return E_NOTIMPL; } +static HRESULT sort_cmp(script_ctx_t *ctx, DispatchEx *cmp_func, VARIANT *v1, VARIANT *v2, jsexcept_t *ei, + IServiceProvider *caller, INT *cmp) +{ + HRESULT hres; + + if(cmp_func) { + VARIANTARG args[2]; + DISPPARAMS dp = {args, NULL, 2, 0}; + VARIANT tmp; + VARIANT res; + + args[0] = *v2; + args[1] = *v1; + + hres = jsdisp_call_value(cmp_func, ctx->lcid, DISPATCH_METHOD, &dp, &res, ei, caller); + if(FAILED(hres)) + return hres; + + hres = to_number(ctx, &res, ei, &tmp); + VariantClear(&res); + if(FAILED(hres)) + return hres; + + if(V_VT(&tmp) == VT_I4) + *cmp = V_I4(&tmp); + else + *cmp = V_R8(&tmp) > 0.0 ? 1 : -1; + }else if(is_num_vt(V_VT(v1))) { + if(is_num_vt(V_VT(v2))) { + DOUBLE d = num_val(v1)-num_val(v2); + if(d > 0.0) + *cmp = 1; + else if(d < -0.0) + *cmp = -1; + else + *cmp = 0; + }else { + *cmp = -1; + } + }else if(is_num_vt(V_VT(v2))) { + *cmp = 1; + }else if(V_VT(v1) == VT_BSTR) { + if(V_VT(v2) == VT_BSTR) + *cmp = strcmpW(V_BSTR(v1), V_BSTR(v2)); + else + *cmp = -1; + }else if(V_VT(v2) == VT_BSTR) { + *cmp = 1; + }else { + *cmp = 0; + } + + return S_OK; +} + +/* ECMA-262 3rd Edition 15.4.4.11 */ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { - FIXME("\n"); - return E_NOTIMPL; + DispatchEx *cmp_func = NULL; + VARIANT *vtab, **sorttab = NULL; + DWORD length; + DWORD i; + HRESULT hres = S_OK; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_ARRAY)) { + length = ((ArrayInstance*)dispex)->length; + }else { + FIXME("unsupported this not array\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp) > 1) { + WARN("invalid arg_cnt %d\n", arg_cnt(dp)); + return E_FAIL; + } + + if(arg_cnt(dp) == 1) { + VARIANT *arg = get_arg(dp, 0); + + if(V_VT(arg) != VT_DISPATCH) { + WARN("arg is not dispatch\n"); + return E_FAIL; + } + + + cmp_func = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg)); + if(!is_class(cmp_func, JSCLASS_FUNCTION)) { + WARN("cmp_func is not a function\n"); + jsdisp_release(cmp_func); + return E_FAIL; + } + } + + if(!length) { + if(cmp_func) + jsdisp_release(cmp_func); + if(retv) { + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex); + IDispatchEx_AddRef(_IDispatchEx_(dispex)); + } + return S_OK; + } + + vtab = heap_alloc_zero(length * sizeof(VARIANT)); + if(vtab) { + for(i=0; ictx, cmp_func, sorttab[2*i+1], sorttab[2*i], ei, caller, &cmp); + if(FAILED(hres)) + break; + + if(cmp < 0) { + tmpv = sorttab[2*i]; + sorttab[2*i] = sorttab[2*i+1]; + sorttab[2*i+1] = tmpv; + } + } + + if(SUCCEEDED(hres)) { + DWORD k, a, b, bend; + + for(k=2; k < length; k *= 2) { + for(i=0; i+k < length; i += 2*k) { + a = b = 0; + if(i+2*k <= length) + bend = k; + else + bend = length - (i+k); + + memcpy(tmpbuf, sorttab+i, k*sizeof(VARIANT*)); + + while(a < k && b < bend) { + hres = sort_cmp(dispex->ctx, cmp_func, tmpbuf[a], sorttab[i+k+b], ei, caller, &cmp); + if(FAILED(hres)) + break; + + if(cmp < 0) { + sorttab[i+a+b] = tmpbuf[a]; + a++; + }else { + sorttab[i+a+b] = sorttab[i+k+b]; + b++; + } + } + + if(FAILED(hres)) + break; + + if(a < k) + memcpy(sorttab+i+a+b, tmpbuf+a, (k-a)*sizeof(VARIANT*)); + } + + if(FAILED(hres)) + break; + } + } + + for(i=0; SUCCEEDED(hres) && i < length; i++) + hres = jsdisp_propput_idx(dispex, i, lcid, sorttab[i], ei, caller); + } + + if(vtab) { + for(i=0; i < length; i++) + VariantClear(vtab+i); + heap_free(vtab); + } + heap_free(sorttab); + if(cmp_func) + jsdisp_release(cmp_func); + + if(FAILED(hres)) + return hres; + + if(retv) { + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex); + IDispatch_AddRef(_IDispatchEx_(dispex)); + } + + return S_OK; } static HRESULT Array_splice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -131,11 +562,18 @@ static HRESULT Array_splice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.4.4.2 */ static HRESULT Array_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + TRACE("\n"); + + if(!is_class(dispex, JSCLASS_ARRAY)) { + WARN("not Array object\n"); + return E_FAIL; + } + + return array_join(dispex, lcid, ((ArrayInstance*)dispex)->length, default_separatorW, retv, ei, sp); } static HRESULT Array_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -183,8 +621,17 @@ static HRESULT Array_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DI static HRESULT Array_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + TRACE("\n"); + + switch(flags) { + case INVOKE_PROPERTYGET: + return array_join(dispex, lcid, ((ArrayInstance*)dispex)->length, default_separatorW, retv, ei, sp); + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } static void Array_destructor(DispatchEx *dispex) diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 1c643f69c9a..896af9101b0 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -698,23 +698,6 @@ static IDispatchExVtbl DispatchExVtbl = { DispatchEx_GetNameSpaceParent }; -HRESULT jsdisp_set_prototype(DispatchEx *dispex, DispatchEx *prototype) -{ - VARIANT *var; - - if(!dispex->props[1].name) - return E_OUTOFMEMORY; - - dispex->props[1].type = PROP_VARIANT; - dispex->props[1].flags = 0; - - var = &dispex->props[1].u.var; - V_VT(var) = VT_DISPATCH; - V_DISPATCH(var) = (IDispatch*)_IDispatchEx_(prototype); - - return S_OK; -} - HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, DispatchEx *prototype) { TRACE("%p (%p)\n", dispex, prototype); @@ -861,6 +844,11 @@ HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS if(FAILED(hres)) { UINT err = 0; + if(flags == DISPATCH_CONSTRUCT) { + WARN("IDispatch cannot be constructor\n"); + return DISP_E_MEMBERNOTFOUND; + } + TRACE("using IDispatch\n"); return IDispatch_Invoke(disp, id, &IID_NULL, lcid, flags, dp, retv, &ei->ei, &err); } @@ -931,6 +919,34 @@ HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce return hres; } +static HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIANT *var, + jsexcept_t *ei, IServiceProvider *caller) +{ + DISPPARAMS dp = {NULL, NULL, 0, 0}; + dispex_prop_t *prop; + HRESULT hres; + + hres = find_prop_name_prot(obj, name, FALSE, &prop); + if(FAILED(hres)) + return hres; + + V_VT(var) = VT_EMPTY; + if(!prop) + return S_OK; + + return prop_get(obj, prop, lcid, &dp, var, ei, caller); +} + +HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, LCID lcid, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller) +{ + WCHAR buf[12]; + + static const WCHAR formatW[] = {'%','d',0}; + + sprintfW(buf, formatW, idx); + return jsdisp_propget_name(obj, buf, lcid, var, ei, caller); +} + HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { DISPPARAMS dp = {NULL,NULL,0,0}; diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index f0f5062e4e1..8f3ab02c3e0 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -278,16 +278,6 @@ static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret) return S_OK; } -static inline BOOL is_num_vt(enum VARENUM vt) -{ - return vt == VT_I4 || vt == VT_R8; -} - -static inline DOUBLE num_val(const VARIANT *v) -{ - return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v); -} - /* ECMA-262 3rd Edition 11.9.6 */ HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret) { @@ -377,7 +367,8 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so DispatchEx *func_obj; VARIANT var; - hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj); + hres = create_source_function(parser, func->parameter_list, func->source_elements, + ctx->scope_chain, func->src_str, func->src_len, &func_obj); if(FAILED(hres)) return hres; @@ -793,9 +784,10 @@ HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t return hres; if(V_VT(&val) != VT_DISPATCH) { - FIXME("in vt %d\n", V_VT(&val)); + TRACE("in vt %d\n", V_VT(&val)); VariantClear(&val); - return E_NOTIMPL; + V_VT(ret) = VT_EMPTY; + return S_OK; } hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj); @@ -959,7 +951,8 @@ HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t * hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain); jsdisp_release(obj); - if(FAILED(hres)); + if(FAILED(hres)) + return hres; hres = stat_eval(ctx, stat->statement, rt, ret); @@ -1251,7 +1244,8 @@ HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD fla TRACE("\n"); - hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, &dispex); + hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, + expr->src_str, expr->src_len, &dispex); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 3f7fda86c9a..beabc9b12c2 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -98,7 +98,8 @@ typedef struct _statement_t statement_t; typedef struct _expression_t expression_t; typedef struct _parameter_t parameter_t; -HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,DispatchEx**); +HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*, + const WCHAR*,DWORD,DispatchEx**); typedef struct { VARTYPE vt; @@ -277,6 +278,8 @@ typedef struct _function_declaration_t { const WCHAR *identifier; parameter_t *parameter_list; source_elements_t *source_elements; + const WCHAR *src_str; + DWORD src_len; struct _function_declaration_t *next; } function_declaration_t; @@ -293,6 +296,8 @@ typedef struct { const WCHAR *identifier; parameter_t *parameter_list; source_elements_t *source_elements; + const WCHAR *src_str; + DWORD src_len; } function_expression_t; typedef struct { diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 7d39ad05893..96c41a917b4 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -31,6 +31,8 @@ typedef struct { parameter_t *parameters; scope_chain_t *scope_chain; parser_ctx_t *parser; + const WCHAR *src_str; + DWORD src_len; DWORD length; } FunctionInstance; @@ -226,6 +228,23 @@ static HRESULT invoke_value_proc(FunctionInstance *function, LCID lcid, WORD fla return hres; } +static HRESULT function_to_string(FunctionInstance *function, BSTR *ret) +{ + BSTR str; + + if(function->value_proc) { + FIXME("Builtin functions not implemented\n"); + return E_NOTIMPL; + } + + str = SysAllocStringLen(function->src_str, function->src_len); + if(!str) + return E_OUTOFMEMORY; + + *ret = str; + return S_OK; +} + static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -249,8 +268,30 @@ static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + FunctionInstance *function; + BSTR str; + HRESULT hres; + + TRACE("\n"); + + if(!is_class(dispex, JSCLASS_FUNCTION)) { + FIXME("throw TypeError\n"); + return E_FAIL; + } + + function = (FunctionInstance*)dispex; + + hres = function_to_string(function, &str); + if(FAILED(hres)) + return hres; + + if(retv) { + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = str; + }else { + SysFreeString(str); + } + return S_OK; } static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -323,6 +364,19 @@ static HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR return invoke_function(function, lcid, dp, retv, ei, caller); + case DISPATCH_PROPERTYGET: { + HRESULT hres; + BSTR str; + + hres = function_to_string(function, &str); + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = str; + break; + } + case DISPATCH_CONSTRUCT: if(function->value_proc) return invoke_value_proc(function, lcid, flags, dp, retv, ei, caller); @@ -438,7 +492,7 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, } HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, source_elements_t *source, - scope_chain_t *scope_chain, DispatchEx **ret) + scope_chain_t *scope_chain, const WCHAR *src_str, DWORD src_len, DispatchEx **ret) { FunctionInstance *function; DispatchEx *prototype; @@ -470,6 +524,9 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc length++; function->length = length; + function->src_str = src_str; + function->src_len = src_len; + *ret = &function->dispex; return S_OK; } diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 4404bffe8c3..30e2bd54a2a 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -228,10 +228,83 @@ static HRESULT JSGlobal_isFinite(DispatchEx *dispex, LCID lcid, WORD flags, DISP return E_NOTIMPL; } +static INT char_to_int(WCHAR c) +{ + if('0' <= c && c <= '9') + return c - '0'; + if('a' <= c && c <= 'z') + return c - 'a' + 10; + if('A' <= c && c <= 'Z') + return c - 'A' + 10; + return 100; +} + static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - return E_NOTIMPL; + DOUBLE ret = 0.0; + INT radix=10, i; + WCHAR *ptr; + BOOL neg = FALSE; + BSTR str; + HRESULT hres; + + if(!arg_cnt(dp)) { + FIXME("NAN\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp) >= 2) { + hres = to_int32(dispex->ctx, get_arg(dp, 1), ei, &radix); + if(FAILED(hres)) + return hres; + + if(!radix) { + radix = 10; + }else if(radix < 2 || radix > 36) { + WARN("radix %d out of range\n", radix); + return E_FAIL; + } + } + + hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &str); + if(FAILED(hres)) + return hres; + + for(ptr = str; isspaceW(*ptr); ptr++); + + switch(*ptr) { + case '+': + ptr++; + break; + case '-': + neg = TRUE; + ptr++; + break; + case '0': + ptr++; + if(*ptr == 'x' || *ptr == 'X') { + radix = 16; + ptr++; + } + } + + while(*ptr) { + i = char_to_int(*ptr++); + if(i > radix) + break; + + ret = ret*radix + i; + } + + SysFreeString(str); + + if(neg) + ret = -ret; + + if(retv) + num_set_val(retv, ret); + return S_OK; } static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -353,7 +426,7 @@ static HRESULT init_constructors(script_ctx_t *ctx) if(FAILED(hres)) return hres; - hres = create_object_constr(ctx, &ctx->regexp_constr); + hres = create_regexp_constr(ctx, &ctx->regexp_constr); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 7c7def07468..373066155d5 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -621,7 +621,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars return hres; } - hres = create_source_function(parser_ctx, NULL, parser_ctx->source, NULL, &dispex); + hres = create_source_function(parser_ctx, NULL, parser_ctx->source, NULL, NULL, 0, &dispex); parser_release(parser_ctx); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 6c4e2723b80..ed248c12a9c 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -126,6 +126,7 @@ HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvide HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx*,DispatchEx**); @@ -208,6 +209,21 @@ static inline DWORD arg_cnt(const DISPPARAMS *dp) return dp->cArgs - dp->cNamedArgs; } +static inline BOOL is_class(DispatchEx *jsdisp, jsclass_t class) +{ + return jsdisp->builtin_info->class == class; +} + +static inline BOOL is_num_vt(enum VARENUM vt) +{ + return vt == VT_I4 || vt == VT_R8; +} + +static inline DOUBLE num_val(const VARIANT *v) +{ + return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v); +} + static inline void num_set_val(VARIANT *v, DOUBLE d) { if(d == (DOUBLE)(INT)d) { diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index f368c3efcaa..cd7fa570b5b 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -217,6 +217,110 @@ HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b) return S_OK; } +static int hex_to_int(WCHAR c) +{ + if('0' <= c && c <= '9') + return c-'0'; + + if('a' <= c && c <= 'f') + return c-'a'+10; + + if('A' <= c && c <= 'F') + return c-'A'+10; + + return -1; +} + +/* ECMA-262 3rd Edition 9.3.1 */ +static HRESULT str_to_number(BSTR str, VARIANT *ret) +{ + const WCHAR *ptr = str; + BOOL neg = FALSE; + DOUBLE d = 0.0; + + static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'}; + + while(isspaceW(*ptr)) + ptr++; + + if(!strncmpW(ptr, infinityW, sizeof(infinityW)/sizeof(WCHAR))) { + ptr += sizeof(infinityW)/sizeof(WCHAR); + while(*ptr && isspaceW(*ptr)) + ptr++; + + if(*ptr) { + FIXME("NaN\n"); + return E_NOTIMPL; + } + + FIXME("inf\n"); + return E_NOTIMPL; + } + + if(*ptr == '-') { + neg = TRUE; + ptr++; + }else if(*ptr == '+') { + ptr++; + }else if(*ptr == '0' && ptr[1] == 'x') { + DWORD l = 0; + + ptr += 2; + while((l = hex_to_int(*ptr)) != -1) { + d = d*16 + l; + ptr++; + } + + num_set_val(ret, d); + return S_OK; + } + + while(isdigitW(*ptr)) + d = d*10 + (*ptr++ - '0'); + + if(*ptr == 'e' || *ptr == 'E') { + BOOL eneg = FALSE; + LONG l = 0; + + ptr++; + if(*ptr == '-') { + ptr++; + eneg = TRUE; + }else if(*ptr == '+') { + ptr++; + } + + while(isdigitW(*ptr)) + l = l*10 + (*ptr++ - '0'); + if(eneg) + l = -l; + + d *= pow(10, l); + }else if(*ptr == '.') { + DOUBLE dec = 0.1; + + ptr++; + while(isdigitW(*ptr)) { + d += dec * (*ptr++ - '0'); + dec *= 0.1; + } + } + + while(isspaceW(*ptr)) + ptr++; + + if(*ptr) { + FIXME("NaN\n"); + return E_NOTIMPL; + } + + if(neg) + d = -d; + + num_set_val(ret, d); + return S_OK; +} + /* ECMA-262 3rd Edition 9.3 */ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret) { @@ -229,6 +333,8 @@ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret) case VT_R8: *ret = *v; break; + case VT_BSTR: + return str_to_number(V_BSTR(v), ret); case VT_BOOL: V_VT(ret) = VT_I4; V_I4(ret) = V_BOOL(v) ? 1 : 0; @@ -252,7 +358,7 @@ HRESULT to_integer(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret) return hres; if(V_VT(&num) == VT_I4) - *ret = *v; + *ret = num; else num_set_val(ret, V_R8(&num) >= 0.0 ? floor(V_R8(&num)) : -floor(-V_R8(&num))); diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c index ed73202a5ab..4ad9fe50d93 100644 --- a/dlls/jscript/lex.c +++ b/dlls/jscript/lex.c @@ -101,7 +101,7 @@ static int lex_error(parser_ctx_t *ctx, HRESULT hres) return -1; } -static int check_keyword(parser_ctx_t *ctx, const WCHAR *word) +static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval) { const WCHAR *p1 = ctx->ptr; const WCHAR *p2 = word; @@ -116,6 +116,7 @@ static int check_keyword(parser_ctx_t *ctx, const WCHAR *word) if(*p2 || (p1 < ctx->end && isalnumW(*p1))) return 1; + *lval = ctx->ptr; ctx->ptr = p1; return 0; } @@ -145,14 +146,14 @@ static int hex_to_int(WCHAR c) return -1; } -static int check_keywords(parser_ctx_t *ctx) +static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval) { int min = 0, max = sizeof(keywords)/sizeof(keywords[0])-1, r, i; while(min <= max) { i = (min+max)/2; - r = check_keyword(ctx, keywords[i].word); + r = check_keyword(ctx, keywords[i].word, lval); if(!r) return keywords[i].token; @@ -387,7 +388,7 @@ static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **li e = e*10 + *ctx->ptr++ - '0'; e *= sign; - d = pow(d, e); + d *= pow(10, e); } *literal = parser_alloc(ctx, sizeof(literal_t)); @@ -468,7 +469,7 @@ int parser_lex(void *lval, parser_ctx_t *ctx) }while(skip_comment(ctx)); if(isalphaW(*ctx->ptr)) { - ret = check_keywords(ctx); + ret = check_keywords(ctx, lval); if(ret) return ret; @@ -480,7 +481,6 @@ int parser_lex(void *lval, parser_ctx_t *ctx) switch(*ctx->ptr) { case '{': - case '}': case '(': case ')': case '[': @@ -492,6 +492,10 @@ int parser_lex(void *lval, parser_ctx_t *ctx) case ':': return *ctx->ptr++; + case '}': + *(const WCHAR**)lval = ctx->ptr++; + return '}'; + case '.': if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) return parse_double_literal(ctx, 0, lval); diff --git a/dlls/jscript/math.c b/dlls/jscript/math.c index 8454cfa87e3..e0e88e4ca27 100644 --- a/dlls/jscript/math.c +++ b/dlls/jscript/math.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "jscript.h" #include "wine/debug.h" @@ -105,11 +107,29 @@ static HRESULT Math_SQRT1_2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.8.2.12 */ static HRESULT Math_abs(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + VARIANT v; + DOUBLE d; + HRESULT hres; + + TRACE("\n"); + + if(!arg_cnt(dp)) { + FIXME("arg_cnt = 0\n"); + return E_NOTIMPL; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + d = num_val(&v); + if(retv) + num_set_val(retv, d < 0.0 ? -d : d); + return S_OK; } static HRESULT Math_acos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -140,11 +160,27 @@ static HRESULT Math_atan2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.8.2.6 */ static HRESULT Math_ceil(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + VARIANT v; + HRESULT hres; + + TRACE("\n"); + + if(!arg_cnt(dp)) { + FIXME("arg_cnt = 0\n"); + return E_NOTIMPL; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + if(retv) + num_set_val(retv, ceil(num_val(&v))); + return S_OK; } static HRESULT Math_cos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -175,25 +211,107 @@ static HRESULT Math_log(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.8.2.11 */ static HRESULT Math_max(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + DOUBLE max, d; + VARIANT v; + DWORD i; + HRESULT hres; + + TRACE("\n"); + + /* FIXME: Handle NaN */ + + if(!arg_cnt(dp)) { + FIXME("arg_cnt = 0\n"); + return E_NOTIMPL; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + max = num_val(&v); + for(i=1; i < arg_cnt(dp); i++) { + hres = to_number(dispex->ctx, get_arg(dp, i), ei, &v); + if(FAILED(hres)) + return hres; + + d = num_val(&v); + if(d > max) + max = d; + } + + if(retv) + num_set_val(retv, max); + return S_OK; } +/* ECMA-262 3rd Edition 15.8.2.12 */ static HRESULT Math_min(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + DOUBLE min, d; + VARIANT v; + DWORD i; + HRESULT hres; + + TRACE("\n"); + + /* FIXME: Handle NaN */ + + if(!arg_cnt(dp)) { + FIXME("arg_cnt = 0\n"); + return E_NOTIMPL; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + min = num_val(&v); + for(i=1; i < arg_cnt(dp); i++) { + hres = to_number(dispex->ctx, get_arg(dp, i), ei, &v); + if(FAILED(hres)) + return hres; + + d = num_val(&v); + if(d < min) + min = d; + } + + if(retv) + num_set_val(retv, min); + return S_OK; } +/* ECMA-262 3rd Edition 15.8.2.13 */ static HRESULT Math_pow(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + VARIANT x, y; + HRESULT hres; + + TRACE("\n"); + + if(arg_cnt(dp) < 2) { + FIXME("unimplemented arg_cnt %d\n", arg_cnt(dp)); + return E_NOTIMPL; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &x); + if(FAILED(hres)) + return hres; + + hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &y); + if(FAILED(hres)) + return hres; + + if(retv) + num_set_val(retv, pow(num_val(&x), num_val(&y))); + return S_OK; } static HRESULT Math_random(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -203,11 +321,27 @@ static HRESULT Math_random(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.8.2.15 */ static HRESULT Math_round(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + VARIANT v; + HRESULT hres; + + TRACE("\n"); + + if(!arg_cnt(dp)) { + FIXME("arg_cnt = 0\n"); + return E_NOTIMPL; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + if(retv) + num_set_val(retv, floor(num_val(&v)+0.5)); + return S_OK; } static HRESULT Math_sin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c index 108cfff1a14..4ace40b093e 100644 --- a/dlls/jscript/number.c +++ b/dlls/jscript/number.c @@ -39,11 +39,39 @@ static const WCHAR propertyIsEnumerableW[] = {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; +/* ECMA-262 3rd Edition 15.7.4.2 */ static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + NumberInstance *number; + BSTR str; + HRESULT hres; + + TRACE("\n"); + + if(!is_class(dispex, JSCLASS_NUMBER)) { + FIXME("throw TypeError\n"); + return E_FAIL; + } + + number = (NumberInstance*)dispex; + + if(arg_cnt(dp) != 0) { + FIXME("unsupported args\n"); + return E_NOTIMPL; + } + + hres = to_string(dispex->ctx, &number->num, ei, &str); + if(FAILED(hres)) + return hres; + + if(retv) { + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = str; + }else { + SysFreeString(str); + } + return S_OK; } static HRESULT Number_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -133,8 +161,61 @@ static const builtin_info_t Number_info = { static HRESULT NumberConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + VARIANT num; + HRESULT hres; + + TRACE("\n"); + + switch(flags) { + case INVOKE_FUNC: + if(!arg_cnt(dp)) { + if(retv) { + V_VT(retv) = VT_I4; + V_I4(retv) = 0; + } + return S_OK; + } + + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &num); + if(FAILED(hres)) + return hres; + + if(retv) + *retv = num; + break; + + case DISPATCH_CONSTRUCT: { + DispatchEx *obj; + + switch(arg_cnt(dp)) { + case 0: + V_VT(&num) = VT_I4; + V_I4(&num) = 0; + break; + case 1: + hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &num); + if(FAILED(hres)) + return hres; + break; + default: + FIXME("unimplemented args\n"); + return E_NOTIMPL; + } + + hres = create_number(dispex->ctx, &num, &obj); + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(obj); + break; + } + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } static HRESULT alloc_number(script_ctx_t *ctx, BOOL use_constr, NumberInstance **ret) diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 2f021f7efa6..02d80de02fd 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -30,6 +30,8 @@ static const WCHAR propertyIsEnumerableW[] = {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; +static const WCHAR default_valueW[] = {'[','o','b','j','e','c','t',' ','O','b','j','e','c','t',']',0}; + static HRESULT Object_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -75,8 +77,21 @@ static HRESULT Object_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, D static HRESULT Object_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = SysAllocString(default_valueW); + if(!V_BSTR(retv)) + return E_OUTOFMEMORY; + break; + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } static void Object_destructor(DispatchEx *dispex) diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index a6cb5ebf32c..96ca9e552d1 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -120,7 +120,8 @@ typedef struct _parameter_list_t { static parameter_list_t *new_parameter_list(parser_ctx_t*,const WCHAR*); static parameter_list_t *parameter_list_add(parser_ctx_t*,parameter_list_t*,const WCHAR*); -static expression_t *new_function_expression(parser_ctx_t*,const WCHAR*,parameter_list_t*,source_elements_t*); +static expression_t *new_function_expression(parser_ctx_t*,const WCHAR*,parameter_list_t*, + source_elements_t*,const WCHAR*,DWORD); static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expression_t*,expression_t*); static expression_t *new_unary_expression(parser_ctx_t*,expression_type_t,expression_t*); static expression_t *new_conditional_expression(parser_ctx_t*,expression_t*,expression_t*,expression_t*); @@ -134,7 +135,8 @@ static expression_t *new_literal_expression(parser_ctx_t*,literal_t*); static expression_t *new_array_literal_expression(parser_ctx_t*,element_list_t*,int); static expression_t *new_prop_and_value_expression(parser_ctx_t*,property_list_t*); -static function_declaration_t *new_function_declaration(parser_ctx_t*,const WCHAR*,parameter_list_t*,source_elements_t*); +static function_declaration_t *new_function_declaration(parser_ctx_t*,const WCHAR*,parameter_list_t*, + source_elements_t*,const WCHAR*,DWORD); static source_elements_t *new_source_elements(parser_ctx_t*); static source_elements_t *source_elements_add_statement(source_elements_t*,statement_t*); static source_elements_t *source_elements_add_function(source_elements_t*,function_declaration_t*); @@ -146,6 +148,7 @@ static source_elements_t *source_elements_add_function(source_elements_t*,functi %union { int ival; + const WCHAR *srcptr; LPCWSTR wstr; literal_t *literal; struct _argument_list_t *argument_list; @@ -166,10 +169,12 @@ static source_elements_t *source_elements_add_function(source_elements_t*,functi } /* keywords */ -%token kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kIF kFINALLY kFOR kFUNCTION kIN +%token kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kIF kFINALLY kFOR kIN %token kINSTANCEOF kNEW kNULL kUNDEFINED kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH %token tANDAND tOROR tINC tDEC +%token kFUNCTION '}' + /* tokens */ %token tIdentifier %token tAssignOper tEqOper tShiftOper tRelOper @@ -257,12 +262,12 @@ SourceElements /* ECMA-262 3rd Edition 13 */ FunctionDeclaration : kFUNCTION tIdentifier '(' FormalParameterList_opt ')' '{' FunctionBody '}' - { $$ = new_function_declaration(ctx, $2, $4, $7); } + { $$ = new_function_declaration(ctx, $2, $4, $7, $1, $8-$1+1); } /* ECMA-262 3rd Edition 13 */ FunctionExpression : kFUNCTION Identifier_opt '(' FormalParameterList_opt ')' '{' FunctionBody '}' - { $$ = new_function_expression(ctx, $2, $4, $7); } + { $$ = new_function_expression(ctx, $2, $4, $7, $1, $8-$1+1); } /* ECMA-262 3rd Edition 13 */ FunctionBody @@ -725,7 +730,7 @@ ArrayLiteral : '[' Elision_opt ']' { $$ = new_array_literal_expression(ctx, NULL, $2); } | '[' ElementList ']' { $$ = new_array_literal_expression(ctx, $2, 0); } | '[' ElementList ',' Elision_opt ']' - { $$ = new_array_literal_expression(ctx, $2, $4); } + { $$ = new_array_literal_expression(ctx, $2, $4+1); } /* ECMA-262 3rd Edition 11.1.4 */ ElementList @@ -1247,7 +1252,7 @@ static parameter_list_t *parameter_list_add(parser_ctx_t *ctx, parameter_list_t } static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *identifier, - parameter_list_t *parameter_list, source_elements_t *source_elements) + parameter_list_t *parameter_list, source_elements_t *source_elements, const WCHAR *src_str, DWORD src_len) { function_expression_t *ret = parser_alloc(ctx, sizeof(function_expression_t)); @@ -1255,6 +1260,8 @@ static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *ide ret->identifier = identifier; ret->parameter_list = parameter_list ? parameter_list->head : NULL; ret->source_elements = source_elements; + ret->src_str = src_str; + ret->src_len = src_len; return &ret->expr; } @@ -1444,13 +1451,15 @@ static expression_t *new_literal_expression(parser_ctx_t *ctx, literal_t *litera } static function_declaration_t *new_function_declaration(parser_ctx_t *ctx, const WCHAR *identifier, - parameter_list_t *parameter_list, source_elements_t *source_elements) + parameter_list_t *parameter_list, source_elements_t *source_elements, const WCHAR *src_str, DWORD src_len) { function_declaration_t *ret = parser_alloc(ctx, sizeof(function_declaration_t)); ret->identifier = identifier; ret->parameter_list = parameter_list ? parameter_list->head : NULL; ret->source_elements = source_elements; + ret->src_str = src_str; + ret->src_len = src_len; ret->next = NULL; return ret; diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c index e8e9bea3618..e811e483eed 100644 --- a/dlls/jscript/regexp.c +++ b/dlls/jscript/regexp.c @@ -2571,7 +2571,7 @@ SimpleMatch(REGlobalData *gData, REMatchState *x, REOp op, if (!updatecp) x->cp = startcp; *startpc = pc; - TRACE(" * \n"); + TRACE(" *\n"); return result; } x->cp = startcp; @@ -3001,7 +3001,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x) }while(0) if (!result) { - TRACE(" - \n"); + TRACE(" -\n"); /* * Non-greedy failure - try to consume another child. */ @@ -3546,11 +3546,81 @@ static HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD return S_OK; } +static HRESULT regexp_constructor(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *retv) +{ + const WCHAR *opt = emptyW, *src; + DispatchEx *ret; + VARIANT *arg; + HRESULT hres; + + if(!arg_cnt(dp)) { + FIXME("no args\n"); + return E_NOTIMPL; + } + + arg = get_arg(dp,0); + if(V_VT(arg) == VT_DISPATCH) { + DispatchEx *obj; + + obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg)); + if(obj) { + if(is_class(obj, JSCLASS_REGEXP)) { + RegExpInstance *regexp = (RegExpInstance*)obj; + + hres = create_regexp(ctx, regexp->str, -1, regexp->jsregexp->flags, &ret); + jsdisp_release(obj); + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret); + return S_OK; + } + + jsdisp_release(obj); + } + } + + if(V_VT(arg) != VT_BSTR) { + FIXME("vt arg0 = %d\n", V_VT(arg)); + return E_NOTIMPL; + } + + src = V_BSTR(arg); + + if(arg_cnt(dp) >= 2) { + arg = get_arg(dp,1); + if(V_VT(arg) != VT_BSTR) { + FIXME("unimplemented for vt %d\n", V_VT(arg)); + return E_NOTIMPL; + } + + opt = V_BSTR(arg); + } + + hres = create_regexp_str(ctx, src, -1, opt, strlenW(opt), &ret); + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret); + return S_OK; +} + static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + TRACE("\n"); + + switch(flags) { + case DISPATCH_CONSTRUCT: + return regexp_constructor(dispex->ctx, dp, retv); + default: + FIXME("unimplemented flags: %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx **ret) diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index 12140d58603..1ceb80ae77c 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -88,18 +88,39 @@ static HRESULT String_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA return S_OK; } +/* ECMA-262 3rd Edition 15.5.4.2 */ static HRESULT String_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + StringInstance *string; + + TRACE("\n"); + + if(!is_class(dispex, JSCLASS_STRING)) { + WARN("this is not a string object\n"); + return E_FAIL; + } + + string = (StringInstance*)dispex; + + if(retv) { + BSTR str = SysAllocString(string->str); + if(!str) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = str; + } + return S_OK; } +/* ECMA-262 3rd Edition 15.5.4.2 */ static HRESULT String_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + TRACE("\n"); + + return String_toString(dispex, lcid, flags, dp, retv, ei, sp); } static HRESULT String_anchor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -178,18 +199,104 @@ static HRESULT String_charAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA return S_OK; } +/* ECMA-262 3rd Edition 15.5.4.5 */ static HRESULT String_charCodeAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + const WCHAR *str; + DWORD length, idx = 0; + HRESULT hres; + + TRACE("\n"); + + if(dispex->builtin_info->class == JSCLASS_STRING) { + StringInstance *string = (StringInstance*)dispex; + + str = string->str; + length = string->length; + }else { + FIXME("not string this not supported\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp) > 0) { + VARIANT v; + + hres = to_integer(dispex->ctx, get_arg(dp, 0), ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) != VT_I4 || V_I4(&v) < 0 || V_I4(&v) >= length) { + FIXME("NAN\n"); + return E_FAIL; + } + + idx = V_I4(&v); + } + + if(retv) { + V_VT(retv) = VT_I4; + V_I4(retv) = str[idx]; + } + return S_OK; } +/* ECMA-262 3rd Edition 15.5.4.6 */ static HRESULT String_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + BSTR *strs = NULL, ret = NULL; + DWORD len = 0, i, l, str_cnt; + VARIANT var; + WCHAR *ptr; + HRESULT hres; + + TRACE("\n"); + + str_cnt = arg_cnt(dp)+1; + strs = heap_alloc_zero(str_cnt * sizeof(BSTR)); + if(!strs) + return E_OUTOFMEMORY; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(dispex); + + hres = to_string(dispex->ctx, &var, ei, strs); + if(SUCCEEDED(hres)) { + for(i=0; i < arg_cnt(dp); i++) { + hres = to_string(dispex->ctx, get_arg(dp, i), ei, strs+i+1); + if(FAILED(hres)) + break; + } + } + + if(SUCCEEDED(hres)) { + for(i=0; i < str_cnt; i++) + len += SysStringLen(strs[i]); + + ptr = ret = SysAllocStringLen(NULL, len); + + for(i=0; i < str_cnt; i++) { + l = SysStringLen(strs[i]); + memcpy(ptr, strs[i], l*sizeof(WCHAR)); + ptr += l; + } + } + + for(i=0; i < str_cnt; i++) + SysFreeString(strs[i]); + heap_free(strs); + + if(FAILED(hres)) + return hres; + + if(retv) { + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + }else { + SysFreeString(ret); + } + return S_OK; } static HRESULT String_fixed(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -332,11 +439,82 @@ static HRESULT String_search(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.5.4.13 */ static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + const WCHAR *str; + DWORD length; + INT start=0, end; + VARIANT v; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_STRING)) { + StringInstance *string = (StringInstance*)dispex; + + str = string->str; + length = string->length; + }else { + FIXME("this is not a string class\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp)) { + hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) == VT_I4) { + start = V_I4(&v); + if(start < 0) { + start = length + start; + if(start < 0) + start = 0; + }else if(start > length) { + start = length; + } + }else { + start = V_R8(&v) < 0.0 ? 0 : length; + } + }else { + start = 0; + } + + if(arg_cnt(dp) >= 2) { + hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-2, ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) == VT_I4) { + end = V_I4(&v); + if(end < 0) { + end = length + end; + if(end < 0) + end = 0; + }else if(end > length) { + end = length; + } + }else { + end = V_R8(&v) < 0.0 ? 0 : length; + } + }else { + end = length; + } + + if(end < start) + end = start; + + if(retv) { + BSTR retstr = SysAllocStringLen(str+start, end-start); + if(!str) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = retstr; + } + return S_OK; } static HRESULT String_small(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -367,11 +545,75 @@ static HRESULT String_sub(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS return E_NOTIMPL; } +/* ECMA-262 3rd Edition 15.5.4.15 */ static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + const WCHAR *str; + INT start=0, end; + DWORD length; + VARIANT v; + HRESULT hres; + + TRACE("\n"); + + if(is_class(dispex, JSCLASS_STRING)) { + StringInstance *string = (StringInstance*)dispex; + + length = string->length; + str = string->str; + }else { + FIXME("not string this not supported\n"); + return E_NOTIMPL; + } + + if(arg_cnt(dp) >= 1) { + hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) == VT_I4) { + start = V_I4(&v); + if(start < 0) + start = 0; + else if(start >= length) + start = length; + }else { + start = V_R8(&v) < 0.0 ? 0 : length; + } + } + + if(arg_cnt(dp) >= 2) { + hres = to_integer(dispex->ctx, dp->rgvarg + dp->cArgs-2, ei, &v); + if(FAILED(hres)) + return hres; + + if(V_VT(&v) == VT_I4) { + end = V_I4(&v); + if(end < 0) + end = 0; + else if(end > length) + end = length; + }else { + end = V_R8(&v) < 0.0 ? 0 : length; + } + }else { + end = length; + } + + if(start > end) { + INT tmp = start; + start = end; + end = tmp; + } + + if(retv) { + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = SysAllocStringLen(str+start, end-start); + if(!V_BSTR(retv)) + return E_OUTOFMEMORY; + } + return S_OK; } static HRESULT String_substr(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, @@ -447,8 +689,26 @@ static HRESULT String_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, D static HRESULT String_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + StringInstance *This = (StringInstance*)dispex; + + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + BSTR str = SysAllocString(This->str); + if(!str) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = str; + break; + } + default: + FIXME("flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } static void String_destructor(DispatchEx *dispex) @@ -510,8 +770,58 @@ static const builtin_info_t String_info = { static HRESULT StringConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + HRESULT hres; + + TRACE("\n"); + + switch(flags) { + case INVOKE_FUNC: { + BSTR str; + + if(arg_cnt(dp)) { + hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &str); + if(FAILED(hres)) + return hres; + }else { + str = SysAllocStringLen(NULL, 0); + if(!str) + return E_OUTOFMEMORY; + } + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = str; + break; + } + case DISPATCH_CONSTRUCT: { + DispatchEx *ret; + + if(arg_cnt(dp)) { + BSTR str; + + hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &str); + if(FAILED(hres)) + return hres; + + hres = create_string(dispex->ctx, str, SysStringLen(str), &ret); + SysFreeString(str); + }else { + hres = create_string(dispex->ctx, NULL, 0, &ret); + } + + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret); + break; + } + + default: + FIXME("unimplemented flags: %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; } static HRESULT string_alloc(script_ctx_t *ctx, BOOL use_constr, StringInstance **ret) diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 45765edf44b..93f06b95a6d 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -16,13 +16,70 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -var tmp; +var tmp, i; + +i = parseInt("0"); +ok(i === 0, "parseInt('0') = " + i); +i = parseInt("123"); +ok(i === 123, "parseInt('123') = " + i); +i = parseInt("-123"); +ok(i === -123, "parseInt('-123') = " + i); +i = parseInt("0xff"); +ok(i === 0xff, "parseInt('0xff') = " + i); +i = parseInt("11", 8); +ok(i === 9, "parseInt('11', 8) = " + i); +i = parseInt("1j", 22); +ok(i === 41, "parseInt('1j', 32) = " + i); +i = parseInt("123", 0); +ok(i === 123, "parseInt('123', 0) = " + i); +i = parseInt("123", 10, "test"); +ok(i === 123, "parseInt('123', 10, 'test') = " + i); +i = parseInt("11", "8"); +ok(i === 9, "parseInt('11', '8') = " + i); + +tmp = "" + new Object(); +ok(tmp === "[object Object]", "'' + new Object() = " + tmp); ok("".length === 0, "\"\".length = " + "".length); ok(getVT("".length) == "VT_I4", "\"\".length = " + "".length); ok("abc".length === 3, "\"abc\".length = " + "abc".length); ok(String.prototype.length === 0, "String.prototype.length = " + String.prototype.length); +tmp = "".toString(); +ok(tmp === "", "''.toString() = " + tmp); +tmp = "test".toString(); +ok(tmp === "test", "''.toString() = " + tmp); +tmp = "test".toString(3); +ok(tmp === "test", "''.toString(3) = " + tmp); + +tmp = "".valueOf(); +ok(tmp === "", "''.valueOf() = " + tmp); +tmp = "test".valueOf(); +ok(tmp === "test", "''.valueOf() = " + tmp); +tmp = "test".valueOf(3); +ok(tmp === "test", "''.valueOf(3) = " + tmp); + +var str = new String("test"); +ok(str.toString() === "test", "str.toString() = " + str.toString()); +var str = new String(); +ok(str.toString() === "", "str.toString() = " + str.toString()); +var str = new String("test", "abc"); +ok(str.toString() === "test", "str.toString() = " + str.toString()); + +tmp = "value " + str; +ok(tmp === "value test", "'value ' + str = " + tmp); + +tmp = String(); +ok(tmp === "", "String() = " + tmp); +tmp = String(false); +ok(tmp === "false", "String(false) = " + tmp); +tmp = String(null); +ok(tmp === "null", "String(null) = " + tmp); +tmp = String("test"); +ok(tmp === "test", "String('test') = " + tmp); +tmp = String("test", "abc"); +ok(tmp === "test", "String('test','abc') = " + tmp); + tmp = "abc".charAt(0); ok(tmp === "a", "'abc',charAt(0) = " + tmp); tmp = "abc".charAt(1); @@ -40,6 +97,60 @@ ok(tmp === "", "'abc',charAt(-1) = " + tmp); tmp = "abc".charAt(0,2); ok(tmp === "a", "'abc',charAt(0.2) = " + tmp); +tmp = "abc".charCodeAt(0); +ok(tmp === 0x61, "'abc'.charCodeAt(0) = " + tmp); +tmp = "abc".charCodeAt(1); +ok(tmp === 0x62, "'abc'.charCodeAt(1) = " + tmp); +tmp = "abc".charCodeAt(2); +ok(tmp === 0x63, "'abc'.charCodeAt(2) = " + tmp); +tmp = "abc".charCodeAt(); +ok(tmp === 0x61, "'abc'.charCodeAt() = " + tmp); +tmp = "abc".charCodeAt(true); +ok(tmp === 0x62, "'abc'.charCodeAt(true) = " + tmp); +tmp = "abc".charCodeAt(0,2); +ok(tmp === 0x61, "'abc'.charCodeAt(0,2) = " + tmp); + +tmp = "abcd".substring(1,3); +ok(tmp === "bc", "'abcd'.substring(1,3) = " + tmp); +tmp = "abcd".substring(-1,3); +ok(tmp === "abc", "'abcd'.substring(-1,3) = " + tmp); +tmp = "abcd".substring(1,6); +ok(tmp === "bcd", "'abcd'.substring(1,6) = " + tmp); +tmp = "abcd".substring(3,1); +ok(tmp === "bc", "'abcd'.substring(3,1) = " + tmp); +tmp = "abcd".substring(2,2); +ok(tmp === "", "'abcd'.substring(2,2) = " + tmp); +tmp = "abcd".substring(true,"3"); +ok(tmp === "bc", "'abcd'.substring(true,'3') = " + tmp); +tmp = "abcd".substring(1,3,2); +ok(tmp === "bc", "'abcd'.substring(1,3,2) = " + tmp); +tmp = "abcd".substring(); +ok(tmp === "abcd", "'abcd'.substring() = " + tmp); + +tmp = "abcd".slice(1,3); +ok(tmp === "bc", "'abcd'.slice(1,3) = " + tmp); +tmp = "abcd".slice(1,-1); +ok(tmp === "bc", "'abcd'.slice(1,-1) = " + tmp); +tmp = "abcd".slice(-3,3); +ok(tmp === "bc", "'abcd'.slice(-3,3) = " + tmp); +tmp = "abcd".slice(-6,3); +ok(tmp === "abc", "'abcd'.slice(-6,3) = " + tmp); +tmp = "abcd".slice(3,1); +ok(tmp === "", "'abcd'.slice(3,1) = " + tmp); +tmp = "abcd".slice(true,3); +ok(tmp === "bc", "'abcd'.slice(true,3) = " + tmp); +tmp = "abcd".slice(); +ok(tmp === "abcd", "'abcd'.slice() = " + tmp); +tmp = "abcd".slice(1); +ok(tmp === "bcd", "'abcd'.slice(1) = " + tmp); + +tmp = "abc".concat(["d",1],2,false); +ok(tmp === "abcd,12false", "concat returned " + tmp); +var arr = new Array(2,"a"); +arr.concat = String.prototype.concat; +tmp = arr.concat("d"); +ok(tmp === "2,ad", "arr.concat = " + tmp); + var arr = new Array(); ok(typeof(arr) === "object", "arr () is not object"); ok((arr.length === 0), "arr.length is not 0"); @@ -55,9 +166,171 @@ ok(arr["2"] === "test", "arr[2] is not \"test\""); arr["7"] = true; ok((arr.length === 8), "arr.length is not 8"); +tmp = "" + []; +ok(tmp === "", "'' + [] = " + tmp); +tmp = "" + [1,true]; +ok(tmp === "1,true", "'' + [1,true] = " + tmp); + var arr = new Array(6); ok(typeof(arr) === "object", "arr (6) is not object"); ok((arr.length === 6), "arr.length is not 6"); ok(arr["0"] === undefined, "arr[0] is not undefined"); +ok(arr.push() === 6, "arr.push() !== 6"); +ok(arr.push(1) === 7, "arr.push(1) !== 7"); +ok(arr[6] === 1, "arr[6] != 1"); +ok(arr.length === 7, "arr.length != 10"); +ok(arr.push(true, 'b', false) === 10, "arr.push(true, 'b', false) !== 10"); +ok(arr[8] === "b", "arr[8] != 'b'"); +ok(arr.length === 10, "arr.length != 10"); + +arr = [1,2,null,false,undefined,,"a"]; + +tmp = arr.join(); +ok(tmp === "1,2,,false,,,a", "arr.join() = " + tmp); +tmp = arr.join(";"); +ok(tmp === "1;2;;false;;;a", "arr.join(';') = " + tmp); +tmp = arr.join(";","test"); +ok(tmp === "1;2;;false;;;a", "arr.join(';') = " + tmp); +tmp = arr.join(""); +ok(tmp === "12falsea", "arr.join('') = " + tmp); + +tmp = arr.toString(); +ok(tmp === "1,2,,false,,,a", "arr.toString() = " + tmp); +tmp = arr.toString("test"); +ok(tmp === "1,2,,false,,,a", "arr.toString() = " + tmp); + +arr = [5,true,2,-1,3,false,"2.5"]; +tmp = arr.sort(function(x,y) { return y-x; }); +ok(tmp === arr, "tmp !== arr"); +tmp = [5,3,"2.5",2,true,false,-1]; +for(var i=0; i < arr.length; i++) + ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]); + +arr = [5,false,2,0,"abc",3,"a",-1]; +tmp = arr.sort(); +ok(tmp === arr, "tmp !== arr"); +tmp = [-1,0,2,3,5,"a","abc",false]; +for(var i=0; i < arr.length; i++) + ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]); + +arr = ["a", "b", "ab"]; +tmp = ["a", "ab", "b"]; +ok(arr.sort() === arr, "arr.sort() !== arr"); +for(var i=0; i < arr.length; i++) + ok(arr[i] === tmp[i], "arr[" + i + "] = " + arr[i] + " expected " + tmp[i]); + +var num = new Number(6); +arr = [0,1,2]; +tmp = arr.concat(3, [4,5], num); +ok(tmp !== arr, "tmp === arr"); +for(var i=0; i<6; i++) + ok(tmp[i] === i, "tmp[" + i + "] = " + tmp[i]); +ok(tmp[6] === num, "tmp[6] !== num"); +ok(tmp.length === 7, "tmp.length = " + tmp.length); + +arr = [].concat(); +ok(arr.length === 0, "arr.length = " + arr.lrngth); + +arr = [1,]; +tmp = arr.concat([2]); +ok(tmp.length === 3, "tmp.length = " + tmp.length); +ok(tmp[1] === undefined, "tmp[1] = " + tmp[1]); + +var num = new Number(2); +ok(num.toString() === "2", "num(2).toString !== 2"); +var num = new Number(); +ok(num.toString() === "0", "num().toString !== 0"); + +ok(Number() === 0, "Number() = " + Number()); +ok(Number(false) === 0, "Number(false) = " + Number(false)); +ok(Number("43") === 43, "Number('43') = " + Number("43")); + +tmp = Math.min(1); +ok(tmp === 1, "Math.min(1) = " + tmp); + +tmp = Math.min(1, false); +ok(tmp === 0, "Math.min(1, false) = " + tmp); + +tmp = Math.min(1, false, true, null, -3); +ok(tmp === -3, "Math.min(1, false, true, null, -3) = " + tmp); + +tmp = Math.max(1); +ok(tmp === 1, "Math.max(1) = " + tmp); + +tmp = Math.max(true, 0); +ok(tmp === 1, "Math.max(true, 0) = " + tmp); + +tmp = Math.max(-2, false, true, null, 1); +ok(tmp === 1, "Math.max(-2, false, true, null, 1) = " + tmp); + +tmp = Math.round(0.5); +ok(tmp === 1, "Math.round(0.5) = " + tmp); + +tmp = Math.round(-0.5); +ok(tmp === 0, "Math.round(-0.5) = " + tmp); + +tmp = Math.round(1.1); +ok(tmp === 1, "Math.round(1.1) = " + tmp); + +tmp = Math.round(true); +ok(tmp === 1, "Math.round(true) = " + tmp); + +tmp = Math.round(1.1, 3, 4); +ok(tmp === 1, "Math.round(1.1, 3, 4) = " + tmp); + +tmp = Math.ceil(0.5); +ok(tmp === 1, "Math.ceil(0.5) = " + tmp); + +tmp = Math.ceil(-0.5); +ok(tmp === 0, "Math.ceil(-0.5) = " + tmp); + +tmp = Math.ceil(1.1); +ok(tmp === 2, "Math.round(1.1) = " + tmp); + +tmp = Math.ceil(true); +ok(tmp === 1, "Math.ceil(true) = " + tmp); + +tmp = Math.ceil(1.1, 3, 4); +ok(tmp === 2, "Math.ceil(1.1, 3, 4) = " + tmp); + +tmp = Math.abs(3); +ok(tmp === 3, "Math.abs(3) = " + tmp); + +tmp = Math.abs(-3); +ok(tmp === 3, "Math.abs(-3) = " + tmp); + +tmp = Math.abs(true); +ok(tmp === 1, "Math.abs(true) = " + tmp); + +tmp = Math.abs(-3, 2); +ok(tmp === 3, "Math.abs(-3, 2) = " + tmp); + +tmp = Math.pow(2, 2); +ok(tmp === 4, "Math.pow(2, 2) = " + tmp); + +tmp = Math.pow(4, 0.5); +ok(tmp === 2, "Math.pow(2, 2) = " + tmp); + +tmp = Math.pow(2, 2, 3); +ok(tmp === 4, "Math.pow(2, 2, 3) = " + tmp); + +var func = function (a) { + var a = 1; + if(a) return; + }.toString(); +ok(func.toString() === "function (a) {\n var a = 1;\n if(a) return;\n }", + "func.toString() = " + func.toString()); +ok("" + func === "function (a) {\n var a = 1;\n if(a) return;\n }", + "'' + func.toString() = " + func); + +function testFuncToString(x,y) { + return x+y; +} + +ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n return x+y;\n}", + "testFuncToString.toString() = " + testFuncToString.toString()); +ok("" + testFuncToString === "function testFuncToString(x,y) {\n return x+y;\n}", + "'' + testFuncToString = " + testFuncToString); + reportSuccess(); diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 83732a2721b..dbe714d9fb3 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -142,6 +142,15 @@ ok(obj2.pvar === 3, "obj2.pvar is not 3"); var obj3 = new Object; ok(typeof(obj3) === "object", "typeof(obj3) is not object"); +for(var iter in "test") + ok(false, "unexpected forin call, test = " + iter); + +for(var iter in null) + ok(false, "unexpected forin call, test = " + iter); + +for(var iter in false) + ok(false, "unexpected forin call, test = " + iter); + tmp = 0; if(true) tmp = 1; @@ -344,6 +353,11 @@ ok(+3 === 3, "+3 !== 3"); ok(+true === 1, "+true !== 1"); ok(+false === 0, "+false !== 0"); ok(+null === 0, "+null !== 0"); +ok(+"0" === 0, "+'0' !== 0"); +ok(+"3" === 3, "+'3' !== 3"); +ok(+"-3" === -3, "+'-3' !== -3"); +ok(+"0xff" === 255, "+'0xff' !== 255"); +ok(+"3e3" === 3000, "+'3e3' !== 3000"); ok("" + 0 === "0", "\"\" + 0 !== \"0\""); ok("" + 123 === "123", "\"\" + 123 !== \"123\""); @@ -587,6 +601,8 @@ ok(tmp["3"] === 2, "tmp[3] !== 2"); ok(tmp["6"] === true, "tmp[6] !== true"); ok(tmp[2] === 1, "tmp[2] !== 1"); +ok([1,].length === 2, "[1,].length !== 2"); + tmp = 0; while(tmp < 4) { ok(tmp < 4, "tmp >= 4"); @@ -617,7 +633,7 @@ do { ok(tmp === 0, "tmp !=== 0"); tmp++; } while(false); -ok(tmp === 1, "tmp !== 4"); +ok(tmp === 1, "tmp !== 1"); tmp = 0; while(tmp < 4) { diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js index 209ee22b0fb..13ce8a20203 100644 --- a/dlls/jscript/tests/regexp.js +++ b/dlls/jscript/tests/regexp.js @@ -51,4 +51,28 @@ ok(m.length === 2, "m.length is not 1"); ok(m["0"] === "aaab", "m[0] is not \"ab\""); ok(m["1"] === "ab", "m[1] is not \"ab\""); +m = "abcabc".match(new RegExp("ab")); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 1, "m.length is not 1"); +ok(m["0"] === "ab", "m[0] is not \"ab\""); + +/* +m = "abcabc".match(new RegExp("ab","g")); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 2, "m.length is not 1"); +ok(m["0"] === "ab", "m[0] is not \"ab\""); +ok(m["1"] === "ab", "m[1] is not \"ab\""); + +m = "abcabc".match(new RegExp(/ab/g)); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 2, "m.length is not 1"); +ok(m["0"] === "ab", "m[0] is not \"ab\""); +ok(m["1"] === "ab", "m[1] is not \"ab\""); + +m = "abcabc".match(new RegExp("ab","g", "test")); +ok(typeof(m) === "object", "typeof m is not object"); +ok(m.length === 2, "m.length is not 1"); +ok(m["0"] === "ab", "m[0] is not \"ab\""); +ok(m["1"] === "ab", "m[1] is not \"ab\""); +*/ reportSuccess(); diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c index ab26533db35..3ed2dcddeaf 100644 --- a/dlls/kernel32/profile.c +++ b/dlls/kernel32/profile.c @@ -405,6 +405,7 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding) { szLineStart = next_line; next_line = memchrW(szLineStart, '\n', szEnd - szLineStart); + if (!next_line) next_line = memchrW(szLineStart, '\r', szEnd - szLineStart); if (!next_line) next_line = szEnd; else next_line++; szLineEnd = next_line; diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 1686a4a82c9..76665a8c4dc 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -1512,6 +1512,8 @@ static void test_FindFirstFileExA(void) ok(FindNextFile(handle, &search_results) == FALSE, "Fetching sixth file should failed\n"); + FindClose( handle ); + cleanup: DeleteFileA("test-dir\\file1"); DeleteFileA("test-dir\\file2"); @@ -1560,12 +1562,16 @@ static void test_MapFile(void) ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n"); hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL ); - ok( hmap == NULL, "mapping should fail\n"); + ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n"); /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */ + if ( hmap ) + CloseHandle( hmap ); hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL ); - ok( hmap == NULL, "mapping should fail\n"); + ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n"); /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */ + if ( hmap ) + CloseHandle( hmap ); /* On XP you can now map again, on Win 95 you cannot. */ diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 37f4c928da9..59588f81892 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -526,7 +526,7 @@ static void test_ImportDescriptors(void) LPCSTR module_name = (LPCSTR) RVAToAddr( import_chunk->Name, kernel32_module); PIMAGE_THUNK_DATA name_table = (PIMAGE_THUNK_DATA) RVAToAddr( - import_chunk->OriginalFirstThunk, kernel32_module); + U(*import_chunk).OriginalFirstThunk, kernel32_module); PIMAGE_THUNK_DATA iat = (PIMAGE_THUNK_DATA) RVAToAddr( import_chunk->FirstThunk, kernel32_module); ok(module_name != NULL, "Imported module name should not be NULL\n"); diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c index b076a6702a1..73d7946cdd6 100644 --- a/dlls/kernel32/tests/module.c +++ b/dlls/kernel32/tests/module.c @@ -343,7 +343,7 @@ START_TEST(module) GetModuleFileNameW(NULL, filenameW, MAX_PATH); if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { - trace("GetModuleFileNameW not existing on this platform, skipping W-calls\n"); + win_skip("GetModuleFileNameW not existing on this platform, skipping W-calls\n"); is_unicode_enabled = FALSE; } diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c index d158df1dbcc..e8e6c1e1ce1 100644 --- a/dlls/kernel32/tests/path.c +++ b/dlls/kernel32/tests/path.c @@ -465,6 +465,14 @@ static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir) /* starting with a '.' */ sprintf(tmpstr,".\\%s",LONGDIR); test_setdir(newdir,tmpstr,tmpstr1,1,"check 9"); +/* change to root without a trailing backslash. The function call succeeds + but the directory is not changed. +*/ + strcpy(tmpstr,"C:"); + test_setdir(newdir,tmpstr,newdir,1,"check 10"); +/* works however with a trailing backslash */ + strcpy(tmpstr,"C:\\"); + test_setdir(newdir,tmpstr,NULL,1,"check 11"); } /* Cleanup the mess we made while executing these tests */ diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 3e9e0e726ff..4531c9fd60e 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -348,8 +348,18 @@ static void doChild(const char* file, const char* option) childPrintf(hFile, "OutputMode=%ld\n", modeOut); /* now that we have written all relevant information, let's change it */ - ok(SetConsoleCP(1252), "Setting CP\n"); - ok(SetConsoleOutputCP(1252), "Setting SB CP\n"); + SetLastError(0xdeadbeef); + ret = SetConsoleCP(1252); + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("Setting the codepage is not implemented"); + } + else + { + ok(ret, "Setting CP\n"); + ok(SetConsoleOutputCP(1252), "Setting SB CP\n"); + } + ret = SetConsoleMode(hConIn, modeIn ^ 1); ok( ret, "Setting mode (%d)\n", GetLastError()); ret = SetConsoleMode(hConOut, modeOut ^ 1); @@ -1125,6 +1135,7 @@ static void test_Console(void) HANDLE hChildIn, hChildInInh, hChildOut, hChildOutInh, hParentIn, hParentOut; const char* msg = "This is a std-handle inheritance test."; unsigned msg_len; + BOOL run_tests = TRUE; memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); @@ -1181,14 +1192,17 @@ static void test_Console(void) SetLastError(0xdeadbeef); ok(!SetConsoleCP(0), "Shouldn't succeed\n"); ok(GetLastError()==ERROR_INVALID_PARAMETER || - broken(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), /* win95 */ + broken(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), /* win9x */ "GetLastError: expecting %u got %u\n", ERROR_INVALID_PARAMETER, GetLastError()); + if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + run_tests = FALSE; + SetLastError(0xdeadbeef); ok(!SetConsoleOutputCP(0), "Shouldn't succeed\n"); ok(GetLastError()==ERROR_INVALID_PARAMETER || - broken(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), /* win95 */ + broken(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), /* win9x */ "GetLastError: expecting %u got %u\n", ERROR_INVALID_PARAMETER, GetLastError()); @@ -1231,8 +1245,14 @@ static void test_Console(void) okChildInt("Console", "InputMode", modeIn); okChildInt("Console", "OutputMode", modeOut); - ok(cpInC == 1252, "Wrong console CP (expected 1252 got %d/%d)\n", cpInC, cpIn); - ok(cpOutC == 1252, "Wrong console-SB CP (expected 1252 got %d/%d)\n", cpOutC, cpOut); + if (run_tests) + { + ok(cpInC == 1252, "Wrong console CP (expected 1252 got %d/%d)\n", cpInC, cpIn); + ok(cpOutC == 1252, "Wrong console-SB CP (expected 1252 got %d/%d)\n", cpOutC, cpOut); + } + else + win_skip("Setting the codepage is not implemented"); + ok(modeInC == (modeIn ^ 1), "Wrong console mode\n"); ok(modeOutC == (modeOut ^ 1), "Wrong console-SB mode\n"); trace("cursor position(X): %d/%d\n",sbi.dwCursorPosition.X, sbiC.dwCursorPosition.X); diff --git a/dlls/kernel32/tests/profile.c b/dlls/kernel32/tests/profile.c index 8a3e83bbd20..2a9f08a6ca2 100644 --- a/dlls/kernel32/tests/profile.c +++ b/dlls/kernel32/tests/profile.c @@ -428,7 +428,7 @@ static BOOL emptystr_ok(CHAR emptystr[MAX_PATH]) return TRUE; } -static void test_GetPrivateProfileString(void) +static void test_GetPrivateProfileString(const char *content, const char *descript) { DWORD ret; CHAR buf[MAX_PATH]; @@ -441,15 +441,10 @@ static void test_GetPrivateProfileString(void) LPSTR tempfile; static const char filename[] = ".\\winetest.ini"; - static const char content[]= - "[section1]\r\n" - "name1=val1\r\n" - "name2=\"val2\"\r\n" - "name3\r\n" - "name4=a\r\n" - "[section2]\r\n"; - create_test_file(filename, content, sizeof(content)); + trace("test_GetPrivateProfileStringA: %s\n", descript); + + create_test_file(filename, content, lstrlenA(content)); /* Run this test series with caching. Wine won't cache profile files younger than 2.1 seconds. */ @@ -674,7 +669,7 @@ static void test_GetPrivateProfileString(void) GetWindowsDirectoryA(windir, MAX_PATH); GetTempFileNameA(windir, "pre", 0, path); tempfile = strrchr(path, '\\') + 1; - create_test_file(path, content, sizeof(content)); + create_test_file(path, content, lstrlenA(content)); /* only filename is used, file exists in windows directory */ lstrcpyA(buf, "kumquat"); @@ -703,5 +698,20 @@ START_TEST(profile) test_profile_existing(); test_profile_delete_on_close(); test_profile_refresh(); - test_GetPrivateProfileString(); + test_GetPrivateProfileString( + "[section1]\r\n" + "name1=val1\r\n" + "name2=\"val2\"\r\n" + "name3\r\n" + "name4=a\r\n" + "[section2]\r\n", + "CR+LF"); + test_GetPrivateProfileString( + "[section1]\r" + "name1=val1\r" + "name2=\"val2\"\r" + "name3\r" + "name4=a\r" + "[section2]\r", + "CR only"); } diff --git a/dlls/mscms/mscms_priv.h b/dlls/mscms/mscms_priv.h index c979ea85fef..479148bee80 100644 --- a/dlls/mscms/mscms_priv.h +++ b/dlls/mscms/mscms_priv.h @@ -44,6 +44,7 @@ #undef CopyMemory #undef LOWORD +#undef HIWORD #undef MAX_PATH #ifdef HAVE_LCMS_LCMS_H diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 587d9530581..e176711ba62 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -463,18 +463,37 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW } if(grfdex & fdexNameEnsure) { + dispex_dynamic_data_t *dynamic_data; + TRACE("creating dynamic prop %s\n", debugstr_w(bstrName)); - if(!This->dynamic_data) { - This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)); - This->dynamic_data->props = heap_alloc(This->dynamic_data->buf_size = 4); - }else if(This->dynamic_data->buf_size == This->dynamic_data->prop_cnt) { - This->dynamic_data->props = heap_realloc(This->dynamic_data->props, This->dynamic_data->buf_size<<=1); + if(This->dynamic_data) { + dynamic_data = This->dynamic_data; + }else { + dynamic_data = This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)); + if(!dynamic_data) + return E_OUTOFMEMORY; + } + + if(!dynamic_data->buf_size) { + dynamic_data->props = heap_alloc(sizeof(dynamic_prop_t)*4); + if(!dynamic_data->props) + return E_OUTOFMEMORY; + dynamic_data->buf_size = 4; + }else if(dynamic_data->buf_size == dynamic_data->prop_cnt) { + dynamic_prop_t *new_props; + + new_props = heap_realloc(dynamic_data->props, sizeof(dynamic_prop_t)*(dynamic_data->buf_size<<1)); + if(!new_props) + return E_OUTOFMEMORY; + + dynamic_data->props = new_props; + dynamic_data->buf_size <<= 1; } - This->dynamic_data->props[This->dynamic_data->prop_cnt].name = heap_strdupW(bstrName); - VariantInit(&This->dynamic_data->props[This->dynamic_data->prop_cnt].var); - *pid = DISPID_DYNPROP_0 + This->dynamic_data->prop_cnt++; + dynamic_data->props[dynamic_data->prop_cnt].name = heap_strdupW(bstrName); + VariantInit(&dynamic_data->props[dynamic_data->prop_cnt].var); + *pid = DISPID_DYNPROP_0 + dynamic_data->prop_cnt++; return S_OK; } diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c index 9fad1874ca7..e5545f56007 100644 --- a/dlls/mshtml/htmlbody.c +++ b/dlls/mshtml/htmlbody.c @@ -140,8 +140,23 @@ static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dis static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v) { HTMLBodyElement *This = HTMLBODY_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + HRESULT hr = S_OK; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_Init(&nsstr, v); + + nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr); + if(!NS_SUCCEEDED(nsres)) + { + hr = E_FAIL; + } + + nsAString_Finish(&nsstr); + + return hr; } static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p) diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index a2e34397b06..78e9c9be5af 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -1615,25 +1615,21 @@ static HRESULT WINAPI HTMLElementCollection_GetTypeInfoCount(IHTMLElementCollect UINT *pctinfo) { HTMLElementCollection *This = ELEMCOL_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); } static HRESULT WINAPI HTMLElementCollection_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLElementCollection *This = ELEMCOL_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLElementCollection_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { HTMLElementCollection *This = ELEMCOL_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLElementCollection_Invoke(IHTMLElementCollection *iface, @@ -1641,9 +1637,8 @@ static HRESULT WINAPI HTMLElementCollection_Invoke(IHTMLElementCollection *iface VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLElementCollection *This = ELEMCOL_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLElementCollection_toString(IHTMLElementCollection *iface, diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 7c03a9647fa..e9237950985 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -102,25 +102,21 @@ static ULONG WINAPI HTMLDOMChildrenCollection_Release(IHTMLDOMChildrenCollection static HRESULT WINAPI HTMLDOMChildrenCollection_GetTypeInfoCount(IHTMLDOMChildrenCollection *iface, UINT *pctinfo) { HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); } static HRESULT WINAPI HTMLDOMChildrenCollection_GetTypeInfo(IHTMLDOMChildrenCollection *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDOMChildrenCollection_GetIDsOfNames(IHTMLDOMChildrenCollection *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDOMChildrenCollection_Invoke(IHTMLDOMChildrenCollection *iface, DISPID dispIdMember, @@ -128,9 +124,8 @@ static HRESULT WINAPI HTMLDOMChildrenCollection_Invoke(IHTMLDOMChildrenCollectio VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDOMChildrenCollection_get_length(IHTMLDOMChildrenCollection *iface, long *p) @@ -315,16 +310,14 @@ static ULONG WINAPI HTMLDOMNode_Release(IHTMLDOMNode *iface) static HRESULT WINAPI HTMLDOMNode_GetTypeInfoCount(IHTMLDOMNode *iface, UINT *pctinfo) { HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); } static HRESULT WINAPI HTMLDOMNode_GetTypeInfo(IHTMLDOMNode *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDOMNode_GetIDsOfNames(IHTMLDOMNode *iface, REFIID riid, @@ -332,9 +325,7 @@ static HRESULT WINAPI HTMLDOMNode_GetIDsOfNames(IHTMLDOMNode *iface, REFIID riid LCID lcid, DISPID *rgDispId) { HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDOMNode_Invoke(IHTMLDOMNode *iface, DISPID dispIdMember, @@ -342,9 +333,8 @@ static HRESULT WINAPI HTMLDOMNode_Invoke(IHTMLDOMNode *iface, DISPID dispIdMembe VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDOMNode_get_nodeType(IHTMLDOMNode *iface, long *p) @@ -739,16 +729,14 @@ static ULONG WINAPI HTMLDOMNode2_Release(IHTMLDOMNode2 *iface) static HRESULT WINAPI HTMLDOMNode2_GetTypeInfoCount(IHTMLDOMNode2 *iface, UINT *pctinfo) { HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); } static HRESULT WINAPI HTMLDOMNode2_GetTypeInfo(IHTMLDOMNode2 *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDOMNode2_GetIDsOfNames(IHTMLDOMNode2 *iface, REFIID riid, @@ -756,9 +744,7 @@ static HRESULT WINAPI HTMLDOMNode2_GetIDsOfNames(IHTMLDOMNode2 *iface, REFIID ri LCID lcid, DISPID *rgDispId) { HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDOMNode2_Invoke(IHTMLDOMNode2 *iface, DISPID dispIdMember, @@ -766,9 +752,8 @@ static HRESULT WINAPI HTMLDOMNode2_Invoke(IHTMLDOMNode2 *iface, DISPID dispIdMem VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDOMNode *This = HTMLDOMNODE2_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDOMNode2_get_ownerDocument(IHTMLDOMNode2 *iface, IDispatch **p) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 56c5057e77d..7d3b3e38157 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -87,12 +87,12 @@ typedef enum { ET_IMG } elem_type_t; -static REFIID const none_iids[] = { +static const IID * const none_iids[] = { &IID_IUnknown, NULL }; -static REFIID const elem_iids[] = { +static const IID * const elem_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -102,7 +102,7 @@ static REFIID const elem_iids[] = { NULL }; -static REFIID const body_iids[] = { +static const IID * const body_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -114,7 +114,7 @@ static REFIID const body_iids[] = { NULL }; -static REFIID const anchor_iids[] = { +static const IID * const anchor_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -125,7 +125,7 @@ static REFIID const anchor_iids[] = { NULL }; -static REFIID const input_iids[] = { +static const IID * const input_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -137,7 +137,7 @@ static REFIID const input_iids[] = { NULL }; -static REFIID const select_iids[] = { +static const IID * const select_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -148,7 +148,7 @@ static REFIID const select_iids[] = { NULL }; -static REFIID const textarea_iids[] = { +static const IID * const textarea_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -159,7 +159,7 @@ static REFIID const textarea_iids[] = { NULL }; -static REFIID const option_iids[] = { +static const IID * const option_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -170,7 +170,7 @@ static REFIID const option_iids[] = { NULL }; -static REFIID const table_iids[] = { +static const IID * const table_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -181,7 +181,7 @@ static REFIID const table_iids[] = { NULL }; -static REFIID const script_iids[] = { +static const IID * const script_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -192,20 +192,20 @@ static REFIID const script_iids[] = { NULL }; -static REFIID const text_iids[] = { +static const IID * const text_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLDOMTextNode, NULL }; -static REFIID const location_iids[] = { +static const IID * const location_iids[] = { &IID_IDispatch, &IID_IHTMLLocation, NULL }; -static REFIID const window_iids[] = { +static const IID * const window_iids[] = { &IID_IDispatch, &IID_IHTMLWindow2, &IID_IHTMLWindow3, @@ -213,7 +213,7 @@ static REFIID const window_iids[] = { NULL }; -static REFIID const comment_iids[] = { +static const IID * const comment_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -224,7 +224,7 @@ static REFIID const comment_iids[] = { NULL }; -static REFIID const img_iids[] = { +static const IID * const img_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, @@ -235,7 +235,7 @@ static REFIID const img_iids[] = { NULL }; -static REFIID const generic_iids[] = { +static const IID * const generic_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, &IID_IHTMLElement, diff --git a/dlls/msi/automation.c b/dlls/msi/automation.c index c15126aed27..60224b64df9 100644 --- a/dlls/msi/automation.c +++ b/dlls/msi/automation.c @@ -441,7 +441,7 @@ static HRESULT WINAPI AutomationObject_Invoke( if (pVarResult == &varResultDummy) VariantClear(pVarResult); /* Free function name if we retrieved it */ - if (bstrName) SysFreeString(bstrName); + SysFreeString(bstrName); TRACE("Returning 0x%08x, %s\n", hr, SUCCEEDED(hr) ? "ok" : "not ok"); diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index 0a28c595c4f..5859adf832d 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -990,7 +990,7 @@ void CDECL _searchenv(const char* file, const char* env, char *buf) return; } memcpy(curPath, penv, end - penv); - if (curPath[end - penv] != '/' || curPath[end - penv] != '\\') + if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') { curPath[end - penv] = '\\'; curPath[end - penv + 1] = '\0'; @@ -1053,7 +1053,7 @@ void CDECL _wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* env, MS return; } memcpy(curPath, penv, (end - penv) * sizeof(MSVCRT_wchar_t)); - if (curPath[end - penv] != '/' || curPath[end - penv] != '\\') + if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') { curPath[end - penv] = '\\'; curPath[end - penv + 1] = '\0'; diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 644743672c6..350e05776cc 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -189,7 +189,8 @@ find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LO res->match_flags = flags; res->found_lang_id = LangID; } - if (flags & (FOUND_LANGUAGE & FOUND_COUNTRY & FOUND_CODEPAGE)) + if ((flags & (FOUND_LANGUAGE | FOUND_COUNTRY | FOUND_CODEPAGE)) == + (FOUND_LANGUAGE | FOUND_COUNTRY | FOUND_CODEPAGE)) { TRACE(":found exact locale match\n"); return STOP_LOOKING; diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c index 87a29f47a3b..9dbc43edb34 100644 --- a/dlls/msvcrt/process.c +++ b/dlls/msvcrt/process.c @@ -96,7 +96,7 @@ static void msvcrt_search_executable(const MSVCRT_wchar_t *name, MSVCRT_wchar_t if (path_len + name_len <= MAX_PATH - 2) { memcpy(buffer, env, path_len * sizeof(MSVCRT_wchar_t)); - if (buffer[path_len] != '/' || buffer[path_len] != '\\') + if (buffer[path_len] != '/' && buffer[path_len] != '\\') { buffer[path_len++] = '\\'; buffer[path_len] = '\0'; diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index ee409c46c05..39413c91a28 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1085,6 +1085,37 @@ static BSTR EnsureCorrectEOL(BSTR sInput) return sNew; } +/* Removes encoding information and last character (nullbyte) */ +static BSTR EnsureNoEncoding(BSTR sInput) +{ + static const WCHAR wszEncoding[] = {'e','n','c','o','d','i','n','g','='}; + BSTR sNew; + WCHAR *pBeg, *pEnd; + + pBeg = sInput; + while(*pBeg != '\n' && memcmp(pBeg, wszEncoding, sizeof(wszEncoding))) + pBeg++; + + if(*pBeg == '\n') + { + SysReAllocStringLen(&sInput, sInput, SysStringLen(sInput)-1); + return sInput; + } + pBeg--; + + pEnd = pBeg + sizeof(wszEncoding)/sizeof(WCHAR) + 2; + while(*pEnd != '\"') pEnd++; + pEnd++; + + sNew = SysAllocStringLen(NULL, + pBeg-sInput + SysStringLen(sInput)-(pEnd-sInput)-1); + memcpy(sNew, sInput, (pBeg-sInput)*sizeof(WCHAR)); + memcpy(&sNew[pBeg-sInput], pEnd, (SysStringLen(sInput)-(pEnd-sInput)-1)*sizeof(WCHAR)); + + SysFreeString(sInput); + return sNew; +} + /* * We are trying to replicate the same behaviour as msxml by converting * line endings to \r\n and using idents as \t. The problem is that msxml @@ -1123,7 +1154,18 @@ static HRESULT WINAPI xmlnode_get_xml( else bstrContent = bstr_from_xmlChar(pContent); - *xmlString = This->node->type == XML_ELEMENT_NODE ? EnsureCorrectEOL(bstrContent) : bstrContent; + switch(This->node->type) + { + case XML_ELEMENT_NODE: + *xmlString = EnsureCorrectEOL(bstrContent); + break; + case XML_DOCUMENT_NODE: + *xmlString = EnsureCorrectEOL(bstrContent); + *xmlString = EnsureNoEncoding(*xmlString); + break; + default: + *xmlString = bstrContent; + } } xmlBufferFree(pXmlBuf); diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c index d0ba6b5967c..646df914f2b 100644 --- a/dlls/msxml3/saxreader.c +++ b/dlls/msxml3/saxreader.c @@ -1517,10 +1517,8 @@ static ULONG WINAPI isaxlocator_Release( ref = InterlockedDecrement( &This->ref ); if ( ref == 0 ) { - if(This->publicId) - SysFreeString(This->publicId); - if(This->systemId) - SysFreeString(This->systemId); + SysFreeString(This->publicId); + SysFreeString(This->systemId); HeapFree(GetProcessHeap(), 0, This->nsStack); ISAXXMLReader_Release((ISAXXMLReader*)&This->saxreader->lpSAXXMLReaderVtbl); @@ -1558,7 +1556,7 @@ static HRESULT WINAPI isaxlocator_getPublicId( BSTR publicId; saxlocator *This = impl_from_ISAXLocator( iface ); - if(This->publicId) SysFreeString(This->publicId); + SysFreeString(This->publicId); publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt)); if(SysStringLen(publicId)) @@ -1580,7 +1578,7 @@ static HRESULT WINAPI isaxlocator_getSystemId( BSTR systemId; saxlocator *This = impl_from_ISAXLocator( iface ); - if(This->systemId) SysFreeString(This->systemId); + SysFreeString(This->systemId); systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt)); if(SysStringLen(systemId)) @@ -1909,6 +1907,17 @@ static HRESULT WINAPI internal_parse( IXMLDOMDocument *xmlDoc; if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) + { + BSTR bstrData; + + IXMLDOMDocument_get_xml(xmlDoc, &bstrData); + hr = internal_parseBuffer(This, (const char*)bstrData, + SysStringByteLen(bstrData), vbInterface); + IXMLDOMDocument_Release(xmlDoc); + break; + } + if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IPersistStream, (void**)&persistStream) == S_OK) { hr = IPersistStream_Save(persistStream, stream, TRUE); @@ -1922,18 +1931,6 @@ static HRESULT WINAPI internal_parse( IStream_Release(stream); break; } - if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), - &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) - { - BSTR bstrData; - - IXMLDOMDocument_get_xml(xmlDoc, &bstrData); - hr = internal_parseBuffer(This, (const char*)bstrData, - SysStringByteLen(bstrData), vbInterface); - IXMLDOMDocument_Release(xmlDoc); - hr = E_NOTIMPL; - break; - } } default: WARN("vt %d not implemented\n", V_VT(&varInput)); diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 2865f531e05..54ffe93c2ca 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -479,6 +479,9 @@ static void test_saxreader(void) HANDLE file; static const CHAR testXmlA[] = "test.xml"; static const WCHAR testXmlW[] = {'t','e','s','t','.','x','m','l',0}; + IXMLDOMDocument *domDocument; + BSTR bstrData; + VARIANT_BOOL vBool; hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (LPVOID*)&reader); @@ -576,6 +579,24 @@ static void test_saxreader(void) DeleteFileA(testXmlA); + hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, + &IID_IXMLDOMDocument, (LPVOID*)&domDocument); + if(FAILED(hr)) + { + skip("Failed to create DOMDocument instance\n"); + return; + } + bstrData = SysAllocString(szSimpleXML); + hr = IXMLDOMDocument_loadXML(domDocument, bstrData, &vBool); + V_VT(&var) = VT_UNKNOWN; + V_UNKNOWN(&var) = (IUnknown*)domDocument; + + expectCall = contentHandlerTest2; + hr = ISAXXMLReader_parse(reader, var); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + test_expect_call(CH_ENDTEST); + IXMLDOMDocument_Release(domDocument); + ISAXXMLReader_Release(reader); } diff --git a/dlls/netapi32/access.c b/dlls/netapi32/access.c index 5da07a617fd..424482781b1 100644 --- a/dlls/netapi32/access.c +++ b/dlls/netapi32/access.c @@ -417,6 +417,10 @@ NetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level, LPDWORD entriesread, LPDWORD totalentries) { NET_API_STATUS status; + const WCHAR admins[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0}; + LPWSTR currentuser; + LOCALGROUP_USERS_INFO_0* info; + DWORD size; FIXME("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n", debugstr_w(servername), debugstr_w(username), level, flags, bufptr, @@ -426,12 +430,37 @@ NetUserGetLocalGroups(LPCWSTR servername, LPCWSTR username, DWORD level, if (status != NERR_Success) return status; - if (!NETAPI_FindUser(username)) + size = UNLEN + 1; + NetApiBufferAllocate(size, (LPVOID*)¤tuser); + GetUserNameW(currentuser, &size); + + if (lstrcmpiW(username, currentuser) && NETAPI_FindUser(username)) + { + NetApiBufferFree(currentuser); return NERR_UserNotFound; + } + + NetApiBufferFree(currentuser); + *totalentries = 1; + size = sizeof(*info) + sizeof(admins); + + if(prefmaxlen < size) + status = ERROR_MORE_DATA; + else + status = NetApiBufferAllocate(size, (LPVOID*)&info); + + if(status != NERR_Success) + { + *bufptr = NULL; + *entriesread = 0; + return status; + } + + info->lgrui0_name = (LPWSTR)((LPBYTE)info + sizeof(*info)); + lstrcpyW(info->lgrui0_name, admins); - if (bufptr) *bufptr = NULL; - if (entriesread) *entriesread = 0; - if (totalentries) *totalentries = 0; + *bufptr = (LPBYTE)info; + *entriesread = 1; return NERR_Success; } diff --git a/dlls/ntdll/tests/atom.c b/dlls/ntdll/tests/atom.c index 87ea222a8f7..bc5fe2a31db 100644 --- a/dlls/ntdll/tests/atom.c +++ b/dlls/ntdll/tests/atom.c @@ -476,4 +476,8 @@ START_TEST(atom) test_NtRefPinAtom(); test_Global(); } + else + win_skip("Needed atom functions are not available\n"); + + FreeLibrary(hntdll); } diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c index aab93684187..92f654e7674 100644 --- a/dlls/ntdll/tests/env.c +++ b/dlls/ntdll/tests/env.c @@ -275,6 +275,11 @@ static void testExpand(void) START_TEST(env) { HMODULE mod = GetModuleHandleA("ntdll.dll"); + if (!mod) + { + win_skip("Not running on NT, skipping tests\n"); + return; + } pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN"); pRtlCreateEnvironment = (void*)GetProcAddress(mod, "RtlCreateEnvironment"); diff --git a/dlls/ntdll/tests/error.c b/dlls/ntdll/tests/error.c index d8d06cc2f68..b65d7d0ccd7 100644 --- a/dlls/ntdll/tests/error.c +++ b/dlls/ntdll/tests/error.c @@ -57,7 +57,10 @@ static int prepare_test(void) ntdll = LoadLibraryA("ntdll.dll"); pRtlNtStatusToDosError = (void*)GetProcAddress(ntdll, "RtlNtStatusToDosError"); if (!pRtlNtStatusToDosError) + { + win_skip("RtlNtStatusToDosError is not available\n"); return 0; + } argc = winetest_get_mainargs(&argv); strict=(argc >= 3 && strcmp(argv[2],"strict")==0); diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 1999da6bb61..2e5f355824f 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -451,23 +451,19 @@ static void test_directory(void) pNtClose(dir); } -#define SYMLNK_TEST_CREATE_FAILURE(h,e) \ - status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\ - ok(status == e,"NtCreateSymbolicLinkObject should have failed with %s got(%08x)\n", #e, status); -#define SYMLNK_TEST_OPEN_FAILURE(h,e) \ - status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\ - ok(status == e,"NtOpenSymbolicLinkObject should have failed with %s got(%08x)\n", #e, status); -#define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) \ +#define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \ pRtlCreateUnicodeStringFromAsciiz(&str, n);\ pRtlCreateUnicodeStringFromAsciiz(&target, t);\ - SYMLNK_TEST_CREATE_FAILURE(h,e)\ - SYMLNK_TEST_OPEN_FAILURE(h,e)\ + status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\ + ok(status == e || status == e2, \ + "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\ + status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\ + ok(status == e || status == e2, \ + "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\ pRtlFreeUnicodeString(&target);\ pRtlFreeUnicodeString(&str); -#define SYMLNK_TEST_CREATE_SUCCESS(h) \ - status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target); \ - ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status); +#define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e) static void test_symboliclink(void) { @@ -490,26 +486,38 @@ static void test_symboliclink(void) /* No attributes */ pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices"); status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target); - ok(status == STATUS_SUCCESS, "NtCreateSymbolicLinkObject failed(%08x)\n", status); + ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */ + "NtCreateSymbolicLinkObject failed(%08x)\n", status); pRtlFreeUnicodeString(&target); - pNtClose(h); + if (!status) pNtClose(h); InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); - SYMLNK_TEST_CREATE_FAILURE(&link, STATUS_INVALID_PARAMETER) - SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target); + ok(status == STATUS_INVALID_PARAMETER || + broken(status == STATUS_SUCCESS), /* nt4 */ + "NtCreateSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status); + if (!status) pNtClose(h); + status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr); + ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, + "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status); /* Bad name */ pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere"); InitializeObjectAttributes(&attr, &str, 0, 0, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, ""); - SYMLNK_TEST_CREATE_SUCCESS(&link) - SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target); + ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status); + status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr); + ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, + "NtOpenSymbolicLinkObject should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08x)\n", status); pNtClose(link); pRtlFreeUnicodeString(&str); pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); - todo_wine {SYMLNK_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)} + status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target); + todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH, + "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08x)\n", status); pRtlFreeUnicodeString(&str); pRtlFreeUnicodeString(&target); @@ -517,7 +525,8 @@ static void test_symboliclink(void) SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID) SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) + SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere", + STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND) /* Compaund test */ @@ -534,7 +543,8 @@ static void test_symboliclink(void) InitializeObjectAttributes(&attr, &str, 0, dir, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "test-link"); pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices"); - SYMLNK_TEST_CREATE_SUCCESS(&link) + status = pNtCreateSymbolicLinkObject(&link, SYMBOLIC_LINK_QUERY, &attr, &target); + ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08x)\n", status); pRtlFreeUnicodeString(&str); pRtlFreeUnicodeString(&target); diff --git a/dlls/ntdll/tests/path.c b/dlls/ntdll/tests/path.c index bf1271aafc3..e1b17676bed 100644 --- a/dlls/ntdll/tests/path.c +++ b/dlls/ntdll/tests/path.c @@ -314,6 +314,12 @@ static void test_RtlGetFullPathName_U(void) START_TEST(path) { HMODULE mod = GetModuleHandleA("ntdll.dll"); + if (!mod) + { + win_skip("Not running on NT, skipping tests\n"); + return; + } + pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN"); pRtlUnicodeToMultiByteN = (void *)GetProcAddress(mod,"RtlUnicodeToMultiByteN"); pRtlDetermineDosPathNameType_U = (void *)GetProcAddress(mod,"RtlDetermineDosPathNameType_U"); diff --git a/dlls/ntdll/tests/port.c b/dlls/ntdll/tests/port.c index 0bb1ff7cb4d..c63820a37fd 100644 --- a/dlls/ntdll/tests/port.c +++ b/dlls/ntdll/tests/port.c @@ -138,6 +138,7 @@ static BOOL init_function_ptrs(void) !pNtRequestPort || !pNtRegisterThreadTerminatePort || !pNtConnectPort || !pRtlInitUnicodeString) { + win_skip("Needed port functions are not available\n"); FreeLibrary(hntdll); return FALSE; } diff --git a/dlls/oleaut32/tests/olefont.c b/dlls/oleaut32/tests/olefont.c index 0e5f55f3cf2..6774368100e 100644 --- a/dlls/oleaut32/tests/olefont.c +++ b/dlls/oleaut32/tests/olefont.c @@ -138,7 +138,9 @@ static void test_QueryInterface(void) /* Test if QueryInterface increments ref counter for IFONTs */ ret = IFont_AddRef(font); - ok(ret == 3, "IFont_QI expected ref value 3 but instead got %12u\n",ret); + ok(ret == 3 || + broken(ret == 1), /* win95 */ + "IFont_QI expected ref value 3 but instead got %ld\n",ret); IFont_Release(font); ok(hres == S_OK,"IFont_QI does not return S_OK, but 0x%08x\n", hres); diff --git a/dlls/oleaut32/tests/varformat.c b/dlls/oleaut32/tests/varformat.c index 47fb8e66178..00551e701c7 100644 --- a/dlls/oleaut32/tests/varformat.c +++ b/dlls/oleaut32/tests/varformat.c @@ -67,7 +67,7 @@ static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 ) if (hres == S_OK) { \ ok(str && strcmpW(str,szResult1) == 0, \ "VarFormatNumber (vt %d): string different\n", vt); \ - if (str) SysFreeString(str); \ + SysFreeString(str); \ } static void test_VarFormatNumber(void) @@ -137,7 +137,7 @@ static const char *szVarFmtFail = "VT %d|0x%04x Format %s: expected 0x%08x, '%s' ok(hres == ret && (FAILED(ret) || !strcmp(buff, str)), \ szVarFmtFail, \ (vt)&VT_TYPEMASK,(vt)&~VT_TYPEMASK,fmt?fmt:"",ret,str,hres,buff); \ - if (out) SysFreeString(out); \ + SysFreeString(out); \ } while(0) typedef struct tagFMTRES diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c index fdfe07ce7c9..a7b40092a2f 100644 --- a/dlls/oleaut32/tmarshal.c +++ b/dlls/oleaut32/tmarshal.c @@ -1420,8 +1420,8 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */) TRACE_(olerelay)("("); } - if (iname) SysFreeString(iname); - if (fname) SysFreeString(fname); + SysFreeString(iname); + SysFreeString(fname); memset(&buf,0,sizeof(buf)); @@ -2080,7 +2080,7 @@ TMStubImpl_Invoke( goto exit; } - if (iname) SysFreeString (iname); + SysFreeString (iname); /* Need them for hack below */ memset(names,0,sizeof(names)); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index ceb229528b1..9539bd076c8 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -838,7 +838,7 @@ enddeleteloop: } end: - if (tlibPath) SysFreeString(tlibPath); + SysFreeString(tlibPath); if (typeLib) ITypeLib_Release(typeLib); if (subKey) RegCloseKey(subKey); if (key) RegCloseKey(key); @@ -3833,29 +3833,17 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) } TRACE(" destroying ITypeLib(%p)\n",This); - if (This->Name) - { - SysFreeString(This->Name); - This->Name = NULL; - } + SysFreeString(This->Name); + This->Name = NULL; - if (This->DocString) - { - SysFreeString(This->DocString); - This->DocString = NULL; - } + SysFreeString(This->DocString); + This->DocString = NULL; - if (This->HelpFile) - { - SysFreeString(This->HelpFile); - This->HelpFile = NULL; - } + SysFreeString(This->HelpFile); + This->HelpFile = NULL; - if (This->HelpStringDll) - { - SysFreeString(This->HelpStringDll); - This->HelpStringDll = NULL; - } + SysFreeString(This->HelpStringDll); + This->HelpStringDll = NULL; for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext) { @@ -4679,23 +4667,14 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) if (This->no_free_data) goto finish_free; - if (This->Name) - { - SysFreeString(This->Name); - This->Name = 0; - } + SysFreeString(This->Name); + This->Name = NULL; - if (This->DocString) - { - SysFreeString(This->DocString); - This->DocString = 0; - } + SysFreeString(This->DocString); + This->DocString = NULL; - if (This->DllName) - { - SysFreeString(This->DllName); - This->DllName = 0; - } + SysFreeString(This->DllName); + This->DllName = NULL; for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext) { @@ -6526,7 +6505,7 @@ static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, { ERR("couldn't load %s\n", debugstr_w(dll)); SysFreeString(dll); - if (entry) SysFreeString(entry); + SysFreeString(entry); return STG_E_FILENOTFOUND; } /* FIXME: store library somewhere where we can free it */ @@ -6552,7 +6531,7 @@ static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, } SysFreeString(dll); - if (entry) SysFreeString(entry); + SysFreeString(entry); if (!*ppv) return TYPE_E_DLLFUNCTIONNOTFOUND; diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c index e93d1d10432..b68871790d1 100644 --- a/dlls/quartz/avisplit.c +++ b/dlls/quartz/avisplit.c @@ -447,10 +447,12 @@ static HRESULT AVISplitter_first_request(LPVOID iface) /* Could be an EOF instead */ have_sample = (hr == S_OK); - if (FAILED(hr)) - break; if (hr == S_FALSE) AVISplitter_SendEndOfFile(This, x); + + if (FAILED(hr) && hr != VFW_E_NOT_CONNECTED) + break; + hr = S_OK; } /* FIXME: Don't do this for each pin that sent an EOF */ diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c index 2a063e28393..d41899d3a39 100644 --- a/dlls/quartz/filesource.c +++ b/dlls/quartz/filesource.c @@ -1182,8 +1182,12 @@ static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader * iface, DWORD dw if (buffer >= This->samples) { if (buffer != This->samples) + { FIXME("Returned: %u (%08x)\n", buffer, GetLastError()); - hr = VFW_E_TIMEOUT; + hr = VFW_E_TIMEOUT; + } + else + hr = VFW_E_WRONG_STATE; buffer = ~0; } else diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 9728c37e085..42b6da87b09 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -2570,8 +2570,10 @@ static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME } static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime){ - FIXME("(%p)->(%f) stub!\n", iface, llTime); - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaPosition_vtbl, iface); + LONGLONG reftime = llTime; + + return IMediaSeeking_SetPositions((IMediaSeeking *)&This->IMediaSeeking_vtbl, &reftime, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); } static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime){ diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 7f2530037cc..628eab60774 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -231,6 +231,7 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface) if (This->state == State_Stopped) { LeaveCriticalSection(&This->csFilter); + IAsyncReader_EndFlush(This->pInputPin->pReader); LeaveCriticalSection(&pin->thread_lock); return S_OK; } @@ -246,6 +247,7 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface) PullPin_PauseProcessing(This->pInputPin); PullPin_WaitForStateChange(This->pInputPin, INFINITE); + IAsyncReader_EndFlush(This->pInputPin->pReader); LeaveCriticalSection(&pin->thread_lock); return S_OK; diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index bcf09a5d98d..56890150baa 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -1526,6 +1526,7 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This) TRACE("Process sample\n"); + pSample = NULL; hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser); /* Return an empty sample on error to the implementation in case it does custom parsing, so it knows it's gone */ @@ -1537,6 +1538,12 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This) { /* FIXME: This is not well handled yet! */ ERR("Processing error: %x\n", hr); + if (hr == VFW_E_TIMEOUT) + { + assert(!pSample); + hr = S_OK; + continue; + } } if (pSample) @@ -1790,6 +1797,10 @@ HRESULT WINAPI PullPin_EndFlush(IPin * iface) EnterCriticalSection(&This->thread_lock); { FILTER_STATE state; + + if (This->pReader) + IAsyncReader_EndFlush(This->pReader); + IBaseFilter_GetState(This->pin.pinInfo.pFilter, INFINITE, &state); if (state != State_Stopped) diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index eba37efa757..2955594a009 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -1099,7 +1099,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type) } - void ME_UpdateScrollBar(ME_TextEditor *editor) +void ME_UpdateScrollBar(ME_TextEditor *editor) { /* Note that this is the only function that should ever call SetScrolLInfo * with SIF_PAGE or SIF_RANGE. SetScrollPos and SetScrollRange should never diff --git a/dlls/rpcrt4/cstub.c b/dlls/rpcrt4/cstub.c index c790ad57329..869265fcdc2 100644 --- a/dlls/rpcrt4/cstub.c +++ b/dlls/rpcrt4/cstub.c @@ -221,9 +221,7 @@ void create_delegating_vtbl(DWORD num_methods) if(current_vtbl.table && current_vtbl.table->ref == 0) { TRACE("freeing old table\n"); - VirtualFree(current_vtbl.table->methods, - (current_vtbl.table->size - 3) * sizeof(vtbl_method_t), - MEM_RELEASE); + VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); HeapFree(GetProcessHeap(), 0, current_vtbl.table); } size = (num_methods - 3) * sizeof(vtbl_method_t); @@ -258,9 +256,7 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl) if(table->ref == 0 && table != current_vtbl.table) { TRACE("... and we're not current so free'ing\n"); - VirtualFree(current_vtbl.table->methods, - (current_vtbl.table->size - 3) * sizeof(vtbl_method_t), - MEM_RELEASE); + VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); HeapFree(GetProcessHeap(), 0, table); } LeaveCriticalSection(&delegating_vtbl_section); diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c index f8efc6713f5..dea1f1b9f71 100644 --- a/dlls/rpcrt4/rpc_server.c +++ b/dlls/rpcrt4/rpc_server.c @@ -1124,6 +1124,40 @@ RPC_STATUS WINAPI RpcMgmtInqIfIds(RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR * } /*********************************************************************** + * RpcMgmtInqStats (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtInqStats(RPC_BINDING_HANDLE Binding, RPC_STATS_VECTOR **Statistics) +{ + RPC_STATS_VECTOR *stats; + + FIXME("(%p,%p)\n", Binding, Statistics); + + if ((stats = HeapAlloc(GetProcessHeap(), 0, sizeof(RPC_STATS_VECTOR)))) + { + stats->Count = 1; + stats->Stats[0] = 0; + *Statistics = stats; + return RPC_S_OK; + } + return RPC_S_OUT_OF_RESOURCES; +} + +/*********************************************************************** + * RpcMgmtStatsVectorFree (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtStatsVectorFree(RPC_STATS_VECTOR **StatsVector) +{ + FIXME("(%p)\n", StatsVector); + + if (StatsVector) + { + HeapFree(GetProcessHeap(), 0, *StatsVector); + *StatsVector = NULL; + } + return RPC_S_OK; +} + +/*********************************************************************** * RpcMgmtEpEltInqBegin (RPCRT4.@) */ RPC_STATUS WINAPI RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE Binding, ULONG InquiryType, diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index e4857d2aca4..1a56c08a8ec 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -399,13 +399,13 @@ @ stdcall RpcMgmtInqIfIds(ptr ptr) @ stub RpcMgmtInqServerPrincNameA @ stub RpcMgmtInqServerPrincNameW -@ stub RpcMgmtInqStats +@ stdcall RpcMgmtInqStats(ptr ptr) @ stdcall RpcMgmtIsServerListening(ptr) @ stub RpcMgmtSetAuthorizationFn @ stdcall RpcMgmtSetCancelTimeout(long) @ stdcall RpcMgmtSetComTimeout(ptr long) @ stdcall RpcMgmtSetServerStackSize(long) -@ stub RpcMgmtStatsVectorFree +@ stdcall RpcMgmtStatsVectorFree(ptr) @ stdcall RpcMgmtStopServerListening(ptr) @ stdcall RpcMgmtWaitServerListen() @ stub RpcNetworkInqProtseqsA diff --git a/dlls/secur32/Makefile.in b/dlls/secur32/Makefile.in index df9695a8063..788f4dea1c2 100644 --- a/dlls/secur32/Makefile.in +++ b/dlls/secur32/Makefile.in @@ -6,6 +6,7 @@ MODULE = secur32.dll IMPORTLIB = secur32 IMPORTS = netapi32 advapi32 kernel32 ntdll DELAYIMPORTS = crypt32 +EXTRAINCL = @GNUTLSINCL@ C_SRCS = \ base64_codec.c \ diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c index 43b0f260c7a..82076689b6d 100644 --- a/dlls/secur32/schannel.c +++ b/dlls/secur32/schannel.c @@ -18,16 +18,120 @@ * FIXME: It should be rather obvious that this file is empty of any * implementation. */ +#include "config.h" +#include "wine/port.h" + #include +#ifdef SONAME_LIBGNUTLS +#include +#endif + #include "windef.h" #include "winbase.h" #include "sspi.h" #include "schannel.h" #include "secur32_priv.h" #include "wine/debug.h" +#include "wine/library.h" WINE_DEFAULT_DEBUG_CHANNEL(secur32); +#ifdef SONAME_LIBGNUTLS + +static void *libgnutls_handle; +#define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(gnutls_certificate_allocate_credentials); +MAKE_FUNCPTR(gnutls_certificate_free_credentials); +MAKE_FUNCPTR(gnutls_global_deinit); +MAKE_FUNCPTR(gnutls_global_init); +MAKE_FUNCPTR(gnutls_global_set_log_function); +MAKE_FUNCPTR(gnutls_global_set_log_level); +#undef MAKE_FUNCPTR + +enum schan_handle_type +{ + SCHAN_HANDLE_CRED, + SCHAN_HANDLE_FREE +}; + +struct schan_handle +{ + void *object; + enum schan_handle_type type; +}; + +struct schan_credentials +{ + ULONG credential_use; + gnutls_certificate_credentials credentials; +}; + +static struct schan_handle *schan_handle_table; +static struct schan_handle *schan_free_handles; +static SIZE_T schan_handle_table_size; +static SIZE_T schan_handle_count; + +static ULONG_PTR schan_alloc_handle(void *object, enum schan_handle_type type) +{ + struct schan_handle *handle; + + if (schan_free_handles) + { + /* Use a free handle */ + handle = schan_free_handles; + if (handle->type != SCHAN_HANDLE_FREE) + { + ERR("Handle %d(%p) is in the free list, but has type %#x.\n", (handle-schan_handle_table), handle, handle->type); + return -1; + } + schan_free_handles = (struct schan_handle *)handle->object; + handle->object = object; + handle->type = type; + + return handle - schan_handle_table; + } + if (!(schan_handle_count < schan_handle_table_size)) + { + /* Grow the table */ + SIZE_T new_size = schan_handle_table_size + (schan_handle_table_size >> 1); + struct schan_handle *new_table = HeapReAlloc(GetProcessHeap(), 0, schan_handle_table, new_size * sizeof(*schan_handle_table)); + if (!new_table) + { + ERR("Failed to grow the handle table\n"); + return -1; + } + schan_handle_table = new_table; + schan_handle_table_size = new_size; + } + + handle = &schan_handle_table[schan_handle_count++]; + handle->object = object; + handle->type = type; + + return handle - schan_handle_table; +} + +static void *schan_free_handle(ULONG_PTR handle_idx, enum schan_handle_type type) +{ + struct schan_handle *handle; + void *object; + + if (handle_idx == -1) return NULL; + handle = &schan_handle_table[handle_idx]; + if (handle->type != type) + { + ERR("Handle %ld(%p) is not of type %#x\n", handle_idx, handle, type); + return NULL; + } + + object = handle->object; + handle->object = schan_free_handles; + handle->type = SCHAN_HANDLE_FREE; + schan_free_handles = handle; + + return object; +} + static SECURITY_STATUS schan_QueryCredentialsAttributes( PCredHandle phCredential, ULONG ulAttribute, const VOID *pBuffer) { @@ -158,6 +262,8 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan { SECURITY_STATUS st = SEC_E_OK; + TRACE("schanCred %p, phCredential %p, ptsExpiry %p\n", schanCred, phCredential, ptsExpiry); + if (schanCred) { st = schan_CheckCreds(schanCred); @@ -170,7 +276,25 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan */ if (st == SEC_E_OK) { - phCredential->dwUpper = SECPKG_CRED_OUTBOUND; + ULONG_PTR handle; + struct schan_credentials *creds; + + creds = HeapAlloc(GetProcessHeap(), 0, sizeof(*creds)); + if (!creds) return SEC_E_INSUFFICIENT_MEMORY; + + handle = schan_alloc_handle(creds, SCHAN_HANDLE_CRED); + if (handle == -1) + { + HeapFree(GetProcessHeap(), 0, creds); + return SEC_E_INTERNAL_ERROR; + } + + creds->credential_use = SECPKG_CRED_OUTBOUND; + pgnutls_certificate_allocate_credentials(&creds->credentials); + + phCredential->dwLower = handle; + phCredential->dwUpper = 0; + /* Outbound credentials have no expiry */ if (ptsExpiry) { @@ -186,12 +310,30 @@ static SECURITY_STATUS schan_AcquireServerCredentials(const SCHANNEL_CRED *schan { SECURITY_STATUS st; + TRACE("schanCred %p, phCredential %p, ptsExpiry %p\n", schanCred, phCredential, ptsExpiry); + if (!schanCred) return SEC_E_NO_CREDENTIALS; st = schan_CheckCreds(schanCred); if (st == SEC_E_OK) { - phCredential->dwUpper = SECPKG_CRED_INBOUND; + ULONG_PTR handle; + struct schan_credentials *creds; + + creds = HeapAlloc(GetProcessHeap(), 0, sizeof(*creds)); + if (!creds) return SEC_E_INSUFFICIENT_MEMORY; + creds->credential_use = SECPKG_CRED_INBOUND; + + handle = schan_alloc_handle(creds, SCHAN_HANDLE_CRED); + if (handle == -1) + { + HeapFree(GetProcessHeap(), 0, creds); + return SEC_E_INTERNAL_ERROR; + } + + phCredential->dwLower = handle; + phCredential->dwUpper = 0; + /* FIXME: get expiry from cert */ } return st; @@ -238,7 +380,19 @@ static SECURITY_STATUS SEC_ENTRY schan_AcquireCredentialsHandleW( static SECURITY_STATUS SEC_ENTRY schan_FreeCredentialsHandle( PCredHandle phCredential) { - FIXME("(%p): stub\n", phCredential); + struct schan_credentials *creds; + + TRACE("phCredential %p\n", phCredential); + + if (!phCredential) return SEC_E_INVALID_HANDLE; + + creds = schan_free_handle(phCredential->dwLower, SCHAN_HANDLE_CRED); + if (!creds) return SEC_E_INVALID_HANDLE; + + if (creds->credential_use == SECPKG_CRED_OUTBOUND) + pgnutls_certificate_free_credentials(creds->credentials); + HeapFree(GetProcessHeap(), 0, creds); + return SEC_E_OK; } @@ -294,6 +448,11 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW( return ret; } +static void schan_gnutls_log(int level, const char *msg) +{ + TRACE("<%d> %s", level, msg); +} + static const SecurityFunctionTableA schanTableA = { 1, NULL, /* EnumerateSecurityPackagesA */ @@ -362,8 +521,34 @@ static const WCHAR schannelDllName[] = { 's','c','h','a','n','n','e','l','.','d' void SECUR32_initSchannelSP(void) { - SecureProvider *provider = SECUR32_addProvider(&schanTableA, &schanTableW, - schannelDllName); + SecureProvider *provider; + + + libgnutls_handle = wine_dlopen(SONAME_LIBGNUTLS, RTLD_NOW, NULL, 0); + if (!libgnutls_handle) + { + WARN("Failed to load libgnutls.\n"); + return; + } + +#define LOAD_FUNCPTR(f) \ + if (!(p##f = wine_dlsym(libgnutls_handle, #f, NULL, 0))) \ + { \ + ERR("Failed to load %s\n", #f); \ + wine_dlclose(libgnutls_handle, NULL, 0); \ + libgnutls_handle = NULL; \ + return; \ + } + + LOAD_FUNCPTR(gnutls_certificate_allocate_credentials) + LOAD_FUNCPTR(gnutls_certificate_free_credentials) + LOAD_FUNCPTR(gnutls_global_deinit) + LOAD_FUNCPTR(gnutls_global_init) + LOAD_FUNCPTR(gnutls_global_set_log_function) + LOAD_FUNCPTR(gnutls_global_set_log_level) +#undef LOAD_FUNCPTR + + provider = SECUR32_addProvider(&schanTableA, &schanTableW, schannelDllName); if (provider) { @@ -393,5 +578,28 @@ void SECUR32_initSchannelSP(void) SECUR32_addPackages(provider, sizeof(info) / sizeof(info[0]), NULL, info); + + schan_handle_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 64 * sizeof(*schan_handle_table)); + schan_handle_table_size = 64; + + pgnutls_global_init(); + if (TRACE_ON(secur32)) + { + pgnutls_global_set_log_level(4); + pgnutls_global_set_log_function(schan_gnutls_log); + } } } + +void SECUR32_deinitSchannelSP(void) +{ + pgnutls_global_deinit(); + if (libgnutls_handle) wine_dlclose(libgnutls_handle, NULL, 0); +} + +#else /* SONAME_LIBGNUTLS */ + +void SECUR32_initSchannelSP(void) {} +void SECUR32_deinitSchannelSP(void) {} + +#endif /* SONAME_LIBGNUTLS */ diff --git a/dlls/secur32/secur32.c b/dlls/secur32/secur32.c index 4a434ac21df..27e0263c6cf 100644 --- a/dlls/secur32/secur32.c +++ b/dlls/secur32/secur32.c @@ -673,6 +673,8 @@ static void SECUR32_freeProviders(void) TRACE("\n"); EnterCriticalSection(&cs); + SECUR32_deinitSchannelSP(); + if (packageTable) { LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry) diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h index 6f9c1e75dec..9eed1a57532 100644 --- a/dlls/secur32/secur32_priv.h +++ b/dlls/secur32/secur32_priv.h @@ -124,6 +124,9 @@ void SECUR32_initSchannelSP(void); void SECUR32_initNegotiateSP(void); void SECUR32_initNTLMSP(void); +/* Cleanup functions for built-in providers */ +void SECUR32_deinitSchannelSP(void); + /* Functions from dispatcher.c used elsewhere in the code */ SECURITY_STATUS fork_helper(PNegoHelper *new_helper, const char *prog, char * const argv[]); diff --git a/dlls/secur32/tests/main.c b/dlls/secur32/tests/main.c index bc6bbe6190f..359bcc7f14b 100644 --- a/dlls/secur32/tests/main.c +++ b/dlls/secur32/tests/main.c @@ -199,7 +199,8 @@ static void testQuerySecurityPackageInfo(void) pkg_info = (void *)0xdeadbeef; sec_status = setupPackageA(ntlm, &pkg_info); - ok((sec_status == SEC_E_OK) || (sec_status == SEC_E_SECPKG_NOT_FOUND), + ok((sec_status == SEC_E_OK) || (sec_status == SEC_E_SECPKG_NOT_FOUND) || + broken(sec_status == SEC_E_UNSUPPORTED_FUNCTION), /* win95 */ "Return value of QuerySecurityPackageInfo() shouldn't be %s\n", getSecError(sec_status) ); diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c index 9f7c2a8f8a8..a6032be8ff9 100644 --- a/dlls/secur32/tests/schannel.c +++ b/dlls/secur32/tests/schannel.c @@ -30,6 +30,8 @@ static HMODULE secdll, crypt32dll; static ACQUIRE_CREDENTIALS_HANDLE_FN_A pAcquireCredentialsHandleA; +static ENUMERATE_SECURITY_PACKAGES_FN_A pEnumerateSecurityPackagesA; +static FREE_CONTEXT_BUFFER_FN pFreeContextBuffer; static FREE_CREDENTIALS_HANDLE_FN pFreeCredentialsHandle; static QUERY_CREDENTIALS_ATTRIBUTES_FN_A pQueryCredentialsAttributesA; @@ -120,6 +122,8 @@ static void InitFunctionPtrs(void) if(secdll) { GET_PROC(secdll, AcquireCredentialsHandleA); + GET_PROC(secdll, EnumerateSecurityPackagesA); + GET_PROC(secdll, FreeContextBuffer); GET_PROC(secdll, FreeCredentialsHandle); GET_PROC(secdll, QueryCredentialsAttributesA); } @@ -150,6 +154,9 @@ static void test_strength(PCredHandle handle) static void testAcquireSecurityContext(void) { + BOOL has_schannel = FALSE; + SecPkgInfoA *package_info; + ULONG i; SECURITY_STATUS st; CredHandle cred; TimeStamp exp; @@ -163,12 +170,31 @@ static void testAcquireSecurityContext(void) CRYPT_KEY_PROV_INFO keyProvInfo; if (!pAcquireCredentialsHandleA || !pCertCreateCertificateContext || + !pEnumerateSecurityPackagesA || !pFreeContextBuffer || !pFreeCredentialsHandle || !pCryptAcquireContextW) { skip("Needed functions are not available\n"); return; } + if (SUCCEEDED(pEnumerateSecurityPackagesA(&i, &package_info))) + { + while(i--) + { + if (!strcmp(package_info[i].Name, unisp_name_a)) + { + has_schannel = TRUE; + break; + } + } + pFreeContextBuffer(package_info); + } + if (!has_schannel) + { + skip("Schannel not available\n"); + return; + } + lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W); keyProvInfo.pwszContainerName = cspNameW; diff --git a/dlls/shdocvw/navigate.c b/dlls/shdocvw/navigate.c index 7ca0b0f56b3..b5299d59e9b 100644 --- a/dlls/shdocvw/navigate.c +++ b/dlls/shdocvw/navigate.c @@ -162,8 +162,7 @@ static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface) IOleClientSite_Release(CLIENTSITE(This->doc_host)); if(This->post_data) GlobalFree(This->post_data); - if(This->headers) - SysFreeString(This->headers); + SysFreeString(This->headers); heap_free(This->url); heap_free(This); } diff --git a/dlls/shdocvw/shdocvw.inf b/dlls/shdocvw/shdocvw.inf index b765e24530e..cec06bc3e97 100644 --- a/dlls/shdocvw/shdocvw.inf +++ b/dlls/shdocvw/shdocvw.inf @@ -137,8 +137,9 @@ HKLM,"Software\Microsoft\Windows\CurrentVersion\URL\Prefixes","www",,"http://" [Settings.Reg] -HKCU,"Software\Microsoft\Internet Explorer\Main","Start Page",,"http://www.winehq.org" -HKCU,"Software\Microsoft\Internet Explorer\Main","Search Page",,"http://www.google.com" +HKCU,"Software\Microsoft\Internet Explorer\Main","Start Page",2,"http://www.winehq.org" +HKCU,"Software\Microsoft\Internet Explorer\Main","Search Page",2,"http://www.google.com" +HKLM,"Software\Microsoft\Internet Explorer\Main","Default_Page_URL",2,"http://www.winehq.org" [IE.Reg] diff --git a/dlls/shell32/tests/appbar.c b/dlls/shell32/tests/appbar.c index ae06a90c8d1..9991fe284e8 100644 --- a/dlls/shell32/tests/appbar.c +++ b/dlls/shell32/tests/appbar.c @@ -30,13 +30,21 @@ static const CHAR testwindow_class[] = "testwindow"; static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD); +typedef BOOL (*boolean_function)(void); + struct testwindow_info { + HWND hwnd; + BOOL registered; RECT desired_rect; UINT edge; RECT allocated_rect; }; +static struct testwindow_info windows[3]; + +static int expected_bottom; + static void testwindow_setpos(HWND hwnd) { struct testwindow_info* info = (struct testwindow_info*)GetWindowLongPtr(hwnd, GWLP_USERDATA); @@ -45,7 +53,7 @@ static void testwindow_setpos(HWND hwnd) ok(info != NULL, "got unexpected ABN_POSCHANGED notification\n"); - if (!info) + if (!info || !info->registered) { return; } @@ -102,6 +110,32 @@ static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, L return DefWindowProc(hwnd, msg, wparam, lparam); } +/* process pending messages until a condition is true or 3 seconds pass */ +static void do_events_until(boolean_function test) +{ + MSG msg; + UINT_PTR timerid; + BOOL timedout=FALSE; + + timerid = SetTimer(0, 0, 3000, NULL); + + while (1) + { + while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.hwnd == 0 && msg.message == WM_TIMER && msg.wParam == timerid) + timedout = TRUE; + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + if (timedout || test()) + break; + WaitMessage(); + } + + KillTimer(0, timerid); +} + /* process any pending messages */ static void do_events(void) { @@ -114,6 +148,28 @@ static void do_events(void) } } +static BOOL no_appbars_intersect(void) +{ + int i, j; + RECT rc; + + for (i=0; i<2; i++) + { + for (j=i+1; j<3; j++) + { + if (windows[i].registered && windows[j].registered && + IntersectRect(&rc, &windows[i].allocated_rect, &windows[j].allocated_rect)) + return FALSE; + } + } + return TRUE; +} + +static BOOL got_expected_bottom(void) +{ + return (no_appbars_intersect() && windows[1].allocated_rect.bottom == expected_bottom); +} + static void register_testwindow_class(void) { WNDCLASSEXA cls; @@ -130,26 +186,30 @@ static void register_testwindow_class(void) RegisterClassExA(&cls); } +#define test_window_rects(a, b) \ + ok(!IntersectRect(&rc, &windows[a].allocated_rect, &windows[b].allocated_rect), \ + "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", \ + windows[a].allocated_rect.left, windows[a].allocated_rect.top, windows[a].allocated_rect.right, windows[a].allocated_rect.bottom, \ + windows[b].allocated_rect.left, windows[b].allocated_rect.top, windows[b].allocated_rect.right, windows[b].allocated_rect.bottom) + static void test_setpos(void) { APPBARDATA abd; RECT rc; - int screen_width, screen_height, expected; - HWND window1, window2, window3; - struct testwindow_info window1_info, window2_info, window3_info; + int screen_width, screen_height; BOOL ret; screen_width = GetSystemMetrics(SM_CXSCREEN); screen_height = GetSystemMetrics(SM_CYSCREEN); - /* create and register window1 */ - window1 = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, + /* create and register windows[0] */ + windows[0].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - ok(window1 != NULL, "couldn't create window\n"); + ok(windows[0].hwnd != NULL, "couldn't create window\n"); do_events(); abd.cbSize = sizeof(abd); - abd.hWnd = window1; + abd.hWnd = windows[0].hwnd; abd.uCallbackMessage = MSG_APPBAR; ret = SHAppBarMessage(ABM_NEW, &abd); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); @@ -159,181 +219,140 @@ static void test_setpos(void) ok(ret == FALSE, "SHAppBarMessage returned %i\n", ret); do_events(); - /* dock window1 to the bottom of the screen */ - window1_info.edge = ABE_BOTTOM; - window1_info.desired_rect.left = 0; - window1_info.desired_rect.right = screen_width; - window1_info.desired_rect.top = screen_height - 15; - window1_info.desired_rect.bottom = screen_height; - SetWindowLongPtr(window1, GWLP_USERDATA, (LONG_PTR)&window1_info); - testwindow_setpos(window1); + /* dock windows[0] to the bottom of the screen */ + windows[0].registered = TRUE; + windows[0].edge = ABE_BOTTOM; + windows[0].desired_rect.left = 0; + windows[0].desired_rect.right = screen_width; + windows[0].desired_rect.top = screen_height - 15; + windows[0].desired_rect.bottom = screen_height; + SetWindowLongPtr(windows[0].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[0]); + testwindow_setpos(windows[0].hwnd); do_events(); - /* create and register window2 */ - window2 = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, + /* create and register windows[1] */ + windows[1].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - ok(window2 != NULL, "couldn't create window\n"); - abd.hWnd = window2; + ok(windows[1].hwnd != NULL, "couldn't create window\n"); + abd.hWnd = windows[1].hwnd; ret = SHAppBarMessage(ABM_NEW, &abd); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); - /* dock window2 to the bottom of the screen */ - window2_info.edge = ABE_BOTTOM; - window2_info.desired_rect.left = 0; - window2_info.desired_rect.right = screen_width; - window2_info.desired_rect.top = screen_height - 10; - window2_info.desired_rect.bottom = screen_height; - SetWindowLongPtr(window2, GWLP_USERDATA, (LONG_PTR)&window2_info); - testwindow_setpos(window2); - do_events(); + /* dock windows[1] to the bottom of the screen */ + windows[1].registered = TRUE; + windows[1].edge = ABE_BOTTOM; + windows[1].desired_rect.left = 0; + windows[1].desired_rect.right = screen_width; + windows[1].desired_rect.top = screen_height - 10; + windows[1].desired_rect.bottom = screen_height; + SetWindowLongPtr(windows[1].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[1]); + testwindow_setpos(windows[1].hwnd); /* the windows are adjusted to they don't overlap */ - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - - /* make window1 larger, forcing window2 to move out of its way */ - window1_info.desired_rect.top = screen_height - 20; - testwindow_setpos(window1); - do_events(); - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); + do_events_until(no_appbars_intersect); + test_window_rects(0, 1); + + /* make windows[0] larger, forcing windows[1] to move out of its way */ + windows[0].desired_rect.top = screen_height - 20; + testwindow_setpos(windows[0].hwnd); + do_events_until(no_appbars_intersect); + test_window_rects(0, 1); - /* create and register window3 */ - window3 = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, + /* create and register windows[2] */ + windows[2].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - ok(window3 != NULL, "couldn't create window\n"); + ok(windows[2].hwnd != NULL, "couldn't create window\n"); do_events(); - abd.hWnd = window3; + abd.hWnd = windows[2].hwnd; ret = SHAppBarMessage(ABM_NEW, &abd); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); - /* dock window3 to the bottom of the screen */ - window3_info.edge = ABE_BOTTOM; - window3_info.desired_rect.left = 0; - window3_info.desired_rect.right = screen_width; - window3_info.desired_rect.top = screen_height - 10; - window3_info.desired_rect.bottom = screen_height; - SetWindowLongPtr(window3, GWLP_USERDATA, (LONG_PTR)&window3_info); - testwindow_setpos(window3); - do_events(); - - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - - /* move window3 to the right side of the screen */ - window3_info.edge = ABE_RIGHT; - window3_info.desired_rect.left = screen_width - 15; - window3_info.desired_rect.right = screen_width; - window3_info.desired_rect.top = 0; - window3_info.desired_rect.bottom = screen_height; - testwindow_setpos(window3); - do_events(); - - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - - /* move window2 to the top of the screen */ - window2_info.edge = ABE_TOP; - window2_info.desired_rect.left = 0; - window2_info.desired_rect.right = screen_width; - window2_info.desired_rect.top = 0; - window2_info.desired_rect.bottom = 15; - testwindow_setpos(window2); - do_events(); - - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - - /* move window2 back to the bottom of the screen */ - window2_info.edge = ABE_BOTTOM; - window2_info.desired_rect.left = 0; - window2_info.desired_rect.right = screen_width; - window2_info.desired_rect.top = screen_height - 10; - window2_info.desired_rect.bottom = screen_height; - testwindow_setpos(window2); - do_events(); - - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - - /* removing window1 will cause window2 to move down into its space */ - expected = max(window1_info.allocated_rect.bottom, window2_info.allocated_rect.bottom); - - SetWindowLongPtr(window1, GWLP_USERDATA, 0); /* don't expect further ABN_POSCHANGED notifications */ - abd.hWnd = window1; + /* dock windows[2] to the bottom of the screen */ + windows[2].registered = TRUE; + windows[2].edge = ABE_BOTTOM; + windows[2].desired_rect.left = 0; + windows[2].desired_rect.right = screen_width; + windows[2].desired_rect.top = screen_height - 10; + windows[2].desired_rect.bottom = screen_height; + SetWindowLongPtr(windows[2].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[2]); + testwindow_setpos(windows[2].hwnd); + + do_events_until(no_appbars_intersect); + test_window_rects(0, 1); + test_window_rects(0, 2); + test_window_rects(1, 2); + + /* move windows[2] to the right side of the screen */ + windows[2].edge = ABE_RIGHT; + windows[2].desired_rect.left = screen_width - 15; + windows[2].desired_rect.right = screen_width; + windows[2].desired_rect.top = 0; + windows[2].desired_rect.bottom = screen_height; + testwindow_setpos(windows[2].hwnd); + + do_events_until(no_appbars_intersect); + test_window_rects(0, 1); + test_window_rects(0, 2); + test_window_rects(1, 2); + + /* move windows[1] to the top of the screen */ + windows[1].edge = ABE_TOP; + windows[1].desired_rect.left = 0; + windows[1].desired_rect.right = screen_width; + windows[1].desired_rect.top = 0; + windows[1].desired_rect.bottom = 15; + testwindow_setpos(windows[1].hwnd); + + do_events_until(no_appbars_intersect); + test_window_rects(0, 1); + test_window_rects(0, 2); + test_window_rects(1, 2); + + /* move windows[1] back to the bottom of the screen */ + windows[1].edge = ABE_BOTTOM; + windows[1].desired_rect.left = 0; + windows[1].desired_rect.right = screen_width; + windows[1].desired_rect.top = screen_height - 10; + windows[1].desired_rect.bottom = screen_height; + testwindow_setpos(windows[1].hwnd); + + do_events_until(no_appbars_intersect); + test_window_rects(0, 1); + test_window_rects(0, 2); + test_window_rects(1, 2); + + /* removing windows[0] will cause windows[1] to move down into its space */ + expected_bottom = max(windows[0].allocated_rect.bottom, windows[1].allocated_rect.bottom); + + abd.hWnd = windows[0].hwnd; ret = SHAppBarMessage(ABM_REMOVE, &abd); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); - do_events(); - DestroyWindow(window1); + windows[0].registered = FALSE; + DestroyWindow(windows[0].hwnd); + + do_events_until(got_expected_bottom); - ok(window2_info.allocated_rect.bottom = expected, "window2's bottom is %i, expected %i\n", window2_info.allocated_rect.bottom, expected); + ok(windows[1].allocated_rect.bottom = expected_bottom, "windows[1]'s bottom is %i, expected %i\n", windows[1].allocated_rect.bottom, expected_bottom); - ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), - "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", - window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, - window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); + test_window_rects(1, 2); /* remove the other windows */ - SetWindowLongPtr(window2, GWLP_USERDATA, 0); - abd.hWnd = window2; + SetWindowLongPtr(windows[1].hwnd, GWLP_USERDATA, 0); + abd.hWnd = windows[1].hwnd; ret = SHAppBarMessage(ABM_REMOVE, &abd); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); - do_events(); - DestroyWindow(window2); + windows[1].registered = FALSE; + DestroyWindow(windows[1].hwnd); - SetWindowLongPtr(window3, GWLP_USERDATA, 0); - abd.hWnd = window3; + SetWindowLongPtr(windows[2].hwnd, GWLP_USERDATA, 0); + abd.hWnd = windows[2].hwnd; ret = SHAppBarMessage(ABM_REMOVE, &abd); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); - do_events(); - DestroyWindow(window3); + windows[2].registered = FALSE; + DestroyWindow(windows[2].hwnd); } static void test_appbarget(void) diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index ba07ebb6b19..c31956c8412 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -385,6 +385,18 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa } break; + case WM_POPUPSYSTEMMENU: + { + /* This is an undocumented message used by the windows taskbar to + display the system menu of windows that belong to other processes. */ + HMENU menu = GetSystemMenu(hwnd, FALSE); + + if (menu) + TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON, + LOWORD(lParam), HIWORD(lParam), 0, hwnd, NULL); + return 0; + } + case WM_NCACTIVATE: return NC_HandleNCActivate( hwnd, wParam, lParam ); diff --git a/dlls/user32/spy.c b/dlls/user32/spy.c index 41caf1d0b0d..9fbd74b3503 100644 --- a/dlls/user32/spy.c +++ b/dlls/user32/spy.c @@ -592,7 +592,8 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_PALETTEISCHANGING", "WM_PALETTECHANGED", "WM_HOTKEY", /* 0x0312 */ - NULL, NULL, NULL, NULL, + "WM_POPUPSYSTEMMENU", /* 0x0313 */ + NULL, NULL, NULL, "WM_PRINT", /* 0x0317 */ "WM_PRINTCLIENT", /* 0x0318 */ "WM_APPCOMMAND", /* 0x0319 */ diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 2a2644706b7..aac6d61ef57 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -371,6 +371,7 @@ static void empty_message_queue(void) { struct transition_s { WORD wVk; BYTE before_state; + BYTE optional; }; typedef enum { @@ -448,11 +449,12 @@ struct sendinput_test_s { /* test L-SHIFT & R-SHIFT: */ /* RSHIFT == LSHIFT */ {VK_RSHIFT, 0, 0, - {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}}, + /* recent windows versions (>= w2k3) correctly report an RSHIFT transition */ + {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00, TRUE}, {VK_RSHIFT, 0x00, TRUE}, {0}}, {{WM_KEYDOWN, hook|wparam, VK_RSHIFT}, {WM_KEYDOWN}, {0}}}, {VK_RSHIFT, KEYEVENTF_KEYUP, 0, - {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}}, + {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80, TRUE}, {VK_RSHIFT, 0x80, TRUE}, {0}}, {{WM_KEYUP, hook, hook|wparam, VK_RSHIFT}, {WM_KEYUP}, {0}}}, @@ -643,7 +645,7 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes ~t->before_state&0x80); } } else { - ok(matched, "%02d: %02x from %02x -> %02x " + ok(matched || t->optional, "%02d: %02x from %02x -> %02x " "instead of %02x -> %02x\n", id, t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state, ~t->before_state&0x80); @@ -1008,19 +1010,19 @@ static void test_GetMouseMovePointsEx(void) SetLastError(MYERROR); retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); /* test second and third parameter @@ -1028,7 +1030,7 @@ static void test_GetMouseMovePointsEx(void) SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_NOACCESS == GetLastError(), + ok(GetLastError() == ERROR_NOACCESS || GetLastError() == MYERROR, "expected error ERROR_NOACCESS, got %u\n", GetLastError()); SetLastError(MYERROR); @@ -1059,7 +1061,7 @@ static void test_GetMouseMovePointsEx(void) count = -1; retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS); ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); SetLastError(MYERROR); @@ -1083,7 +1085,7 @@ static void test_GetMouseMovePointsEx(void) SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); /* it was not possible to force an error with the fifth parameter on win2k */ @@ -1092,25 +1094,25 @@ static void test_GetMouseMovePointsEx(void) SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); SetLastError(MYERROR); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); - ok(ERROR_INVALID_PARAMETER == GetLastError(), + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR, "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); #undef BUFLIM diff --git a/dlls/user32/tests/listbox.c b/dlls/user32/tests/listbox.c index ff216aa1c84..6d4050f2b79 100644 --- a/dlls/user32/tests/listbox.c +++ b/dlls/user32/tests/listbox.c @@ -44,7 +44,7 @@ static const char * const strings[4] = { "Fourth added which is very long because at some time we only had a 256 byte character buffer and that was overflowing in one of those applications that had a common dialog file open box and tried to add a 300 characters long custom filter string which of course the code did not like and crashed. Just make sure this string is longer than 256 characters." }; -static const char BAD_EXTENSION[] = "*.txtbad"; +static const char BAD_EXTENSION[] = "*.badtxt"; static HWND create_listbox (DWORD add_style, HWND parent) @@ -458,18 +458,18 @@ static void test_itemfrompoint(void) HWND hList = CreateWindow( "ListBox", "list test", WS_VISIBLE|WS_POPUP|LBS_NOINTEGRALHEIGHT, 1, 1, 600, 100, NULL, NULL, NULL, NULL ); - LONG r, id; + ULONG r, id; RECT rc; - /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000 */ + /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */ r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 )); - ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r ); + ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r ); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 )); - ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r ); + ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r ); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 )); - ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r ); + ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r ); id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi"); ok( id == 0, "item id wrong\n"); @@ -480,7 +480,8 @@ static void test_itemfrompoint(void) ok( r == 0x1, "ret %x\n", r ); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 )); - ok( r == 0x10001, "ret %x\n", r ); + ok( r == 0x10001 || broken(r == 1), /* nt4 */ + "ret %x\n", r ); /* Resize control so that below assertions about sizes are valid */ r = SendMessage( hList, LB_GETITEMRECT, 0, (LPARAM)&rc); @@ -517,16 +518,20 @@ static void test_itemfrompoint(void) ok( r == 1, "ret %x\n", r); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) ); - ok( r == 0x10001, "ret %x\n", r ); + ok( r == 0x10001 || broken(r == 1), /* nt4 */ + "ret %x\n", r ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) ); - ok( r == 0x10001, "ret %x\n", r ); + ok( r == 0x10001 || broken(r == 1), /* nt4 */ + "ret %x\n", r ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) ); - ok( r == 0x10005, "item %x\n", r ); + ok( r == 0x10005 || broken(r == 5), /* nt4 */ + "item %x\n", r ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) ); - ok( r == 0x10005, "item %x\n", r ); + ok( r == 0x10005 || broken(r == 5), /* nt4 */ + "item %x\n", r ); DestroyWindow( hList ); } @@ -585,6 +590,11 @@ static void test_listbox_LB_DIR() strcpy(pathBuffer, "*"); SendMessage(hList, LB_RESETCONTENT, 0, 0); res = SendMessage(hList, LB_DIR, 0, (LPARAM)pathBuffer); + if (res == -1) /* "*" wildcard doesn't work on win9x */ + { + strcpy(pathBuffer, "*.*"); + res = SendMessage(hList, LB_DIR, 0, (LPARAM)pathBuffer); + } ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError()); /* There should be some content in the listbox */ @@ -640,6 +650,11 @@ static void test_listbox_LB_DIR() strcpy(pathBuffer, "*"); SendMessage(hList, LB_RESETCONTENT, 0, 0); res = SendMessage(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer); + if (res == -1) /* "*" wildcard doesn't work on win9x */ + { + strcpy(pathBuffer, "*.*"); + res = SendMessage(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer); + } ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError()); /* There should be some content in the listbox. diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 3d2fd1e9226..c78401aeadf 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -156,11 +156,13 @@ static const struct message WmSWP_ShowOverlappedSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, /* Win9x adds SWP_NOZORDER below */ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_GETTEXT, sent|optional }, { WM_NCCALCSIZE, sent|wparam|optional, 1 }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, @@ -416,12 +418,14 @@ static const struct message WmShowOverlappedSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, /* Win9x adds SWP_NOZORDER below */ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { WM_NCCALCSIZE, sent|optional }, + { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|optional }, { WM_ERASEBKGND, sent|optional }, #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE @@ -456,6 +460,7 @@ static const struct message WmShowMaxOverlappedSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, @@ -463,6 +468,7 @@ static const struct message WmShowMaxOverlappedSeq[] = { { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_STATECHANGED }, { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc|wparam, SIZE_MAXIMIZED }, + { WM_GETTEXT, sent|optional }, { WM_NCCALCSIZE, sent|optional }, { WM_NCPAINT, sent|optional }, { WM_ERASEBKGND, sent|optional }, @@ -513,6 +519,7 @@ static const struct message WmShowRestoreMinOverlappedSeq[] = { { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent }, @@ -523,6 +530,7 @@ static const struct message WmShowRestoreMinOverlappedSeq[] = { { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, { WM_ACTIVATE, sent|wparam, 1 }, + { WM_GETTEXT, sent|optional }, { WM_PAINT, sent|optional }, { WM_NCPAINT, sent|beginpaint|optional }, { WM_ERASEBKGND, sent|beginpaint|optional }, @@ -626,6 +634,7 @@ static const struct message WmCreateMaxPopupSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_SYNCPAINT, sent|wparam|optional, 4 }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, @@ -670,6 +679,7 @@ static const struct message WmShowMaxPopupResizedSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, { WM_WINDOWPOSCHANGED, sent }, @@ -698,6 +708,7 @@ static const struct message WmShowMaxPopupSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_SYNCPAINT, sent|wparam|optional, 4 }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, @@ -731,6 +742,7 @@ static const struct message WmCreatePopupSeq[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_GETTEXT, sent|optional }, { WM_SYNCPAINT, sent|wparam|optional, 4 }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, @@ -743,6 +755,7 @@ static const struct message WmShowVisMaxPopupSeq[] = { { WM_GETMINMAXINFO, sent }, { WM_GETTEXT, sent|optional }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_STATECHANGED }, + { WM_GETTEXT, sent|optional }, { WM_NCCALCSIZE, sent|wparam, TRUE }, { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, { WM_NCPAINT, sent|wparam|optional, 1 }, @@ -804,6 +817,7 @@ static const struct message WmShowVisiblePopupSeq_3[] = { { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|defwinproc }, + { WM_GETTEXT, sent|optional }, { 0 } }; /* CreateWindow (for child window, not initially visible) */ @@ -1177,6 +1191,7 @@ static const struct message WmCreateCustomDialogSeq[] = { { WM_GETTEXT, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_ACTIVATE, sent|wparam, 1 }, + { WM_GETTEXT, sent|optional }, { WM_KILLFOCUS, sent|parent }, { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 }, { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, @@ -1239,6 +1254,7 @@ static const struct message WmShowCustomDialogSeq[] = { { WM_ACTIVATEAPP, sent|wparam|optional, 1 }, { WM_NCACTIVATE, sent|wparam, 1 }, { WM_ACTIVATE, sent|wparam, 1 }, + { WM_GETTEXT, sent|optional }, { WM_KILLFOCUS, sent|parent }, { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 }, @@ -1574,6 +1590,10 @@ static const struct message WmSHOWNAChildInvisParVis[] = { static const struct message WmSHOWNATopVisible[] = { { WM_SHOWWINDOW, sent|wparam, 1 }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|optional }, { 0 } }; static const struct message WmSHOWNATopInvisible[] = { @@ -1869,10 +1889,10 @@ static const struct message WmCreateMDIframeSeq[] = { static const struct message WmDestroyMDIframeSeq[] = { { HCBT_DESTROYWND, hook }, { 0x0090, sent|optional }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, { WM_NCACTIVATE, sent|wparam|optional, 0 }, /* Win9x */ - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { WM_NCACTIVATE, sent|wparam|optional, 0 }, /* XP */ { WM_ACTIVATE, sent|wparam|optional, 0 }, /* Win9x */ { WM_ACTIVATEAPP, sent|wparam|optional, 0 }, /* Win9x */ @@ -1895,26 +1915,26 @@ static const struct message WmCreateMDIclientSeq[] = { { WM_MOVE, sent }, { WM_PARENTNOTIFY, sent|wparam, WM_CREATE }, /* in MDI frame */ { WM_SHOWWINDOW, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { 0 } }; /* ShowWindow(SW_SHOW) for MDI client window */ static const struct message WmShowMDIclientSeq[] = { { WM_SHOWWINDOW, sent|wparam, 1 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { 0 } }; /* ShowWindow(SW_HIDE) for MDI client window */ static const struct message WmHideMDIclientSeq[] = { { WM_SHOWWINDOW, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam|optional, 0, 0 }, /* win2000 */ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP */ - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { 0 } }; /* DestroyWindow for MDI client window, initially visible */ @@ -1923,9 +1943,9 @@ static const struct message WmDestroyMDIclientSeq[] = { { 0x0090, sent|optional }, { WM_PARENTNOTIFY, sent|wparam, WM_DESTROY }, /* in MDI frame */ { WM_SHOWWINDOW, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, { WM_DESTROY, sent }, { WM_NCDESTROY, sent }, @@ -2018,10 +2038,10 @@ static const struct message WmDestroyMDIchildVisibleSeq[] = { { 0x0090, sent|optional }, { WM_PARENTNOTIFY, sent /*|wparam, WM_DESTROY*/ }, /* in MDI client */ { WM_SHOWWINDOW, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, { WM_ERASEBKGND, sent|parent|optional }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, /* { WM_DESTROY, sent } * Win9x: message sequence terminates here. @@ -2637,10 +2657,10 @@ static const struct message WmDestroyMDIchildVisibleMaxSeq1[] = { { WM_PARENTNOTIFY, sent /*|wparam, WM_DESTROY*/ }, /* in MDI client */ { WM_SHOWWINDOW, sent|wparam, 0 }, - { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, { WM_ERASEBKGND, sent|parent|optional }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, { WM_DESTROY, sent }, @@ -8438,7 +8458,9 @@ static DWORD CALLBACK send_msg_thread( LPVOID arg ) struct sendmsg_info *info = arg; SetLastError( 0xdeadbeef ); info->ret = SendMessageTimeoutA( info->hwnd, WM_USER, 0, 0, 0, info->timeout, NULL ); - if (!info->ret) ok( GetLastError() == ERROR_TIMEOUT, "unexpected error %d\n", GetLastError()); + if (!info->ret) ok( GetLastError() == ERROR_TIMEOUT || + broken(GetLastError() == 0), /* win9x */ + "unexpected error %d\n", GetLastError()); return 0; } @@ -8462,6 +8484,7 @@ static void test_SendMessageTimeout(void) HANDLE thread; struct sendmsg_info info; DWORD tid; + BOOL is_win9x; info.hwnd = CreateWindowA( "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL); @@ -8485,17 +8508,18 @@ static void test_SendMessageTimeout(void) ok( info.ret == 0, "SendMessageTimeout succeeded\n" ); ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); - /* 0 means infinite timeout */ + /* 0 means infinite timeout (but not on win9x) */ info.timeout = 0; info.ret = 0xdeadbeef; thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); Sleep(100); wait_for_thread( thread ); CloseHandle( thread ); - ok( info.ret == 1, "SendMessageTimeout failed\n" ); - ok_sequence( WmUser, "WmUser", FALSE ); + is_win9x = !info.ret; + if (is_win9x) ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + else ok_sequence( WmUser, "WmUser", FALSE ); - /* timeout is treated as signed despite the prototype */ + /* timeout is treated as signed despite the prototype (but not on win9x) */ info.timeout = 0x7fffffff; info.ret = 0xdeadbeef; thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); @@ -8511,8 +8535,16 @@ static void test_SendMessageTimeout(void) Sleep(100); wait_for_thread( thread ); CloseHandle( thread ); - ok( info.ret == 0, "SendMessageTimeout succeeded\n" ); - ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + if (is_win9x) + { + ok( info.ret == 1, "SendMessageTimeout failed\n" ); + ok_sequence( WmUser, "WmUser", FALSE ); + } + else + { + ok( info.ret == 0, "SendMessageTimeout succeeded\n" ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + } /* now check for timeout during message processing */ SetWindowLongPtrA( info.hwnd, GWLP_WNDPROC, (LONG_PTR)send_msg_delay_proc ); @@ -8837,6 +8869,7 @@ static void test_PeekMessage(void) DWORD tid, qstatus; UINT qs_all_input = QS_ALLINPUT; UINT qs_input = QS_INPUT; + UINT qs_sendmessage = 0; BOOL ret; struct peekmsg_info info; @@ -8920,6 +8953,12 @@ static void test_PeekMessage(void) ok(!ret, "PeekMessageA should have returned FALSE instead of msg %04x\n", msg.message); + if (!sequence_cnt) /* nt4 needs explicit PM_QS_SENDMESSAGE to process sent messages */ + { + qs_sendmessage = QS_SENDMESSAGE; + ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | ((qs_input|qs_sendmessage) << 16)); + ok(!ret, "PeekMessageA should have returned FALSE instead of msg %04x\n", msg.message); + } ok_sequence(WmUser, "WmUser", FALSE); qstatus = GetQueueStatus(qs_all_input); @@ -8935,7 +8974,7 @@ static void test_PeekMessage(void) "wrong qstatus %08x\n", qstatus); msg.message = 0; - ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE); + ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE | (qs_sendmessage << 16) ); ok(!ret, "PeekMessageA should have returned FALSE instead of msg %04x\n", msg.message); @@ -9424,17 +9463,20 @@ static void test_TrackMouseEvent(void) default_hover_time = 0xdeadbeef; SetLastError(0xdeadbeef); ret = SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, &default_hover_time, 0); - ok(ret, "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError()); + ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */ + "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError()); if (!ret) default_hover_time = 400; trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time); SetLastError(0xdeadbeef); ret = SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH, 0, &hover_width, 0); - ok(ret, "SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError()); + ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */ + "SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError()); if (!ret) hover_width = 4; SetLastError(0xdeadbeef); ret = SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT, 0, &hover_height, 0); - ok(ret, "SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError()); + ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */ + "SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError()); if (!ret) hover_height = 4; trace("hover rect is %u x %d\n", hover_width, hover_height); @@ -10206,6 +10248,7 @@ static const struct message SetActiveWindowSeq0[] = { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { WM_SETFOCUS, sent|defwinproc }, + { WM_GETTEXT, sent|optional }, { 0 } }; /* SetActiveWindow( hwnd ) hwnd visible */ @@ -10238,6 +10281,7 @@ static const struct message SetActiveWindowSeq2[] = { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, { WM_SETFOCUS, sent|defwinproc }, + { WM_GETTEXT, sent|optional }, { 0 } }; diff --git a/dlls/user32/tests/winstation.c b/dlls/user32/tests/winstation.c index 42f2644b295..efc122a32dc 100644 --- a/dlls/user32/tests/winstation.c +++ b/dlls/user32/tests/winstation.c @@ -122,7 +122,9 @@ static void test_handles(void) flags = 0; ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" ); - ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), "handle %p PROTECT_FROM_CLOSE set\n", w1 ); + ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) || + broken(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), /* set on nt4 */ + "handle %p PROTECT_FROM_CLOSE set\n", w1 ); ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); @@ -201,7 +203,11 @@ static void test_handles(void) ok( GetLastError() == ERROR_BUSY, "bad last error %d\n", GetLastError() ); SetLastError( 0xdeadbeef ); - ok( !CloseHandle(d1), "closing thread desktop handle failed\n" ); + if (CloseHandle( d1 )) /* succeeds on nt4 */ + { + win_skip( "NT4 desktop handle management is completely different\n" ); + return; + } ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() ); ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0, diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index da635b0ab48..40e57e1f096 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -82,6 +82,7 @@ static inline HLOCAL16 LOCAL_Free( HANDLE16 ds, HLOCAL16 handle ) #define GET_DWORD(ptr) (*(const DWORD *)(ptr)) #define WM_SYSTIMER 0x0118 +#define WM_POPUPSYSTEMMENU 0x0313 /* internal messages codes */ enum wine_internal_message diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c index d277f360411..df2774b6b6a 100644 --- a/dlls/userenv/tests/userenv.c +++ b/dlls/userenv/tests/userenv.c @@ -189,14 +189,22 @@ static void test_create_env(void) r = SetEnvironmentVariableA("WINE_XYZZY", "ZZYZX"); expect(TRUE, r); - r = CreateEnvironmentBlock(NULL, NULL, FALSE); - expect(FALSE, r); + if (0) + { + /* Crashes on NT4 */ + r = CreateEnvironmentBlock(NULL, NULL, FALSE); + expect(FALSE, r); + } r = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htok); expect(TRUE, r); - r = CreateEnvironmentBlock(NULL, htok, FALSE); - expect(FALSE, r); + if (0) + { + /* Crashes on NT4 */ + r = CreateEnvironmentBlock(NULL, htok, FALSE); + expect(FALSE, r); + } r = CreateEnvironmentBlock((LPVOID) &env1, NULL, FALSE); expect(TRUE, r); diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 2bb70c30a12..233098b7299 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -956,7 +956,7 @@ static inline void pshader_gen_output_modifier_line( regstr, write_mask, regstr, shift_tab[shift]); } -void pshader_hw_bem(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_bem(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; SHADER_BUFFER* buffer = arg->buffer; @@ -994,7 +994,7 @@ void pshader_hw_bem(SHADER_OPCODE_ARG* arg) { } } -void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; SHADER_BUFFER* buffer = arg->buffer; @@ -1028,7 +1028,7 @@ void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) { pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name); } -void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; char dst_wmask[20]; @@ -1057,7 +1057,7 @@ void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_DP2ADD instruction in ARB. * dst = dot2(src0, src1) + src2 */ -void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; char dst_wmask[20]; char dst_name[50]; @@ -1083,74 +1083,122 @@ void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg) { } /* Map the opcode 1-to-1 to the GL code */ -void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { +static void shader_hw_map2gl(SHADER_OPCODE_ARG* arg) +{ + IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader; + CONST SHADER_OPCODE* curOpcode = arg->opcode; + SHADER_BUFFER* buffer = arg->buffer; + DWORD dst = arg->dst; + DWORD* src = arg->src; - CONST SHADER_OPCODE* curOpcode = arg->opcode; - SHADER_BUFFER* buffer = arg->buffer; - DWORD dst = arg->dst; - DWORD* src = arg->src; - - unsigned int i; - char tmpLine[256]; - - /* Output token related */ - char output_rname[256]; - char output_wmask[20]; - BOOL saturate = FALSE; - BOOL centroid = FALSE; - BOOL partialprecision = FALSE; - DWORD shift; - - strcpy(tmpLine, curOpcode->glname); - - /* Process modifiers */ - if (0 != (dst & WINED3DSP_DSTMOD_MASK)) { - DWORD mask = dst & WINED3DSP_DSTMOD_MASK; - - saturate = mask & WINED3DSPDM_SATURATE; - centroid = mask & WINED3DSPDM_MSAMPCENTROID; - partialprecision = mask & WINED3DSPDM_PARTIALPRECISION; - mask &= ~(WINED3DSPDM_MSAMPCENTROID | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_SATURATE); - if (mask) - FIXME("Unrecognized modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT); - - if (centroid) - FIXME("Unhandled modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT); - } - shift = (dst & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - - /* Generate input and output registers */ - if (curOpcode->num_params > 0) { - char operands[4][100]; - - /* Generate input register names (with modifiers) */ - for (i = 1; i < curOpcode->num_params; ++i) - pshader_gen_input_modifier_line(arg->shader, buffer, src[i-1], i-1, operands[i]); - - /* Handle output register */ - pshader_get_register_name(arg->shader, dst, output_rname); - strcpy(operands[0], output_rname); - shader_arb_get_write_mask(arg, dst, output_wmask); - strcat(operands[0], output_wmask); - - if (saturate && (shift == 0)) - strcat(tmpLine, "_SAT"); - strcat(tmpLine, " "); - strcat(tmpLine, operands[0]); - for (i = 1; i < curOpcode->num_params; i++) { - strcat(tmpLine, ", "); - strcat(tmpLine, operands[i]); - } - strcat(tmpLine,";\n"); - shader_addline(buffer, tmpLine); + char tmpLine[256]; + unsigned int i; - /* A shift requires another line. */ - if (shift != 0) - pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname); - } + if (shader_is_pshader_version(shader->baseShader.hex_version)) + { + BOOL saturate = FALSE; + BOOL centroid = FALSE; + BOOL partialprecision = FALSE; + DWORD shift; + + strcpy(tmpLine, curOpcode->glname); + + /* Process modifiers */ + if (dst & WINED3DSP_DSTMOD_MASK) + { + DWORD mask = dst & WINED3DSP_DSTMOD_MASK; + + saturate = mask & WINED3DSPDM_SATURATE; + centroid = mask & WINED3DSPDM_MSAMPCENTROID; + partialprecision = mask & WINED3DSPDM_PARTIALPRECISION; + mask &= ~(WINED3DSPDM_MSAMPCENTROID | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_SATURATE); + if (mask) + FIXME("Unrecognized modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT); + + if (centroid) + FIXME("Unhandled modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT); + } + shift = (dst & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; + + /* Generate input and output registers */ + if (curOpcode->num_params > 0) + { + /* Output token related */ + char output_rname[256]; + char output_wmask[20]; + char operands[4][100]; + + /* Generate input register names (with modifiers) */ + for (i = 1; i < curOpcode->num_params; ++i) + pshader_gen_input_modifier_line(arg->shader, buffer, src[i-1], i-1, operands[i]); + + /* Handle output register */ + pshader_get_register_name(arg->shader, dst, output_rname); + strcpy(operands[0], output_rname); + shader_arb_get_write_mask(arg, dst, output_wmask); + strcat(operands[0], output_wmask); + + if (saturate && (shift == 0)) + strcat(tmpLine, "_SAT"); + strcat(tmpLine, " "); + strcat(tmpLine, operands[0]); + for (i = 1; i < curOpcode->num_params; i++) + { + strcat(tmpLine, ", "); + strcat(tmpLine, operands[i]); + } + strcat(tmpLine,";\n"); + shader_addline(buffer, tmpLine); + + /* A shift requires another line. */ + if (shift != 0) + pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname); + } + } else { + if ((curOpcode->opcode == WINED3DSIO_MOV && shader_get_regtype(dst) == WINED3DSPR_ADDR) + || curOpcode->opcode == WINED3DSIO_MOVA) { + memset(tmpLine, 0, sizeof(tmpLine)); + if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) + { + 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"); + } else { + /* 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); + + if (curOpcode->num_params > 0) + { + vshader_program_add_param(arg, dst, FALSE, tmpLine); + for (i = 1; i < curOpcode->num_params; ++i) + { + strcat(tmpLine, ","); + vshader_program_add_param(arg, src[i-1], TRUE, tmpLine); + } + } + shader_addline(buffer, "%s;\n", tmpLine); + } } -void pshader_hw_texkill(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texkill(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; DWORD hex_version = This->baseShader.hex_version; SHADER_BUFFER* buffer = arg->buffer; @@ -1174,7 +1222,7 @@ void pshader_hw_texkill(SHADER_OPCODE_ARG* arg) { } } -void pshader_hw_tex(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_tex(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; @@ -1238,7 +1286,7 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* arg) { shader_hw_sample(arg, reg_sampler_code, reg_dest, reg_coord, projected, bias); } -void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; DWORD dst = arg->dst; @@ -1259,7 +1307,7 @@ void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg) { } } -void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; @@ -1278,7 +1326,7 @@ void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg) { shader_hw_sample(arg, reg1, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE); } -void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; @@ -1293,7 +1341,7 @@ void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) { shader_hw_sample(arg, reg1, dst_str, "TMP", FALSE, FALSE); } -void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; DWORD reg1 = arg->dst & WINED3DSP_REGNUM_MASK; @@ -1305,7 +1353,7 @@ void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg) { shader_hw_sample(arg, reg1, dst_str, src_str, FALSE, FALSE); } -void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; BOOL has_bumpmat = FALSE; BOOL has_luminance = FALSE; @@ -1376,7 +1424,7 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) { } } -void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) { DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; SHADER_BUFFER* buffer = arg->buffer; @@ -1386,7 +1434,7 @@ void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) { shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name); } -void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; @@ -1403,7 +1451,7 @@ void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) { shader_hw_sample(arg, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE); } -void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; @@ -1416,7 +1464,7 @@ void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) { current_state->texcoord_w[current_state->current_row++] = reg; } -void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; @@ -1437,7 +1485,7 @@ void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) { current_state->current_row = 0; } -void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; @@ -1473,7 +1521,7 @@ void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) { current_state->current_row = 0; } -void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; @@ -1510,7 +1558,7 @@ void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) { current_state->current_row = 0; } -void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; char dst_name[50]; @@ -1539,7 +1587,7 @@ void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB: * Take a 3-component dot product of the TexCoord[dstreg] and src, * then perform a 1D texture lookup from stage dstregnum, place into dst. */ -void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; char src0[50]; @@ -1555,7 +1603,7 @@ void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXDP3 instruction in ARB: * Take a 3-component dot product of the TexCoord[dstreg] and src. */ -void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg) { char src0[50]; char dst_str[50]; char dst_mask[6]; @@ -1574,7 +1622,7 @@ void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X3 instruction in ARB * Perform the 3rd row of a 3x3 matrix multiply */ -void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; char dst_str[50]; char dst_mask[6]; @@ -1596,7 +1644,7 @@ void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg) { * Calculate tmp0.y = TexCoord[dstreg] . src.xyz; (tmp0.x has already been calculated) * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y */ -void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg) { +static void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; DWORD dst_reg = arg->dst & WINED3DSP_REGNUM_MASK; char src0[50]; @@ -1616,7 +1664,7 @@ void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg) { /** Handles transforming all WINED3DSIO_M?x? opcodes for Vertex/Pixel shaders to ARB_vertex_program codes */ -void shader_hw_mnxn(SHADER_OPCODE_ARG* arg) { +static void shader_hw_mnxn(SHADER_OPCODE_ARG* arg) { int i; int nComponents = 0; @@ -1660,11 +1708,11 @@ void shader_hw_mnxn(SHADER_OPCODE_ARG* arg) { for (i = 0; i < nComponents; i++) { tmpArg.dst = ((arg->dst) & ~WINED3DSP_WRITEMASK_ALL)|(WINED3DSP_WRITEMASK_0<src[1]+i; - vshader_hw_map2gl(&tmpArg); + shader_hw_map2gl(&tmpArg); } } -void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg) { +static void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg) { CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; DWORD dst = arg->dst; @@ -1687,7 +1735,7 @@ void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg) { shader_addline(buffer, "%s;\n", tmpLine); } -void shader_hw_nrm(SHADER_OPCODE_ARG* arg) { +static void shader_hw_nrm(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; char dst_name[50]; char src_name[50]; @@ -1709,7 +1757,7 @@ void shader_hw_nrm(SHADER_OPCODE_ARG* arg) { pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name); } -void shader_hw_sincos(SHADER_OPCODE_ARG* arg) { +static void shader_hw_sincos(SHADER_OPCODE_ARG* arg) { /* This instruction exists in ARB, but the d3d instruction takes two extra parameters which * must contain fixed constants. So we need a separate function to filter those constants and * can't use map2gl @@ -1733,58 +1781,6 @@ void shader_hw_sincos(SHADER_OPCODE_ARG* arg) { } -/* TODO: merge with pixel shader */ -/* Map the opcode 1-to-1 to the GL code */ -void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg) { - - IWineD3DVertexShaderImpl *shader = (IWineD3DVertexShaderImpl*) arg->shader; - CONST SHADER_OPCODE* curOpcode = arg->opcode; - SHADER_BUFFER* buffer = arg->buffer; - DWORD dst = arg->dst; - DWORD* src = arg->src; - - DWORD dst_regtype = shader_get_regtype(dst); - char tmpLine[256]; - 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) { - 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"); - } else { - /* 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); - - if (curOpcode->num_params > 0) { - vshader_program_add_param(arg, dst, FALSE, tmpLine); - for (i = 1; i < curOpcode->num_params; ++i) { - strcat(tmpLine, ","); - vshader_program_add_param(arg, src[i-1], TRUE, tmpLine); - } - } - shader_addline(buffer, "%s;\n", tmpLine); -} - static GLuint create_arb_blt_vertex_program(WineD3D_GL_Info *gl_info) { GLuint program_id = 0; const char *blt_vprogram = @@ -2219,7 +2215,95 @@ static BOOL shader_arb_conv_supported(WINED3DFORMAT fmt) { } } +static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = +{ + /* WINED3DSIH_ABS */ shader_hw_map2gl, + /* WINED3DSIH_ADD */ shader_hw_map2gl, + /* WINED3DSIH_BEM */ pshader_hw_bem, + /* WINED3DSIH_BREAK */ NULL, + /* WINED3DSIH_BREAKC */ NULL, + /* WINED3DSIH_BREAKP */ NULL, + /* WINED3DSIH_CALL */ NULL, + /* WINED3DSIH_CALLNZ */ NULL, + /* WINED3DSIH_CMP */ pshader_hw_cmp, + /* WINED3DSIH_CND */ pshader_hw_cnd, + /* WINED3DSIH_CRS */ shader_hw_map2gl, + /* WINED3DSIH_DCL */ NULL, + /* WINED3DSIH_DEF */ NULL, + /* WINED3DSIH_DEFB */ NULL, + /* WINED3DSIH_DEFI */ NULL, + /* WINED3DSIH_DP2ADD */ pshader_hw_dp2add, + /* WINED3DSIH_DP3 */ shader_hw_map2gl, + /* WINED3DSIH_DP4 */ shader_hw_map2gl, + /* WINED3DSIH_DST */ shader_hw_map2gl, + /* WINED3DSIH_DSX */ NULL, + /* WINED3DSIH_DSY */ NULL, + /* WINED3DSIH_ELSE */ NULL, + /* WINED3DSIH_ENDIF */ NULL, + /* WINED3DSIH_ENDLOOP */ NULL, + /* WINED3DSIH_ENDREP */ NULL, + /* WINED3DSIH_EXP */ shader_hw_map2gl, + /* WINED3DSIH_EXPP */ shader_hw_map2gl, + /* WINED3DSIH_FRC */ shader_hw_map2gl, + /* WINED3DSIH_IF */ NULL, + /* WINED3DSIH_IFC */ NULL, + /* WINED3DSIH_LABEL */ NULL, + /* WINED3DSIH_LIT */ shader_hw_map2gl, + /* WINED3DSIH_LOG */ shader_hw_map2gl, + /* WINED3DSIH_LOGP */ shader_hw_map2gl, + /* WINED3DSIH_LOOP */ NULL, + /* WINED3DSIH_LRP */ shader_hw_map2gl, + /* WINED3DSIH_M3x2 */ shader_hw_mnxn, + /* WINED3DSIH_M3x3 */ shader_hw_mnxn, + /* WINED3DSIH_M3x4 */ shader_hw_mnxn, + /* WINED3DSIH_M4x3 */ shader_hw_mnxn, + /* WINED3DSIH_M4x4 */ shader_hw_mnxn, + /* WINED3DSIH_MAD */ shader_hw_map2gl, + /* WINED3DSIH_MAX */ shader_hw_map2gl, + /* WINED3DSIH_MIN */ shader_hw_map2gl, + /* WINED3DSIH_MOV */ shader_hw_map2gl, + /* WINED3DSIH_MOVA */ shader_hw_map2gl, + /* WINED3DSIH_MUL */ shader_hw_map2gl, + /* WINED3DSIH_NOP */ shader_hw_map2gl, + /* WINED3DSIH_NRM */ shader_hw_nrm, + /* WINED3DSIH_PHASE */ NULL, + /* WINED3DSIH_POW */ shader_hw_map2gl, + /* WINED3DSIH_RCP */ vshader_hw_rsq_rcp, + /* WINED3DSIH_REP */ NULL, + /* WINED3DSIH_RET */ NULL, + /* WINED3DSIH_RSQ */ vshader_hw_rsq_rcp, + /* WINED3DSIH_SETP */ NULL, + /* WINED3DSIH_SGE */ shader_hw_map2gl, + /* WINED3DSIH_SGN */ NULL, + /* WINED3DSIH_SINCOS */ shader_hw_sincos, + /* WINED3DSIH_SLT */ shader_hw_map2gl, + /* WINED3DSIH_SUB */ shader_hw_map2gl, + /* WINED3DSIH_TEX */ pshader_hw_tex, + /* WINED3DSIH_TEXBEM */ pshader_hw_texbem, + /* WINED3DSIH_TEXBEML */ pshader_hw_texbem, + /* WINED3DSIH_TEXCOORD */ pshader_hw_texcoord, + /* WINED3DSIH_TEXDEPTH */ pshader_hw_texdepth, + /* WINED3DSIH_TEXDP3 */ pshader_hw_texdp3, + /* WINED3DSIH_TEXDP3TEX */ pshader_hw_texdp3tex, + /* WINED3DSIH_TEXKILL */ pshader_hw_texkill, + /* WINED3DSIH_TEXLDD */ NULL, + /* WINED3DSIH_TEXLDL */ NULL, + /* WINED3DSIH_TEXM3x2DEPTH */ pshader_hw_texm3x2depth, + /* WINED3DSIH_TEXM3x2PAD */ pshader_hw_texm3x2pad, + /* WINED3DSIH_TEXM3x2TEX */ pshader_hw_texm3x2tex, + /* WINED3DSIH_TEXM3x3 */ pshader_hw_texm3x3, + /* WINED3DSIH_TEXM3x3DIFF */ NULL, + /* WINED3DSIH_TEXM3x3PAD */ pshader_hw_texm3x3pad, + /* WINED3DSIH_TEXM3x3SPEC */ pshader_hw_texm3x3spec, + /* WINED3DSIH_TEXM3x3TEX */ pshader_hw_texm3x3tex, + /* WINED3DSIH_TEXM3x3VSPEC */ pshader_hw_texm3x3vspec, + /* WINED3DSIH_TEXREG2AR */ pshader_hw_texreg2ar, + /* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb, + /* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb, +}; + const shader_backend_t arb_program_shader_backend = { + shader_arb_instruction_handler_table, shader_arb_select, shader_arb_select_depth_blt, shader_arb_deselect_depth_blt, diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 82187fc1a11..4c98f5a1b95 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -790,6 +790,7 @@ void shader_generate_main( IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */ + const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table; const DWORD *pToken = pFunction; const SHADER_OPCODE *curOpcode = NULL; SHADER_HANDLER hw_fct = NULL; @@ -828,10 +829,8 @@ void shader_generate_main( /* Select handler */ if (curOpcode == NULL) hw_fct = NULL; - else if (This->baseShader.shader_mode == SHADER_GLSL) - hw_fct = curOpcode->hw_glsl_fct; - else if (This->baseShader.shader_mode == SHADER_ARB) - hw_fct = curOpcode->hw_fct; + else + hw_fct = handler_table[curOpcode->handler_idx]; /* Unknown opcode and its parameters */ if (NULL == curOpcode) { @@ -883,6 +882,8 @@ void shader_generate_main( device->shader_backend->shader_color_correction(&hw_arg); /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */ + /* FIXME: This should be internal to the shader backend. + * Also, right now this is the only reason "shader_mode" exists. */ if (This->baseShader.shader_mode == SHADER_GLSL) shader_glsl_add_instruction_modifiers(&hw_arg); @@ -1089,6 +1090,7 @@ void shader_trace_init( } } +static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0}; static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {} static void shader_none_select_depth_blt(IWineD3DDevice *iface) {} static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {} @@ -1132,6 +1134,7 @@ static BOOL shader_none_conv_supported(WINED3DFORMAT fmt) { } const shader_backend_t none_shader_backend = { + shader_none_instruction_handler_table, shader_none_select, shader_none_select_depth_blt, shader_none_deselect_depth_blt, diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 76d449ad7ea..2aeb5fa7e76 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -77,7 +77,8 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; IWineD3DBaseTextureImpl *texture_impl; - BOOL update_minfilter, update_magfilter; + BOOL update_minfilter = FALSE; + BOOL update_magfilter = FALSE; /* Update base texture states array */ if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) @@ -225,7 +226,7 @@ static struct fbo_entry *context_create_fbo_entry(IWineD3DDevice *iface) return entry; } -void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry *entry) +static void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry *entry) { if (entry->id) { @@ -319,6 +320,46 @@ static void context_apply_fbo_state(IWineD3DDevice *iface) context_check_fbo_status(iface); } +void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + UINT i; + + switch(type) + { + case WINED3DRTYPE_SURFACE: + { + for (i = 0; i < This->numContexts; ++i) + { + struct fbo_entry *entry, *entry2; + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->contexts[i]->fbo_list, struct fbo_entry, entry) + { + BOOL destroyed = FALSE; + UINT j; + + for (j = 0; !destroyed && j < GL_LIMITS(buffers); ++j) + { + if (entry->render_targets[j] == (IWineD3DSurface *)resource) + { + context_destroy_fbo_entry(This, entry); + destroyed = TRUE; + } + } + + if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource) + context_destroy_fbo_entry(This, entry); + } + } + + break; + } + + default: + break; + } +} + /***************************************************************************** * Context_MarkStateDirty * diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 4ca96e655fa..08ef2e1c139 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1618,19 +1618,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic if (This->auto_depth_stencil_buffer != NULL) IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0); } - - /** TODO: A check on width, height and multisample types - *(since the zbuffer must be at least as large as the render target and have the same multisample parameters) - ****************************/ - object->wantsDepthStencilBuffer = TRUE; - } else { - object->wantsDepthStencilBuffer = FALSE; } IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *) object, &object->orig_gamma); TRACE("Created swapchain %p\n", object); - TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer ? object->backBuffer[0] : NULL, object->wantsDepthStencilBuffer); + TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer ? object->backBuffer[0] : NULL, pPresentationParameters->EnableAutoDepthStencil); return WINED3D_OK; error: @@ -1718,8 +1711,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, elements, element_count); if(FAILED(hr)) { + IWineD3DVertexDeclaration_Release((IWineD3DVertexDeclaration *)object); *ppVertexDeclaration = NULL; - HeapFree(GetProcessHeap(), 0, object); } return hr; @@ -5970,6 +5963,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, } else { + const unsigned char* data =((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset; glTexSubImage2D(glDescription->target ,glDescription->level ,destLeft @@ -5978,7 +5972,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, ,srcHeight ,glDescription->glFormat ,glDescription->glType - ,IWineD3DSurface_GetData(pSourceSurface) + ,data ); } } @@ -6653,9 +6647,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice * ******************************************************/ if (This->stencilBufferTarget) { - ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD); - surface_load_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); - surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); + if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL + || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) { + surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED); + } else { + ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD); + surface_load_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); + surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); + } } tmp = This->stencilBufferTarget; @@ -7325,10 +7324,14 @@ static void WINAPI IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWin static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DResource *resource){ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + WINED3DRESOURCETYPE type = IWineD3DResource_GetType(resource); int counter; TRACE("(%p) : resource %p\n", This, resource); - switch(IWineD3DResource_GetType(resource)){ + + context_resource_released(iface, resource, type); + + switch (type) { /* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */ case WINED3DRTYPE_SURFACE: { unsigned int i; @@ -7374,24 +7377,6 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW if (This->stencilBufferTarget == (IWineD3DSurface *)resource) { This->stencilBufferTarget = NULL; } - - for (i = 0; i < This->numContexts; ++i) { - struct fbo_entry *entry, *entry2; - int j; - - LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->contexts[i]->fbo_list, struct fbo_entry, entry) { - BOOL destroyed = FALSE; - for (j = 0; !destroyed && j < GL_LIMITS(buffers); ++j) { - if (entry->render_targets[j] == (IWineD3DSurface *)resource) { - context_destroy_fbo_entry(This, entry); - destroyed = TRUE; - } - } - if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource) { - context_destroy_fbo_entry(This, entry); - } - } - } } break; diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 37cbe1975c6..c4154a76f2d 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -219,17 +219,22 @@ void primitiveDeclarationConvertToStridedData( stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx); if (stride_used) { - TRACE("Loaded %s array %u [usage=%s, usage_idx=%u, " + TRACE("Load %s array %u [usage=%s, usage_idx=%u, " "stream=%u, offset=%u, stride=%u, type=%s, VBO=%u]\n", useVertexShaderFunction? "shader": "fixed function", idx, debug_d3ddeclusage(element->Usage), element->UsageIndex, element->Stream, element->Offset, stride, debug_d3ddecltype(element->Type), streamVBO); - strided->u.input[idx].lpData = data; - strided->u.input[idx].dwType = element->Type; - strided->u.input[idx].dwStride = stride; - strided->u.input[idx].VBO = streamVBO; - strided->u.input[idx].streamNo = element->Stream; + if (!useVertexShaderFunction && !vertexDeclaration->ffp_valid[i]) { + WARN("Skipping unsupported fixed function element of type %s and usage %s\n", + debug_d3ddecltype(element->Type), debug_d3ddeclusage(element->Usage)); + } else { + strided->u.input[idx].lpData = data; + strided->u.input[idx].dwType = element->Type; + strided->u.input[idx].dwStride = stride; + strided->u.input[idx].VBO = streamVBO; + strided->u.input[idx].streamNo = element->Stream; + } } } /* Now call PreLoad on all the vertex buffers. In the very rare case diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 3ce81880d14..057826d2515 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1426,7 +1426,7 @@ static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) { ****************************************************************************/ /* Generate GLSL arithmetic functions (dst = src1 + src2) */ -void shader_glsl_arith(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_arith(SHADER_OPCODE_ARG* arg) { CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; glsl_src_param_t src0_param; @@ -1452,7 +1452,7 @@ void shader_glsl_arith(SHADER_OPCODE_ARG* arg) { } /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */ -void shader_glsl_mov(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_mov(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; SHADER_BUFFER* buffer = arg->buffer; glsl_src_param_t src0_param; @@ -1487,7 +1487,7 @@ void shader_glsl_mov(SHADER_OPCODE_ARG* arg) { } /* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */ -void shader_glsl_dot(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_dot(SHADER_OPCODE_ARG* arg) { CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; glsl_src_param_t src0_param; @@ -1517,7 +1517,7 @@ void shader_glsl_dot(SHADER_OPCODE_ARG* arg) { /* Note that this instruction has some restrictions. The destination write mask * can't contain the w component, and the source swizzles have to be .xyzw */ -void shader_glsl_cross(SHADER_OPCODE_ARG *arg) { +static void shader_glsl_cross(SHADER_OPCODE_ARG *arg) { DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; glsl_src_param_t src0_param; glsl_src_param_t src1_param; @@ -1533,7 +1533,7 @@ void shader_glsl_cross(SHADER_OPCODE_ARG *arg) { /* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1) * Src0 and src1 are scalars. Note that D3D uses the absolute of src0, while * GLSL uses the value as-is. */ -void shader_glsl_pow(SHADER_OPCODE_ARG *arg) { +static void shader_glsl_pow(SHADER_OPCODE_ARG *arg) { SHADER_BUFFER *buffer = arg->buffer; glsl_src_param_t src0_param; glsl_src_param_t src1_param; @@ -1556,7 +1556,7 @@ void shader_glsl_pow(SHADER_OPCODE_ARG *arg) { /* Process the WINED3DSIO_LOG instruction in GLSL (dst = log2(|src0|)) * Src0 is a scalar. Note that D3D uses the absolute of src0, while * GLSL uses the value as-is. */ -void shader_glsl_log(SHADER_OPCODE_ARG *arg) { +static void shader_glsl_log(SHADER_OPCODE_ARG *arg) { SHADER_BUFFER *buffer = arg->buffer; glsl_src_param_t src0_param; DWORD dst_write_mask; @@ -1575,7 +1575,7 @@ void shader_glsl_log(SHADER_OPCODE_ARG *arg) { } /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */ -void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) { CONST SHADER_OPCODE* curOpcode = arg->opcode; SHADER_BUFFER* buffer = arg->buffer; glsl_src_param_t src_param; @@ -1592,8 +1592,6 @@ void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) { case WINED3DSIO_ABS: instruction = "abs"; break; case WINED3DSIO_FRC: instruction = "fract"; break; case WINED3DSIO_NRM: instruction = "normalize"; break; - case WINED3DSIO_LOGP: - case WINED3DSIO_LOG: instruction = "log2"; break; case WINED3DSIO_EXP: instruction = "exp2"; break; case WINED3DSIO_SGN: instruction = "sign"; break; case WINED3DSIO_DSX: instruction = "dFdx"; break; @@ -1628,7 +1626,7 @@ void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) { * For 2.0 shaders, just do this (honoring writemask and swizzle): * dst = 2^src; (partial precision is allowed, but optional) */ -void shader_glsl_expp(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_expp(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader; glsl_src_param_t src_param; @@ -1661,7 +1659,7 @@ void shader_glsl_expp(SHADER_OPCODE_ARG* arg) { } /** Process the RCP (reciprocal or inverse) opcode in GLSL (dst = 1 / src) */ -void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src_param; DWORD write_mask; unsigned int mask_size; @@ -1677,7 +1675,7 @@ void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) { } } -void shader_glsl_rsq(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_rsq(SHADER_OPCODE_ARG* arg) { SHADER_BUFFER* buffer = arg->buffer; glsl_src_param_t src_param; DWORD write_mask; @@ -1696,7 +1694,7 @@ void shader_glsl_rsq(SHADER_OPCODE_ARG* arg) { } /** Process signed comparison opcodes in GLSL. */ -void shader_glsl_compare(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_compare(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; DWORD write_mask; @@ -1743,7 +1741,7 @@ void shader_glsl_compare(SHADER_OPCODE_ARG* arg) { } /** Process CMP instruction in GLSL (dst = src0 >= 0.0 ? src1 : src2), per channel */ -void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src2_param; @@ -1819,7 +1817,7 @@ void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) { /** Process the CND opcode in GLSL (dst = (src0 > 0.5) ? src1 : src2) */ /* For ps 1.1-1.3, only a single component of src0 is used. For ps 1.4 * the compare is done per component of src0. */ -void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; glsl_src_param_t src0_param; glsl_src_param_t src1_param; @@ -1865,7 +1863,7 @@ void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) { } /** GLSL code generation for WINED3DSIO_MAD: Multiply the first 2 opcodes, then add the last */ -void shader_glsl_mad(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_mad(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src2_param; @@ -1881,7 +1879,7 @@ void shader_glsl_mad(SHADER_OPCODE_ARG* arg) { /** Handles transforming all WINED3DSIO_M?x? opcodes for Vertex shaders to GLSL codes */ -void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) { int i; int nComponents = 0; SHADER_OPCODE_ARG tmpArg; @@ -1934,7 +1932,7 @@ void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) { blend factor. Equation: (dst = src2 + src0 * (src1 - src2)) This is equivalent to mix(src2, src1, src0); */ -void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src2_param; @@ -1956,7 +1954,7 @@ void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) { * dst.z = (src0.x > 0) ? ((src0.y > 0) ? pow(src0.y, src.w) : 0) : 0 * where src.w is clamped at +- 128 */ -void shader_glsl_lit(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_lit(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src3_param; @@ -2000,7 +1998,7 @@ void shader_glsl_lit(SHADER_OPCODE_ARG* arg) { * dst.z = src0.z * dst.w = src1.w */ -void shader_glsl_dst(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_dst(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0y_param; glsl_src_param_t src0z_param; glsl_src_param_t src1y_param; @@ -2028,7 +2026,7 @@ void shader_glsl_dst(SHADER_OPCODE_ARG* arg) { * dst.z = dst.z * dst.w = dst.w */ -void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; DWORD write_mask; @@ -2060,7 +2058,7 @@ void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) { * Need to use a temporary variable for this operation. */ /* FIXME: I don't think nested loops will work correctly this way. */ -void shader_glsl_loop(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_loop(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src1_param; IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; DWORD regtype = shader_get_regtype(arg->src[1]); @@ -2112,7 +2110,7 @@ void shader_glsl_loop(SHADER_OPCODE_ARG* arg) { shader->baseShader.cur_loop_regno++; } -void shader_glsl_end(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_end(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; shader_addline(arg->buffer, "}\n"); @@ -2126,7 +2124,7 @@ void shader_glsl_end(SHADER_OPCODE_ARG* arg) { } } -void shader_glsl_rep(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_rep(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader; glsl_src_param_t src0_param; @@ -2137,14 +2135,14 @@ void shader_glsl_rep(SHADER_OPCODE_ARG* arg) { shader->baseShader.cur_loop_depth++; } -void shader_glsl_if(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_if(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param); shader_addline(arg->buffer, "if (%s) {\n", src0_param.param_str); } -void shader_glsl_ifc(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_ifc(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; @@ -2155,16 +2153,16 @@ void shader_glsl_ifc(SHADER_OPCODE_ARG* arg) { src0_param.param_str, shader_get_comp_op(arg->opcode_token), src1_param.param_str); } -void shader_glsl_else(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_else(SHADER_OPCODE_ARG* arg) { shader_addline(arg->buffer, "} else {\n"); } -void shader_glsl_break(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_break(SHADER_OPCODE_ARG* arg) { shader_addline(arg->buffer, "break;\n"); } /* FIXME: According to MSDN the compare is done per component. */ -void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; @@ -2175,19 +2173,19 @@ void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) { src0_param.param_str, shader_get_comp_op(arg->opcode_token), src1_param.param_str); } -void shader_glsl_label(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_label(SHADER_OPCODE_ARG* arg) { DWORD snum = (arg->src[0]) & WINED3DSP_REGNUM_MASK; shader_addline(arg->buffer, "}\n"); shader_addline(arg->buffer, "void subroutine%u () {\n", snum); } -void shader_glsl_call(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_call(SHADER_OPCODE_ARG* arg) { DWORD snum = (arg->src[0]) & WINED3DSP_REGNUM_MASK; shader_addline(arg->buffer, "subroutine%u();\n", snum); } -void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src1_param; DWORD snum = (arg->src[0]) & WINED3DSP_REGNUM_MASK; @@ -2198,7 +2196,7 @@ void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) { /********************************************* * Pixel Shader Specific Code begins here ********************************************/ -void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; DWORD hex_version = This->baseShader.hex_version; @@ -2295,7 +2293,7 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) { } } -void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) { +static void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*)arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; glsl_sample_function_t sample_function; @@ -2330,7 +2328,7 @@ void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) { } } -void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) { /* FIXME: Make this work for more than just 2D textures */ @@ -2382,7 +2380,7 @@ void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXDP3TEX instruction in GLSL: * Take a 3-component dot product of the TexCoord[dstreg] and src, * then perform a 1D texture lookup from stage dstregnum, place into dst. */ -void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; char dst_mask[6]; glsl_sample_function_t sample_function; @@ -2424,7 +2422,7 @@ void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXDP3 instruction in GLSL: * Take a 3-component dot product of the TexCoord[dstreg] and src. */ -void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; DWORD dstreg = arg->dst & WINED3DSP_REGNUM_MASK; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; @@ -2444,7 +2442,7 @@ void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXDEPTH instruction in GLSL: * Calculate the depth as dst.x / dst.y */ -void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) { glsl_dst_param_t dst_param; shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param); @@ -2463,7 +2461,7 @@ void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) { * Calculate tmp0.y = TexCoord[dstreg] . src.xyz; (tmp0.x has already been calculated) * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y */ -void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg) { DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; DWORD dstreg = arg->dst & WINED3DSP_REGNUM_MASK; glsl_src_param_t src0_param; @@ -2476,7 +2474,7 @@ void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL * Calculate the 1st of a 2-row matrix multiplication. */ -void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg) { DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; SHADER_BUFFER* buffer = arg->buffer; @@ -2488,7 +2486,7 @@ void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X3PAD instruction in GLSL * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */ -void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; @@ -2502,7 +2500,7 @@ void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg) { current_state->texcoord_w[current_state->current_row++] = reg; } -void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) { DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; SHADER_BUFFER* buffer = arg->buffer; @@ -2521,7 +2519,7 @@ void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculated coordinates */ -void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) { DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; glsl_src_param_t src0_param; char dst_mask[6]; @@ -2547,7 +2545,7 @@ void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X3 instruction in GLSL * Perform the 3rd row of a 3x3 matrix multiply */ -void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg) { DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; glsl_src_param_t src0_param; char dst_mask[6]; @@ -2566,7 +2564,7 @@ void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X3SPEC instruction in GLSL * Peform the final texture lookup based on the previous 2 3x3 matrix multiplies */ -void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader; DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; @@ -2600,7 +2598,7 @@ void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXM3X3VSPEC instruction in GLSL * Peform the final texture lookup based on the previous 2 3x3 matrix multiplies */ -void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader; DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK; @@ -2637,7 +2635,7 @@ void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) { * Apply a fake bump map transform. * texbem is pshader <= 1.3 only, this saves a few version checks */ -void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; char dst_swizzle[6]; @@ -2692,7 +2690,7 @@ void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) { } } -void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param, src1_param; DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; @@ -2706,7 +2704,7 @@ void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXREG2AR instruction in GLSL * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */ -void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; @@ -2721,7 +2719,7 @@ void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXREG2GB instruction in GLSL * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */ -void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; char dst_mask[6]; @@ -2735,7 +2733,7 @@ void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */ -void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; char dst_mask[6]; DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; @@ -2753,7 +2751,7 @@ void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_TEXKILL instruction in GLSL. * If any of the first 3 components are < 0, discard this pixel */ -void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) { IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader; DWORD hex_version = This->baseShader.hex_version; glsl_dst_param_t dst_param; @@ -2774,7 +2772,7 @@ void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) { /** Process the WINED3DSIO_DP2ADD instruction in GLSL. * dst = dot2(src0, src1) + src2 */ -void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg) { +static void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg) { glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src2_param; @@ -3785,7 +3783,95 @@ static BOOL shader_glsl_conv_supported(WINED3DFORMAT fmt) { } } +static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = +{ + /* WINED3DSIH_ABS */ shader_glsl_map2gl, + /* WINED3DSIH_ADD */ shader_glsl_arith, + /* WINED3DSIH_BEM */ pshader_glsl_bem, + /* WINED3DSIH_BREAK */ shader_glsl_break, + /* WINED3DSIH_BREAKC */ shader_glsl_breakc, + /* WINED3DSIH_BREAKP */ NULL, + /* WINED3DSIH_CALL */ shader_glsl_call, + /* WINED3DSIH_CALLNZ */ shader_glsl_callnz, + /* WINED3DSIH_CMP */ shader_glsl_cmp, + /* WINED3DSIH_CND */ shader_glsl_cnd, + /* WINED3DSIH_CRS */ shader_glsl_cross, + /* WINED3DSIH_DCL */ NULL, + /* WINED3DSIH_DEF */ NULL, + /* WINED3DSIH_DEFB */ NULL, + /* WINED3DSIH_DEFI */ NULL, + /* WINED3DSIH_DP2ADD */ pshader_glsl_dp2add, + /* WINED3DSIH_DP3 */ shader_glsl_dot, + /* WINED3DSIH_DP4 */ shader_glsl_dot, + /* WINED3DSIH_DST */ shader_glsl_dst, + /* WINED3DSIH_DSX */ shader_glsl_map2gl, + /* WINED3DSIH_DSY */ shader_glsl_map2gl, + /* WINED3DSIH_ELSE */ shader_glsl_else, + /* WINED3DSIH_ENDIF */ shader_glsl_end, + /* WINED3DSIH_ENDLOOP */ shader_glsl_end, + /* WINED3DSIH_ENDREP */ shader_glsl_end, + /* WINED3DSIH_EXP */ shader_glsl_map2gl, + /* WINED3DSIH_EXPP */ shader_glsl_expp, + /* WINED3DSIH_FRC */ shader_glsl_map2gl, + /* WINED3DSIH_IF */ shader_glsl_if, + /* WINED3DSIH_IFC */ shader_glsl_ifc, + /* WINED3DSIH_LABEL */ shader_glsl_label, + /* WINED3DSIH_LIT */ shader_glsl_lit, + /* WINED3DSIH_LOG */ shader_glsl_log, + /* WINED3DSIH_LOGP */ shader_glsl_log, + /* WINED3DSIH_LOOP */ shader_glsl_loop, + /* WINED3DSIH_LRP */ shader_glsl_lrp, + /* WINED3DSIH_M3x2 */ shader_glsl_mnxn, + /* WINED3DSIH_M3x3 */ shader_glsl_mnxn, + /* WINED3DSIH_M3x4 */ shader_glsl_mnxn, + /* WINED3DSIH_M4x3 */ shader_glsl_mnxn, + /* WINED3DSIH_M4x4 */ shader_glsl_mnxn, + /* WINED3DSIH_MAD */ shader_glsl_mad, + /* WINED3DSIH_MAX */ shader_glsl_map2gl, + /* WINED3DSIH_MIN */ shader_glsl_map2gl, + /* WINED3DSIH_MOV */ shader_glsl_mov, + /* WINED3DSIH_MOVA */ shader_glsl_mov, + /* WINED3DSIH_MUL */ shader_glsl_arith, + /* WINED3DSIH_NOP */ NULL, + /* WINED3DSIH_NRM */ shader_glsl_map2gl, + /* WINED3DSIH_PHASE */ NULL, + /* WINED3DSIH_POW */ shader_glsl_pow, + /* WINED3DSIH_RCP */ shader_glsl_rcp, + /* WINED3DSIH_REP */ shader_glsl_rep, + /* WINED3DSIH_RET */ NULL, + /* WINED3DSIH_RSQ */ shader_glsl_rsq, + /* WINED3DSIH_SETP */ NULL, + /* WINED3DSIH_SGE */ shader_glsl_compare, + /* WINED3DSIH_SGN */ shader_glsl_map2gl, + /* WINED3DSIH_SINCOS */ shader_glsl_sincos, + /* WINED3DSIH_SLT */ shader_glsl_compare, + /* WINED3DSIH_SUB */ shader_glsl_arith, + /* WINED3DSIH_TEX */ pshader_glsl_tex, + /* WINED3DSIH_TEXBEM */ pshader_glsl_texbem, + /* WINED3DSIH_TEXBEML */ pshader_glsl_texbem, + /* WINED3DSIH_TEXCOORD */ pshader_glsl_texcoord, + /* WINED3DSIH_TEXDEPTH */ pshader_glsl_texdepth, + /* WINED3DSIH_TEXDP3 */ pshader_glsl_texdp3, + /* WINED3DSIH_TEXDP3TEX */ pshader_glsl_texdp3tex, + /* WINED3DSIH_TEXKILL */ pshader_glsl_texkill, + /* WINED3DSIH_TEXLDD */ NULL, + /* WINED3DSIH_TEXLDL */ shader_glsl_texldl, + /* WINED3DSIH_TEXM3x2DEPTH */ pshader_glsl_texm3x2depth, + /* WINED3DSIH_TEXM3x2PAD */ pshader_glsl_texm3x2pad, + /* WINED3DSIH_TEXM3x2TEX */ pshader_glsl_texm3x2tex, + /* WINED3DSIH_TEXM3x3 */ pshader_glsl_texm3x3, + /* WINED3DSIH_TEXM3x3DIFF */ NULL, + /* WINED3DSIH_TEXM3x3PAD */ pshader_glsl_texm3x3pad, + /* WINED3DSIH_TEXM3x3SPEC */ pshader_glsl_texm3x3spec, + /* WINED3DSIH_TEXM3x3TEX */ pshader_glsl_texm3x3tex, + /* WINED3DSIH_TEXM3x3VSPEC */ pshader_glsl_texm3x3vspec, + /* WINED3DSIH_TEXREG2AR */ pshader_glsl_texreg2ar, + /* WINED3DSIH_TEXREG2GB */ pshader_glsl_texreg2gb, + /* WINED3DSIH_TEXREG2RGB */ pshader_glsl_texreg2rgb, +}; + const shader_backend_t glsl_shader_backend = { + shader_glsl_instruction_handler_table, shader_glsl_select, shader_glsl_select_depth_blt, shader_glsl_deselect_depth_blt, diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 29cd36891cc..8182939962d 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -99,96 +99,96 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader* CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { /* Arithmetic */ - {WINED3DSIO_NOP, "nop", "NOP", 0, 0, pshader_hw_map2gl, NULL, 0, 0}, - {WINED3DSIO_MOV, "mov", "MOV", 1, 2, pshader_hw_map2gl, shader_glsl_mov, 0, 0}, - {WINED3DSIO_ADD, "add", "ADD", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0}, - {WINED3DSIO_SUB, "sub", "SUB", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0}, - {WINED3DSIO_MAD, "mad", "MAD", 1, 4, pshader_hw_map2gl, shader_glsl_mad, 0, 0}, - {WINED3DSIO_MUL, "mul", "MUL", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0}, - {WINED3DSIO_RCP, "rcp", "RCP", 1, 2, pshader_hw_map2gl, shader_glsl_rcp, 0, 0}, - {WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, pshader_hw_map2gl, shader_glsl_rsq, 0, 0}, - {WINED3DSIO_DP3, "dp3", "DP3", 1, 3, pshader_hw_map2gl, shader_glsl_dot, 0, 0}, - {WINED3DSIO_DP4, "dp4", "DP4", 1, 3, pshader_hw_map2gl, shader_glsl_dot, 0, 0}, - {WINED3DSIO_MIN, "min", "MIN", 1, 3, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_MAX, "max", "MAX", 1, 3, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_SLT, "slt", "SLT", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0}, - {WINED3DSIO_SGE, "sge", "SGE", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0}, - {WINED3DSIO_ABS, "abs", "ABS", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_EXP, "exp", "EX2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_LOG, "log", "LG2", 1, 2, pshader_hw_map2gl, shader_glsl_log, 0, 0}, - {WINED3DSIO_EXPP, "expp", "EXP", 1, 2, pshader_hw_map2gl, shader_glsl_expp, 0, 0}, - {WINED3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_DST, "dst", "DST", 1, 3, pshader_hw_map2gl, shader_glsl_dst, 0, 0}, - {WINED3DSIO_LRP, "lrp", "LRP", 1, 4, pshader_hw_map2gl, shader_glsl_lrp, 0, 0}, - {WINED3DSIO_FRC, "frc", "FRC", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_CND, "cnd", NULL, 1, 4, pshader_hw_cnd, shader_glsl_cnd, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_CMP, "cmp", NULL, 1, 4, pshader_hw_cmp, shader_glsl_cmp, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)}, - {WINED3DSIO_POW, "pow", "POW", 1, 3, pshader_hw_map2gl, shader_glsl_pow, 0, 0}, - {WINED3DSIO_CRS, "crs", "XPD", 1, 3, pshader_hw_map2gl, shader_glsl_cross, 0, 0}, - {WINED3DSIO_NRM, "nrm", NULL, 1, 2, shader_hw_nrm, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, shader_hw_sincos, shader_glsl_sincos, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)}, - {WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, shader_hw_sincos, shader_glsl_sincos, WINED3DPS_VERSION(3,0), -1}, - {WINED3DSIO_DP2ADD, "dp2add", NULL, 1, 4, pshader_hw_dp2add, pshader_glsl_dp2add, WINED3DPS_VERSION(2,0), -1}, + {WINED3DSIO_NOP, "nop", "NOP", 0, 0, WINED3DSIH_NOP, 0, 0 }, + {WINED3DSIO_MOV, "mov", "MOV", 1, 2, WINED3DSIH_MOV, 0, 0 }, + {WINED3DSIO_ADD, "add", "ADD", 1, 3, WINED3DSIH_ADD, 0, 0 }, + {WINED3DSIO_SUB, "sub", "SUB", 1, 3, WINED3DSIH_SUB, 0, 0 }, + {WINED3DSIO_MAD, "mad", "MAD", 1, 4, WINED3DSIH_MAD, 0, 0 }, + {WINED3DSIO_MUL, "mul", "MUL", 1, 3, WINED3DSIH_MUL, 0, 0 }, + {WINED3DSIO_RCP, "rcp", "RCP", 1, 2, WINED3DSIH_RCP, 0, 0 }, + {WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, WINED3DSIH_RSQ, 0, 0 }, + {WINED3DSIO_DP3, "dp3", "DP3", 1, 3, WINED3DSIH_DP3, 0, 0 }, + {WINED3DSIO_DP4, "dp4", "DP4", 1, 3, WINED3DSIH_DP4, 0, 0 }, + {WINED3DSIO_MIN, "min", "MIN", 1, 3, WINED3DSIH_MIN, 0, 0 }, + {WINED3DSIO_MAX, "max", "MAX", 1, 3, WINED3DSIH_MAX, 0, 0 }, + {WINED3DSIO_SLT, "slt", "SLT", 1, 3, WINED3DSIH_SLT, 0, 0 }, + {WINED3DSIO_SGE, "sge", "SGE", 1, 3, WINED3DSIH_SGE, 0, 0 }, + {WINED3DSIO_ABS, "abs", "ABS", 1, 2, WINED3DSIH_ABS, 0, 0 }, + {WINED3DSIO_EXP, "exp", "EX2", 1, 2, WINED3DSIH_EXP, 0, 0 }, + {WINED3DSIO_LOG, "log", "LG2", 1, 2, WINED3DSIH_LOG, 0, 0 }, + {WINED3DSIO_EXPP, "expp", "EXP", 1, 2, WINED3DSIH_EXPP, 0, 0 }, + {WINED3DSIO_LOGP, "logp", "LOG", 1, 2, WINED3DSIH_LOGP, 0, 0 }, + {WINED3DSIO_DST, "dst", "DST", 1, 3, WINED3DSIH_DST, 0, 0 }, + {WINED3DSIO_LRP, "lrp", "LRP", 1, 4, WINED3DSIH_LRP, 0, 0 }, + {WINED3DSIO_FRC, "frc", "FRC", 1, 2, WINED3DSIH_FRC, 0, 0 }, + {WINED3DSIO_CND, "cnd", NULL, 1, 4, WINED3DSIH_CND, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_CMP, "cmp", NULL, 1, 4, WINED3DSIH_CMP, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)}, + {WINED3DSIO_POW, "pow", "POW", 1, 3, WINED3DSIH_POW, 0, 0 }, + {WINED3DSIO_CRS, "crs", "XPD", 1, 3, WINED3DSIH_CRS, 0, 0 }, + {WINED3DSIO_NRM, "nrm", NULL, 1, 2, WINED3DSIH_NRM, 0, 0 }, + {WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, WINED3DSIH_SINCOS, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)}, + {WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, WINED3DSIH_SINCOS, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_DP2ADD, "dp2add", NULL, 1, 4, WINED3DSIH_DP2ADD, WINED3DPS_VERSION(2,0), -1 }, /* Matrix */ - {WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, + {WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, WINED3DSIH_M4x4, 0, 0 }, + {WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, WINED3DSIH_M4x3, 0, 0 }, + {WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, WINED3DSIH_M3x4, 0, 0 }, + {WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, WINED3DSIH_M3x3, 0, 0 }, + {WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, WINED3DSIH_M3x2, 0, 0 }, /* Register declarations */ - {WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0}, + {WINED3DSIO_DCL, "dcl", NULL, 0, 2, WINED3DSIH_DCL, 0, 0 }, /* Flow control - requires GLSL or software shaders */ - {WINED3DSIO_REP , "rep", NULL, 0, 1, NULL, shader_glsl_rep, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_ENDREP, "endrep", NULL, 0, 0, NULL, shader_glsl_end, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_IF, "if", NULL, 0, 1, NULL, shader_glsl_if, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_IFC, "ifc", NULL, 0, 2, NULL, shader_glsl_ifc, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_ELSE, "else", NULL, 0, 0, NULL, shader_glsl_else, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_ENDIF, "endif", NULL, 0, 0, NULL, shader_glsl_end, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_BREAK, "break", NULL, 0, 0, NULL, shader_glsl_break, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_BREAKC, "breakc", NULL, 0, 2, NULL, shader_glsl_breakc, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, NULL, NULL, 0, 0}, - {WINED3DSIO_CALL, "call", NULL, 0, 1, NULL, shader_glsl_call, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_CALLNZ, "callnz", NULL, 0, 2, NULL, shader_glsl_callnz, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_LOOP, "loop", NULL, 0, 2, NULL, shader_glsl_loop, WINED3DPS_VERSION(3,0), -1}, - {WINED3DSIO_RET, "ret", NULL, 0, 0, NULL, NULL, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_ENDLOOP, "endloop", NULL, 0, 0, NULL, shader_glsl_end, WINED3DPS_VERSION(3,0), -1}, - {WINED3DSIO_LABEL, "label", NULL, 0, 1, NULL, shader_glsl_label, WINED3DPS_VERSION(2,1), -1}, + {WINED3DSIO_REP , "rep", NULL, 0, 1, WINED3DSIH_REP, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ENDREP, "endrep", NULL, 0, 0, WINED3DSIH_ENDREP, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_IF, "if", NULL, 0, 1, WINED3DSIH_IF, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_IFC, "ifc", NULL, 0, 2, WINED3DSIH_IFC, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ELSE, "else", NULL, 0, 0, WINED3DSIH_ELSE, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ENDIF, "endif", NULL, 0, 0, WINED3DSIH_ENDIF, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAK, "break", NULL, 0, 0, WINED3DSIH_BREAK, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKC, "breakc", NULL, 0, 2, WINED3DSIH_BREAKC, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, WINED3DSIH_BREAKP, 0, 0 }, + {WINED3DSIO_CALL, "call", NULL, 0, 1, WINED3DSIH_CALL, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_CALLNZ, "callnz", NULL, 0, 2, WINED3DSIH_CALLNZ, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_LOOP, "loop", NULL, 0, 2, WINED3DSIH_LOOP, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_RET, "ret", NULL, 0, 0, WINED3DSIH_RET, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_ENDLOOP, "endloop", NULL, 0, 0, WINED3DSIH_ENDLOOP, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_LABEL, "label", NULL, 0, 1, WINED3DSIH_LABEL, WINED3DPS_VERSION(2,1), -1 }, /* Constant definitions */ - {WINED3DSIO_DEF, "def", "undefined", 1, 5, NULL, NULL, 0, 0}, - {WINED3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, 0, 0}, - {WINED3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, 0, 0}, + {WINED3DSIO_DEF, "def", "undefined", 1, 5, WINED3DSIH_DEF, 0, 0 }, + {WINED3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_DEFB, 0, 0 }, + {WINED3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, WINED3DSIH_DEFI, 0, 0 }, /* Texture */ - {WINED3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_hw_texcoord, pshader_glsl_texcoord, 0, WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXCOORD, "texcrd", "undefined", 1, 2, pshader_hw_texcoord, pshader_glsl_texcoord, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, pshader_hw_texkill, pshader_glsl_texkill, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)}, - {WINED3DSIO_TEX, "tex", "undefined", 1, 1, pshader_hw_tex, pshader_glsl_tex, 0, WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEX, "texld", "undefined", 1, 2, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_TEX, "texld", "undefined", 1, 3, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(2,0), -1}, - {WINED3DSIO_TEXBEM, "texbem", "undefined", 1, 2, pshader_hw_texbem, pshader_glsl_texbem, 0, WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, pshader_hw_texbem, pshader_glsl_texbem, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_hw_texreg2ar, pshader_glsl_texreg2ar, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_hw_texreg2gb, pshader_glsl_texreg2gb, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXREG2RGB, "texreg2rgb", "undefined", 1, 2, pshader_hw_texreg2rgb, pshader_glsl_texreg2rgb, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x2PAD, "texm3x2pad", "undefined", 1, 2, pshader_hw_texm3x2pad, pshader_glsl_texm3x2pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x2TEX, "texm3x2tex", "undefined", 1, 2, pshader_hw_texm3x2tex, pshader_glsl_texm3x2tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3PAD, "texm3x3pad", "undefined", 1, 2, pshader_hw_texm3x3pad, pshader_glsl_texm3x3pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3DIFF, "texm3x3diff", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)}, - {WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", "undefined", 1, 3, pshader_hw_texm3x3spec, pshader_glsl_texm3x3spec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined", 1, 2, pshader_hw_texm3x3vspec, pshader_glsl_texm3x3vspec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3TEX, "texm3x3tex", "undefined", 1, 2, pshader_hw_texm3x3tex, pshader_glsl_texm3x3tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDP3TEX, "texdp3tex", NULL, 1, 2, pshader_hw_texdp3tex, pshader_glsl_texdp3tex, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, pshader_hw_texm3x2depth, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDP3, "texdp3", NULL, 1, 2, pshader_hw_texdp3, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXM3x3, "texm3x3", NULL, 1, 2, pshader_hw_texm3x3, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDEPTH, "texdepth", NULL, 1, 1, pshader_hw_texdepth, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_BEM, "bem", "undefined", 1, 3, pshader_hw_bem, pshader_glsl_bem, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, - {WINED3DSIO_DSX, "dsx", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_DSY, "dsy", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_TEXLDD, "texldd", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, WINED3DPS_VERSION(2,1), -1}, - {WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0}, - {WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, NULL, shader_glsl_texldl, WINED3DPS_VERSION(3,0), -1}, - {WINED3DSIO_PHASE, "phase", GLNAME_REQUIRE_GLSL, 0, 0, NULL, NULL, 0, 0}, - {0, NULL, NULL, 0, 0, NULL, NULL, 0, 0} + {WINED3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXCOORD, "texcrd", "undefined", 1, 2, WINED3DSIH_TEXCOORD, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, WINED3DSIH_TEXKILL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)}, + {WINED3DSIO_TEX, "tex", "undefined", 1, 1, WINED3DSIH_TEX, 0, WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEX, "texld", "undefined", 1, 2, WINED3DSIH_TEX, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_TEX, "texld", "undefined", 1, 3, WINED3DSIH_TEX, WINED3DPS_VERSION(2,0), -1 }, + {WINED3DSIO_TEXBEM, "texbem", "undefined", 1, 2, WINED3DSIH_TEXBEM, 0, WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_TEXBEML, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXREG2AR, "texreg2ar", "undefined", 1, 2, WINED3DSIH_TEXREG2AR, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXREG2GB, "texreg2gb", "undefined", 1, 2, WINED3DSIH_TEXREG2GB, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXREG2RGB, "texreg2rgb", "undefined", 1, 2, WINED3DSIH_TEXREG2RGB, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2PAD, "texm3x2pad", "undefined", 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2TEX, "texm3x2tex", "undefined", 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3PAD, "texm3x3pad", "undefined", 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3DIFF, "texm3x3diff", GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)}, + {WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", "undefined", 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined", 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3TEX, "texm3x3tex", "undefined", 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDP3TEX, "texdp3tex", NULL, 1, 2, WINED3DSIH_TEXDP3TEX, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDP3, "texdp3", NULL, 1, 2, WINED3DSIH_TEXDP3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3, "texm3x3", NULL, 1, 2, WINED3DSIH_TEXM3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDEPTH, "texdepth", NULL, 1, 1, WINED3DSIH_TEXDEPTH, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_BEM, "bem", "undefined", 1, 3, WINED3DSIH_BEM, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)}, + {WINED3DSIO_DSX, "dsx", NULL, 1, 2, WINED3DSIH_DSX, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_DSY, "dsy", NULL, 1, 2, WINED3DSIH_DSY, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_TEXLDD, "texldd", GLNAME_REQUIRE_GLSL, 1, 5, WINED3DSIH_TEXLDD, WINED3DPS_VERSION(2,1), -1 }, + {WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, WINED3DSIH_SETP, 0, 0 }, + {WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, WINED3DSIH_TEXLDL, WINED3DPS_VERSION(3,0), -1 }, + {WINED3DSIO_PHASE, "phase", GLNAME_REQUIRE_GLSL, 0, 0, WINED3DSIH_PHASE, 0, 0 }, + {0, NULL, NULL, 0, 0, 0, 0, 0 } }; static void pshader_set_limits( diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index be6ffb33c85..4c6acc3239d 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -632,16 +632,6 @@ void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT te TRACE("(%p) : setting textureName %u, target %#x\n", This, textureName, target); if (This->glDescription.textureName == 0 && textureName != 0) { IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); - if((This->Flags & SFLAG_LOCATIONS) == 0) { - /* In 1.0-rc4 and earlier, AddDirtyRect was called in the place of this if condition. - * This had the problem that a correctly set INDRAWABLE flag was removed if the PreLoad - * during the offscreen rendering readback triggered the creation of the GL texture. - * The change intended to keep the INDRAWABLE intact. To prevent unintended side effects - * before release, set the INSYSMEM flag like the old AddDirtyRect did. - */ - WARN("Wine 1.0 safety path hit\n"); - This->Flags |= SFLAG_INSYSMEM; - } } if(target == GL_TEXTURE_RECTANGLE_ARB && This->glDescription.target != target) { This->Flags &= ~SFLAG_NORMCOORD; @@ -2365,6 +2355,19 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) { glGenTextures(1, &This->glDescription.textureName); checkGLcall("glGenTextures"); TRACE("Surface %p given name %d\n", This, This->glDescription.textureName); + + glBindTexture(This->glDescription.target, This->glDescription.textureName); + checkGLcall("glBindTexture"); + glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); + glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); + glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)"); + glTexParameteri(This->glDescription.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); + glTexParameteri(This->glDescription.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); } /* This is where we should be reducing the amount of GLMemoryUsed */ } else if (This->glDescription.textureName) { @@ -3446,6 +3449,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * /* Activate the destination context, set it up for blitting */ ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT); + /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates', + * while OpenGL coordinates are window relative. + * Also beware of the origin difference(top left vs bottom left). + * Also beware that the front buffer's surface size is screen width x screen height, + * whereas the real gl drawable size is the size of the window. + */ if (dstSwapchain && (IWineD3DSurface *)This == dstSwapchain->frontBuffer) { RECT windowsize; POINT offset = {0,0}; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 1a82ab8a241..a9a5787610d 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -259,6 +259,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO } } + if (This->wineD3DDevice->stencilBufferTarget) { + if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL + || ((IWineD3DSurfaceImpl *)This->wineD3DDevice->stencilBufferTarget)->Flags & SFLAG_DISCARD) { + surface_modify_ds_location(This->wineD3DDevice->stencilBufferTarget, SFLAG_DS_DISCARDED); + } + } + if(This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE && GL_SUPPORT(SGI_VIDEO_SYNC)) { retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync)); if(retval != 0) { diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index 936ef57fbbe..7fc711b4521 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -74,6 +74,7 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat } HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); + HeapFree(GetProcessHeap(), 0, This->ffp_valid); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -118,6 +119,90 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVerte return hr; } +static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element) +{ + switch(element->Usage) + { + case WINED3DDECLUSAGE_POSITION: + case WINED3DDECLUSAGE_POSITIONT: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT2: + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_SHORT2: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_2: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_BLENDWEIGHT: + switch(element->Type) + { + case WINED3DDECLTYPE_D3DCOLOR: + case WINED3DDECLTYPE_UBYTE4: + case WINED3DDECLTYPE_SHORT2: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_2: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_NORMAL: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_TEXCOORD: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT1: + case WINED3DDECLTYPE_FLOAT2: + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_SHORT2: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_2: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_COLOR: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_D3DCOLOR: + case WINED3DDECLTYPE_UBYTE4: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_UBYTE4N: + case WINED3DDECLTYPE_SHORT4N: + case WINED3DDECLTYPE_USHORT4N: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + default: + return FALSE; + } +} + static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface, const WINED3DVERTEXELEMENT *elements, UINT element_count) { IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; @@ -136,7 +221,8 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte This->declarationWNumElements = element_count; This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count); - if (!This->pDeclarationWine) { + This->ffp_valid = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->ffp_valid) * element_count); + if (!This->pDeclarationWine || !This->ffp_valid) { ERR("Memory allocation failed\n"); return WINED3DERR_OUTOFVIDEOMEMORY; } else { @@ -149,6 +235,7 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte This->num_streams = 0; This->position_transformed = FALSE; for (i = 0; i < element_count; ++i) { + This->ffp_valid[i] = declaration_element_valid_ffp(&This->pDeclarationWine[i]); if(This->pDeclarationWine[i].Usage == WINED3DDECLUSAGE_POSITIONT) { This->position_transformed = TRUE; @@ -167,7 +254,6 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte 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); return E_FAIL; } diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 928b97dde3c..80bfda00b25 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -43,71 +43,71 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = { /* This table is not order or position dependent. */ /* Arithmetic */ - {WINED3DSIO_NOP, "nop", "NOP", 0, 0, vshader_hw_map2gl, NULL, 0, 0}, - {WINED3DSIO_MOV, "mov", "MOV", 1, 2, vshader_hw_map2gl, shader_glsl_mov, 0, 0}, - {WINED3DSIO_MOVA, "mova", NULL, 1, 2, vshader_hw_map2gl, shader_glsl_mov, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_ADD, "add", "ADD", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0}, - {WINED3DSIO_SUB, "sub", "SUB", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0}, - {WINED3DSIO_MAD, "mad", "MAD", 1, 4, vshader_hw_map2gl, shader_glsl_mad, 0, 0}, - {WINED3DSIO_MUL, "mul", "MUL", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0}, - {WINED3DSIO_RCP, "rcp", "RCP", 1, 2, vshader_hw_rsq_rcp, shader_glsl_rcp, 0, 0}, - {WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, vshader_hw_rsq_rcp, shader_glsl_rsq, 0, 0}, - {WINED3DSIO_DP3, "dp3", "DP3", 1, 3, vshader_hw_map2gl, shader_glsl_dot, 0, 0}, - {WINED3DSIO_DP4, "dp4", "DP4", 1, 3, vshader_hw_map2gl, shader_glsl_dot, 0, 0}, - {WINED3DSIO_MIN, "min", "MIN", 1, 3, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_MAX, "max", "MAX", 1, 3, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_SLT, "slt", "SLT", 1, 3, vshader_hw_map2gl, shader_glsl_compare, 0, 0}, - {WINED3DSIO_SGE, "sge", "SGE", 1, 3, vshader_hw_map2gl, shader_glsl_compare, 0, 0}, - {WINED3DSIO_ABS, "abs", "ABS", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_EXP, "exp", "EX2", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_LOG, "log", "LG2", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_EXPP, "expp", "EXP", 1, 2, vshader_hw_map2gl, shader_glsl_expp, 0, 0}, - {WINED3DSIO_LOGP, "logp", "LOG", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_LIT, "lit", "LIT", 1, 2, vshader_hw_map2gl, shader_glsl_lit, 0, 0}, - {WINED3DSIO_DST, "dst", "DST", 1, 3, vshader_hw_map2gl, shader_glsl_dst, 0, 0}, - {WINED3DSIO_LRP, "lrp", "LRP", 1, 4, NULL, shader_glsl_lrp, 0, 0}, - {WINED3DSIO_FRC, "frc", "FRC", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_POW, "pow", "POW", 1, 3, vshader_hw_map2gl, shader_glsl_pow, 0, 0}, - {WINED3DSIO_CRS, "crs", "XPD", 1, 3, vshader_hw_map2gl, shader_glsl_cross, 0, 0}, + {WINED3DSIO_NOP, "nop", "NOP", 0, 0, WINED3DSIH_NOP, 0, 0 }, + {WINED3DSIO_MOV, "mov", "MOV", 1, 2, WINED3DSIH_MOV, 0, 0 }, + {WINED3DSIO_MOVA, "mova", NULL, 1, 2, WINED3DSIH_MOVA, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ADD, "add", "ADD", 1, 3, WINED3DSIH_ADD, 0, 0 }, + {WINED3DSIO_SUB, "sub", "SUB", 1, 3, WINED3DSIH_SUB, 0, 0 }, + {WINED3DSIO_MAD, "mad", "MAD", 1, 4, WINED3DSIH_MAD, 0, 0 }, + {WINED3DSIO_MUL, "mul", "MUL", 1, 3, WINED3DSIH_MUL, 0, 0 }, + {WINED3DSIO_RCP, "rcp", "RCP", 1, 2, WINED3DSIH_RCP, 0, 0 }, + {WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, WINED3DSIH_RSQ, 0, 0 }, + {WINED3DSIO_DP3, "dp3", "DP3", 1, 3, WINED3DSIH_DP3, 0, 0 }, + {WINED3DSIO_DP4, "dp4", "DP4", 1, 3, WINED3DSIH_DP4, 0, 0 }, + {WINED3DSIO_MIN, "min", "MIN", 1, 3, WINED3DSIH_MIN, 0, 0 }, + {WINED3DSIO_MAX, "max", "MAX", 1, 3, WINED3DSIH_MAX, 0, 0 }, + {WINED3DSIO_SLT, "slt", "SLT", 1, 3, WINED3DSIH_SLT, 0, 0 }, + {WINED3DSIO_SGE, "sge", "SGE", 1, 3, WINED3DSIH_SGE, 0, 0 }, + {WINED3DSIO_ABS, "abs", "ABS", 1, 2, WINED3DSIH_ABS, 0, 0 }, + {WINED3DSIO_EXP, "exp", "EX2", 1, 2, WINED3DSIH_EXP, 0, 0 }, + {WINED3DSIO_LOG, "log", "LG2", 1, 2, WINED3DSIH_LOG, 0, 0 }, + {WINED3DSIO_EXPP, "expp", "EXP", 1, 2, WINED3DSIH_EXPP, 0, 0 }, + {WINED3DSIO_LOGP, "logp", "LOG", 1, 2, WINED3DSIH_LOGP, 0, 0 }, + {WINED3DSIO_LIT, "lit", "LIT", 1, 2, WINED3DSIH_LIT, 0, 0 }, + {WINED3DSIO_DST, "dst", "DST", 1, 3, WINED3DSIH_DST, 0, 0 }, + {WINED3DSIO_LRP, "lrp", "LRP", 1, 4, WINED3DSIH_LRP, 0, 0 }, + {WINED3DSIO_FRC, "frc", "FRC", 1, 2, WINED3DSIH_FRC, 0, 0 }, + {WINED3DSIO_POW, "pow", "POW", 1, 3, WINED3DSIH_POW, 0, 0 }, + {WINED3DSIO_CRS, "crs", "XPD", 1, 3, WINED3DSIH_CRS, 0, 0 }, /* TODO: sng can possibly be performed a s RCP tmp, vec MUL out, tmp, vec*/ - {WINED3DSIO_SGN, "sgn", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_NRM, "nrm", NULL, 1, 2, shader_hw_nrm, shader_glsl_map2gl, 0, 0}, - {WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, shader_hw_sincos, shader_glsl_sincos, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)}, - {WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, shader_hw_sincos, shader_glsl_sincos, WINED3DVS_VERSION(3,0), -1}, + {WINED3DSIO_SGN, "sgn", NULL, 1, 2, WINED3DSIH_SGN, 0, 0 }, + {WINED3DSIO_NRM, "nrm", NULL, 1, 2, WINED3DSIH_NRM, 0, 0 }, + {WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, WINED3DSIH_SINCOS, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)}, + {WINED3DSIO_SINCOS, "sincos", "SCS", 1, 2, WINED3DSIH_SINCOS, WINED3DVS_VERSION(3,0), -1 }, /* Matrix */ - {WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, - {WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, shader_hw_mnxn, shader_glsl_mnxn, 0, 0}, + {WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, WINED3DSIH_M4x4, 0, 0 }, + {WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, WINED3DSIH_M4x3, 0, 0 }, + {WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, WINED3DSIH_M3x4, 0, 0 }, + {WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, WINED3DSIH_M3x3, 0, 0 }, + {WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, WINED3DSIH_M3x2, 0, 0 }, /* Declare registers */ - {WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0}, + {WINED3DSIO_DCL, "dcl", NULL, 0, 2, WINED3DSIH_DCL, 0, 0 }, /* Constant definitions */ - {WINED3DSIO_DEF, "def", NULL, 1, 5, NULL, NULL, 0, 0}, - {WINED3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, 0, 0}, - {WINED3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, 0, 0}, + {WINED3DSIO_DEF, "def", NULL, 1, 5, WINED3DSIH_DEF, 0, 0 }, + {WINED3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_DEFB, 0, 0 }, + {WINED3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, WINED3DSIH_DEFI, 0, 0 }, /* Flow control - requires GLSL or software shaders */ - {WINED3DSIO_REP , "rep", NULL, 0, 1, NULL, shader_glsl_rep, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_ENDREP, "endrep", NULL, 0, 0, NULL, shader_glsl_end, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_IF, "if", NULL, 0, 1, NULL, shader_glsl_if, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_IFC, "ifc", NULL, 0, 2, NULL, shader_glsl_ifc, WINED3DVS_VERSION(2,1), -1}, - {WINED3DSIO_ELSE, "else", NULL, 0, 0, NULL, shader_glsl_else, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_ENDIF, "endif", NULL, 0, 0, NULL, shader_glsl_end, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_BREAK, "break", NULL, 0, 0, NULL, shader_glsl_break, WINED3DVS_VERSION(2,1), -1}, - {WINED3DSIO_BREAKC, "breakc", NULL, 0, 2, NULL, shader_glsl_breakc, WINED3DVS_VERSION(2,1), -1}, - {WINED3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, NULL, NULL, 0, 0}, - {WINED3DSIO_CALL, "call", NULL, 0, 1, NULL, shader_glsl_call, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_CALLNZ, "callnz", NULL, 0, 2, NULL, shader_glsl_callnz, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_LOOP, "loop", NULL, 0, 2, NULL, shader_glsl_loop, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_RET, "ret", NULL, 0, 0, NULL, NULL, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_ENDLOOP,"endloop", NULL, 0, 0, NULL, shader_glsl_end, WINED3DVS_VERSION(2,0), -1}, - {WINED3DSIO_LABEL, "label", NULL, 0, 1, NULL, shader_glsl_label, WINED3DVS_VERSION(2,0), -1}, - - {WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0}, - {WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, NULL, shader_glsl_texldl, WINED3DVS_VERSION(3,0), -1}, - {0, NULL, NULL, 0, 0, NULL, NULL, 0, 0} + {WINED3DSIO_REP , "rep", NULL, 0, 1, WINED3DSIH_REP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ENDREP, "endrep", NULL, 0, 0, WINED3DSIH_ENDREP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_IF, "if", NULL, 0, 1, WINED3DSIH_IF, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_IFC, "ifc", NULL, 0, 2, WINED3DSIH_IFC, WINED3DVS_VERSION(2,1), -1 }, + {WINED3DSIO_ELSE, "else", NULL, 0, 0, WINED3DSIH_ELSE, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ENDIF, "endif", NULL, 0, 0, WINED3DSIH_ENDIF, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_BREAK, "break", NULL, 0, 0, WINED3DSIH_BREAK, WINED3DVS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKC, "breakc", NULL, 0, 2, WINED3DSIH_BREAKC, WINED3DVS_VERSION(2,1), -1 }, + {WINED3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, WINED3DSIH_BREAKP, 0, 0 }, + {WINED3DSIO_CALL, "call", NULL, 0, 1, WINED3DSIH_CALL, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_CALLNZ, "callnz", NULL, 0, 2, WINED3DSIH_CALLNZ, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_LOOP, "loop", NULL, 0, 2, WINED3DSIH_LOOP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_RET, "ret", NULL, 0, 0, WINED3DSIH_RET, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_ENDLOOP, "endloop", NULL, 0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1 }, + {WINED3DSIO_LABEL, "label", NULL, 0, 1, WINED3DSIH_LABEL, WINED3DVS_VERSION(2,0), -1 }, + + {WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, WINED3DSIH_SETP, 0, 0 }, + {WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, WINED3DSIH_TEXLDL, WINED3DVS_VERSION(3,0), -1 }, + {0, NULL, NULL, 0, 0, 0, 0, 0 } }; static void vshader_set_limits( diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d3478071209..b6f3fc6b4e7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -217,6 +217,96 @@ typedef struct SHADER_BUFFER { BOOL newline; } SHADER_BUFFER; +enum WINED3D_SHADER_INSTRUCTION_HANDLER +{ + WINED3DSIH_ABS, + WINED3DSIH_ADD, + WINED3DSIH_BEM, + WINED3DSIH_BREAK, + WINED3DSIH_BREAKC, + WINED3DSIH_BREAKP, + WINED3DSIH_CALL, + WINED3DSIH_CALLNZ, + WINED3DSIH_CMP, + WINED3DSIH_CND, + WINED3DSIH_CRS, + WINED3DSIH_DCL, + WINED3DSIH_DEF, + WINED3DSIH_DEFB, + WINED3DSIH_DEFI, + WINED3DSIH_DP2ADD, + WINED3DSIH_DP3, + WINED3DSIH_DP4, + WINED3DSIH_DST, + WINED3DSIH_DSX, + WINED3DSIH_DSY, + WINED3DSIH_ELSE, + WINED3DSIH_ENDIF, + WINED3DSIH_ENDLOOP, + WINED3DSIH_ENDREP, + WINED3DSIH_EXP, + WINED3DSIH_EXPP, + WINED3DSIH_FRC, + WINED3DSIH_IF, + WINED3DSIH_IFC, + WINED3DSIH_LABEL, + WINED3DSIH_LIT, + WINED3DSIH_LOG, + WINED3DSIH_LOGP, + WINED3DSIH_LOOP, + WINED3DSIH_LRP, + WINED3DSIH_M3x2, + WINED3DSIH_M3x3, + WINED3DSIH_M3x4, + WINED3DSIH_M4x3, + WINED3DSIH_M4x4, + WINED3DSIH_MAD, + WINED3DSIH_MAX, + WINED3DSIH_MIN, + WINED3DSIH_MOV, + WINED3DSIH_MOVA, + WINED3DSIH_MUL, + WINED3DSIH_NOP, + WINED3DSIH_NRM, + WINED3DSIH_PHASE, + WINED3DSIH_POW, + WINED3DSIH_RCP, + WINED3DSIH_REP, + WINED3DSIH_RET, + WINED3DSIH_RSQ, + WINED3DSIH_SETP, + WINED3DSIH_SGE, + WINED3DSIH_SGN, + WINED3DSIH_SINCOS, + WINED3DSIH_SLT, + WINED3DSIH_SUB, + WINED3DSIH_TEX, + WINED3DSIH_TEXBEM, + WINED3DSIH_TEXBEML, + WINED3DSIH_TEXCOORD, + WINED3DSIH_TEXDEPTH, + WINED3DSIH_TEXDP3, + WINED3DSIH_TEXDP3TEX, + WINED3DSIH_TEXKILL, + WINED3DSIH_TEXLDD, + WINED3DSIH_TEXLDL, + WINED3DSIH_TEXM3x2DEPTH, + WINED3DSIH_TEXM3x2PAD, + WINED3DSIH_TEXM3x2TEX, + WINED3DSIH_TEXM3x3, + WINED3DSIH_TEXM3x3DIFF, + WINED3DSIH_TEXM3x3PAD, + WINED3DSIH_TEXM3x3SPEC, + WINED3DSIH_TEXM3x3TEX, + WINED3DSIH_TEXM3x3VSPEC, + WINED3DSIH_TEXREG2AR, + WINED3DSIH_TEXREG2GB, + WINED3DSIH_TEXREG2RGB, + WINED3DSIH_TABLE_SIZE +}; + +typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*); + struct shader_caps { DWORD VertexShaderVersion; DWORD MaxVertexShaderConst; @@ -234,6 +324,7 @@ struct shader_caps { }; typedef struct { + const SHADER_HANDLER *shader_instruction_handler_table; void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS); void (*shader_select_depth_blt)(IWineD3DDevice *iface); void (*shader_deselect_depth_blt)(IWineD3DDevice *iface); @@ -250,7 +341,6 @@ typedef struct { BOOL (*shader_conv_supported)(WINED3DFORMAT conv); } shader_backend_t; -extern const shader_backend_t atifs_shader_backend; extern const shader_backend_t glsl_shader_backend; extern const shader_backend_t arb_program_shader_backend; extern const shader_backend_t none_shader_backend; @@ -629,6 +719,7 @@ typedef enum ContextUsage { void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage); WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms); void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context); +void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type); void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo); void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer); void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface); @@ -1448,6 +1539,7 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back); #define SFLAG_DS_LOCATIONS (SFLAG_DS_ONSCREEN | \ SFLAG_DS_OFFSCREEN) +#define SFLAG_DS_DISCARDED SFLAG_DS_LOCATIONS BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]); @@ -1499,6 +1591,7 @@ typedef struct IWineD3DVertexDeclarationImpl { IWineD3DDeviceImpl *wineD3DDevice; WINED3DVERTEXELEMENT *pDeclarationWine; + BOOL *ffp_valid; UINT declarationWNumElements; DWORD streams[MAX_STREAMS]; @@ -1744,7 +1837,6 @@ typedef struct IWineD3DSwapChainImpl /* IWineD3DSwapChain fields */ IWineD3DSurface **backBuffer; IWineD3DSurface *frontBuffer; - BOOL wantsDepthStencilBuffer; WINED3DPRESENT_PARAMETERS presentParms; DWORD orig_width, orig_height; WINED3DFORMAT orig_fmt; @@ -1882,7 +1974,6 @@ unsigned int count_bits(unsigned int mask); /*** class static members ***/ void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface); -typedef void (*SHADER_HANDLER) (struct SHADER_OPCODE_ARG*); /* TODO: Make this dynamic, based on shader limits ? */ #define MAX_REG_ADDR 1 @@ -1953,8 +2044,7 @@ typedef struct SHADER_OPCODE { const char* glname; char dst_token; CONST UINT num_params; - SHADER_HANDLER hw_fct; - SHADER_HANDLER hw_glsl_fct; + enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx; DWORD min_version; DWORD max_version; } SHADER_OPCODE; @@ -2021,104 +2111,9 @@ extern BOOL vshader_input_is_color( extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object); -/* ARB shader program Prototypes */ -extern void shader_hw_def(SHADER_OPCODE_ARG *arg); - -/* ARB pixel shader prototypes */ -extern void pshader_hw_bem(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_cnd(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_cmp(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_tex(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texbem(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texkill(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg); -extern void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg); - -/* ARB vertex / pixel shader common prototypes */ -extern void shader_hw_nrm(SHADER_OPCODE_ARG* arg); -extern void shader_hw_sincos(SHADER_OPCODE_ARG* arg); -extern void shader_hw_mnxn(SHADER_OPCODE_ARG* arg); - -/* ARB vertex shader prototypes */ -extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg); -extern void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg); - /* GLSL helper functions */ extern void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG *arg); -/** The following translate DirectX pixel/vertex shader opcodes to GLSL lines */ -extern void shader_glsl_cross(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_arith(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_mov(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_mad(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_lrp(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_dot(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_rcp(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_rsq(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_cnd(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_compare(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_def(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_defi(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_defb(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_expp(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_cmp(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_lit(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_dst(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_sincos(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_loop(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_end(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_if(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_ifc(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_else(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_break(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_breakc(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_rep(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_call(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_callnz(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_label(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_pow(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_log(SHADER_OPCODE_ARG* arg); -extern void shader_glsl_texldl(SHADER_OPCODE_ARG* arg); - -/** GLSL Pixel Shader Prototypes */ -extern void pshader_glsl_tex(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_bem(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg); -extern void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg); - /***************************************************************************** * IDirect3DBaseShader implementation structure */ @@ -2442,6 +2437,4 @@ static inline BOOL use_ps(IWineD3DDeviceImpl *device) { void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect, IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip); void depth_blt(IWineD3DDevice *iface, GLuint texture, GLsizei w, GLsizei h); - -void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry *entry); #endif diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index aae8f4b2cdf..39183e1cdbf 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2220,9 +2220,18 @@ int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) */ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ) { - Window win = X11DRV_get_whole_window( hwnd ); + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); - if (win) sync_window_opacity( thread_display(), win, key, alpha, flags ); + if (data) + { + if (data->whole_window) + sync_window_opacity( thread_display(), data->whole_window, key, alpha, flags ); + } + else + { + Window win = X11DRV_get_whole_window( hwnd ); + if (win) sync_window_opacity( gdi_display, win, key, alpha, flags ); + } } diff --git a/dlls/winhttp/Makefile.in b/dlls/winhttp/Makefile.in index cf188c7217c..3d85c4df01b 100644 --- a/dlls/winhttp/Makefile.in +++ b/dlls/winhttp/Makefile.in @@ -13,7 +13,8 @@ C_SRCS = \ main.c \ net.c \ request.c \ - session.c + session.c \ + url.c RC_SRCS = \ version.rc diff --git a/dlls/winhttp/main.c b/dlls/winhttp/main.c index 4a4aea8f65a..1a4a1313ac2 100644 --- a/dlls/winhttp/main.c +++ b/dlls/winhttp/main.c @@ -84,41 +84,3 @@ HRESULT WINAPI DllUnregisterServer(void) FIXME("()\n"); return S_OK; } - -#define SCHEME_HTTP 3 -#define SCHEME_HTTPS 4 - -BOOL WINAPI InternetCrackUrlW( LPCWSTR, DWORD, DWORD, LPURL_COMPONENTSW ); -BOOL WINAPI InternetCreateUrlW( LPURL_COMPONENTS, DWORD, LPWSTR, LPDWORD ); - -/*********************************************************************** - * WinHttpCrackUrl (winhttp.@) - */ -BOOL WINAPI WinHttpCrackUrl( LPCWSTR url, DWORD len, DWORD flags, LPURL_COMPONENTSW components ) -{ - BOOL ret; - - TRACE("%s, %d, %x, %p\n", debugstr_w(url), len, flags, components); - - if ((ret = InternetCrackUrlW( url, len, flags, components ))) - { - /* fix up an incompatibility between wininet and winhttp */ - if (components->nScheme == SCHEME_HTTP) components->nScheme = INTERNET_SCHEME_HTTP; - else if (components->nScheme == SCHEME_HTTPS) components->nScheme = INTERNET_SCHEME_HTTPS; - else - { - set_last_error( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ); - return FALSE; - } - } - return ret; -} - -/*********************************************************************** - * WinHttpCreateUrl (winhttp.@) - */ -BOOL WINAPI WinHttpCreateUrl( LPURL_COMPONENTS comps, DWORD flags, LPWSTR url, LPDWORD len ) -{ - TRACE("%p, 0x%08x, %p, %p\n", comps, flags, url, len); - return InternetCreateUrlW( comps, flags, url, len ); -} diff --git a/dlls/winhttp/tests/Makefile.in b/dlls/winhttp/tests/Makefile.in index 06890c4d5f3..561efac8a1d 100644 --- a/dlls/winhttp/tests/Makefile.in +++ b/dlls/winhttp/tests/Makefile.in @@ -7,6 +7,7 @@ IMPORTS = winhttp kernel32 CTESTS = \ notification.c \ + url.c \ winhttp.c @MAKE_TEST_RULES@ diff --git a/dlls/winhttp/tests/url.c b/dlls/winhttp/tests/url.c new file mode 100644 index 00000000000..20ff7f630d0 --- /dev/null +++ b/dlls/winhttp/tests/url.c @@ -0,0 +1,275 @@ +/* + * Copyright 2008 Hans Leidekker + * + * 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 "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winhttp.h" + +#include "wine/test.h" + +static WCHAR empty[] = {0}; +static WCHAR ftp[] = {'f','t','p',0}; +static WCHAR http[] = {'h','t','t','p',0}; +static WCHAR winehq[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0}; +static WCHAR username[] = {'u','s','e','r','n','a','m','e',0}; +static WCHAR password[] = {'p','a','s','s','w','o','r','d',0}; +static WCHAR about[] = {'/','s','i','t','e','/','a','b','o','u','t',0}; +static WCHAR query[] = {'?','q','u','e','r','y',0}; +static WCHAR escape[] = {' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`','{','|','}','~',0}; + +static const WCHAR url1[] = + {'h','t','t','p',':','/','/','u','s','e','r','n','a','m','e',':','p','a','s','s','w','o','r','d', + '@','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','s','i','t','e','/','a','b','o','u','t','?','q','u','e','r','y',0}; +static const WCHAR url2[] = + {'h','t','t','p',':','/','/','u','s','e','r','n','a','m','e', + '@','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','s','i','t','e','/','a','b','o','u','t','?','q','u','e','r','y',0}; +static const WCHAR url3[] = {'h','t','t','p',':','/','/','u','s','e','r','n','a','m','e',':',0}; +static const WCHAR url4[] = + {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','s','i','t','e','/','a','b','o','u','t','?','q','u','e','r','y',0}; +static const WCHAR url5[] = {'h','t','t','p',':','/','/',0}; +static const WCHAR url6[] = + {'f','t','p',':','/','/','u','s','e','r','n','a','m','e',':','p','a','s','s','w','o','r','d', + '@','w','w','w','.','w','i','n','e','h','q','.','o','r','g',':','8','0','/','s','i','t','e','/','a','b','o','u','t','?','q','u','e','r','y',0}; +static const WCHAR url7[] = + {'h','t','t','p',':','/','/','u','s','e','r','n','a','m','e',':','p','a','s','s','w','o','r','d', + '@','w','w','w','.','w','i','n','e','h','q','.','o','r','g',':','4','2','/','s','i','t','e','/','a','b','o','u','t','?','q','u','e','r','y',0}; +static const WCHAR url8[] = + {'h','t','t','p',':','/','/','u','s','e','r','n','a','m','e',':','p','a','s','s','w','o','r','d', + '@','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','s','i','t','e','/','a','b','o','u','t', + '%','2','0','!','%','2','2','%','2','3','$','%','2','5','&','\'','(',')','*','+',',','-','.','/',':',';','%','3','C','=','%','3','E','?','@','%', + '5','B','%','5','C','%','5','D','%','5','E','_','%','6','0','%','7','B','%','7','C','%','7','D','%','7','E',0}; +static const WCHAR url9[] = + {'h','t','t','p',':','/','/','u','s','e','r','n','a','m','e',':','p','a','s','s','w','o','r','d', + '@','w','w','w','.','w','i','n','e','h','q','.','o','r','g',':','0','/','s','i','t','e','/','a','b','o','u','t','?','q','u','e','r','y',0}; + +static void fill_url_components( URL_COMPONENTS *uc ) +{ + uc->dwStructSize = sizeof(URL_COMPONENTS); + uc->lpszScheme = http; + uc->dwSchemeLength = lstrlenW( uc->lpszScheme ); + uc->nScheme = INTERNET_SCHEME_HTTP; + uc->lpszHostName = winehq; + uc->dwHostNameLength = lstrlenW( uc->lpszHostName ); + uc->nPort = 80; + uc->lpszUserName = username; + uc->dwUserNameLength = lstrlenW( uc->lpszUserName ); + uc->lpszPassword = password; + uc->dwPasswordLength = lstrlenW( uc->lpszPassword ); + uc->lpszUrlPath = about; + uc->dwUrlPathLength = lstrlenW( uc->lpszUrlPath ); + uc->lpszExtraInfo = query; + uc->dwExtraInfoLength = lstrlenW( uc->lpszExtraInfo ); +} + +static void WinHttpCreateUrl_test( void ) +{ + URL_COMPONENTS uc; + WCHAR *url; + DWORD len; + BOOL ret; + + /* NULL components */ + len = ~0UL; + SetLastError( 0xdeadbeef ); + ret = WinHttpCreateUrl( NULL, 0, NULL, &len ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", GetLastError() ); + ok( len == ~0UL, "expected len ~0UL got %u\n", len ); + + /* zero'ed components */ + memset( &uc, 0, sizeof(URL_COMPONENTS) ); + SetLastError( 0xdeadbeef ); + ret = WinHttpCreateUrl( &uc, 0, NULL, &len ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", GetLastError() ); + ok( len == ~0UL, "expected len ~0UL got %u\n", len ); + + /* valid components, NULL url, NULL length */ + fill_url_components( &uc ); + SetLastError( 0xdeadbeef ); + ret = WinHttpCreateUrl( &uc, 0, NULL, NULL ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", GetLastError() ); + ok( len == ~0UL, "expected len ~0UL got %u\n", len ); + + /* valid components, NULL url */ + SetLastError( 0xdeadbeef ); + ret = WinHttpCreateUrl( &uc, 0, NULL, &len ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError() ); + ok( len == 57, "expected len 57 got %u\n", len ); + + /* correct size, NULL url */ + fill_url_components( &uc ); + SetLastError( 0xdeadbeef ); + ret = WinHttpCreateUrl( &uc, 0, NULL, &len ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError() ); + ok( len == 57, "expected len 57 got %u\n", len ); + + /* valid components, allocated url, short length */ + SetLastError( 0xdeadbeef ); + url = HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) ); + url[0] = 0; + len = 2; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError() ); + ok( len == 57, "expected len 57 got %u\n", len ); + + /* allocated url, NULL scheme */ + uc.lpszScheme = NULL; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 56, "expected len 56 got %u\n", len ); + ok( !lstrcmpW( url, url1 ), "url doesn't match\n" ); + + /* allocated url, 0 scheme */ + fill_url_components( &uc ); + uc.nScheme = 0; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 56, "expected len 56 got %u\n", len ); + + /* valid components, allocated url */ + fill_url_components( &uc ); + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 56, "expected len 56 got %d\n", len ); + ok( !lstrcmpW( url, url1 ), "url doesn't match\n" ); + + /* valid username, NULL password */ + fill_url_components( &uc ); + uc.lpszPassword = NULL; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + + /* valid username, empty password */ + fill_url_components( &uc ); + uc.lpszPassword = empty; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 56, "expected len 56 got %u\n", len ); + ok( !lstrcmpW( url, url3 ), "url doesn't match\n" ); + + /* valid password, NULL username */ + fill_url_components( &uc ); + SetLastError( 0xdeadbeef ); + uc.lpszUserName = NULL; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( !ret, "expected failure\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", GetLastError() ); + + /* valid password, empty username */ + fill_url_components( &uc ); + uc.lpszUserName = empty; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n"); + + /* NULL username, NULL password */ + fill_url_components( &uc ); + uc.lpszUserName = NULL; + uc.lpszPassword = NULL; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 38, "expected len 38 got %u\n", len ); + ok( !lstrcmpW( url, url4 ), "url doesn't match\n" ); + + /* empty username, empty password */ + fill_url_components( &uc ); + uc.lpszUserName = empty; + uc.lpszPassword = empty; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 56, "expected len 56 got %u\n", len ); + ok( !lstrcmpW( url, url5 ), "url doesn't match\n" ); + + /* nScheme has lower precedence than lpszScheme */ + fill_url_components( &uc ); + uc.lpszScheme = ftp; + uc.dwSchemeLength = lstrlenW( uc.lpszScheme ); + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == lstrlenW( url6 ), "expected len %d got %u\n", lstrlenW( url6 ) + 1, len ); + ok( !lstrcmpW( url, url6 ), "url doesn't match\n" ); + + /* non-standard port */ + uc.lpszScheme = http; + uc.dwSchemeLength = lstrlenW( uc.lpszScheme ); + uc.nPort = 42; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 59, "expected len 59 got %u\n", len ); + ok( !lstrcmpW( url, url7 ), "url doesn't match\n" ); + + /* escape extra info */ + fill_url_components( &uc ); + uc.lpszExtraInfo = escape; + uc.dwExtraInfoLength = lstrlenW( uc.lpszExtraInfo ); + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, ICU_ESCAPE, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 113, "expected len 113 got %u\n", len ); + ok( !lstrcmpW( url, url8 ), "url doesn't match\n" ); + + /* NULL lpszScheme, 0 nScheme and nPort */ + fill_url_components( &uc ); + uc.lpszScheme = NULL; + uc.dwSchemeLength = 0; + uc.nScheme = 0; + uc.nPort = 0; + url[0] = 0; + len = 256; + ret = WinHttpCreateUrl( &uc, 0, url, &len ); + ok( ret, "expected success\n" ); + ok( len == 58, "expected len 58 got %u\n", len ); + ok( !lstrcmpW( url, url9 ), "url doesn't match\n" ); + + HeapFree( GetProcessHeap(), 0, url ); +} + +START_TEST(url) +{ + WinHttpCreateUrl_test(); +} diff --git a/dlls/winhttp/url.c b/dlls/winhttp/url.c new file mode 100644 index 00000000000..7d739d5a050 --- /dev/null +++ b/dlls/winhttp/url.c @@ -0,0 +1,333 @@ +/* + * Copyright 2008 Hans Leidekker for CodeWeavers + * + * 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 + +#include "wine/debug.h" + +#include "windef.h" +#include "winbase.h" +#include "winhttp.h" + +#include "winhttp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhttp); + +#define SCHEME_HTTP 3 +#define SCHEME_HTTPS 4 + +BOOL WINAPI InternetCrackUrlW( LPCWSTR, DWORD, DWORD, LPURL_COMPONENTSW ); + +/*********************************************************************** + * WinHttpCrackUrl (winhttp.@) + */ +BOOL WINAPI WinHttpCrackUrl( LPCWSTR url, DWORD len, DWORD flags, LPURL_COMPONENTSW components ) +{ + BOOL ret; + + TRACE("%s, %d, %x, %p\n", debugstr_w(url), len, flags, components); + + if ((ret = InternetCrackUrlW( url, len, flags, components ))) + { + /* fix up an incompatibility between wininet and winhttp */ + if (components->nScheme == SCHEME_HTTP) components->nScheme = INTERNET_SCHEME_HTTP; + else if (components->nScheme == SCHEME_HTTPS) components->nScheme = INTERNET_SCHEME_HTTPS; + else + { + set_last_error( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ); + return FALSE; + } + } + return ret; +} + +static const WCHAR scheme_http[] = {'h','t','t','p',0}; +static const WCHAR scheme_https[] = {'h','t','t','p','s',0}; + +static INTERNET_SCHEME get_scheme( const WCHAR *scheme, DWORD len ) +{ + if (!strncmpW( scheme, scheme_http, len )) return INTERNET_SCHEME_HTTP; + if (!strncmpW( scheme, scheme_https, len )) return INTERNET_SCHEME_HTTPS; + return 0; +} + +static const WCHAR *get_scheme_string( INTERNET_SCHEME scheme ) +{ + if (scheme == INTERNET_SCHEME_HTTP) return scheme_http; + if (scheme == INTERNET_SCHEME_HTTPS) return scheme_https; + return NULL; +} + +static BOOL uses_default_port( INTERNET_SCHEME scheme, INTERNET_PORT port ) +{ + if ((scheme == INTERNET_SCHEME_HTTP) && (port == INTERNET_DEFAULT_HTTP_PORT)) return TRUE; + if ((scheme == INTERNET_SCHEME_HTTPS) && (port == INTERNET_DEFAULT_HTTPS_PORT)) return TRUE; + return FALSE; +} + +static BOOL need_escape( WCHAR c ) +{ + if (isalnumW( c )) return FALSE; + + if (c <= 31 || c >= 127) return TRUE; + else + { + switch (c) + { + case ' ': + case '"': + case '#': + case '%': + case '<': + case '>': + case ']': + case '\\': + case '[': + case '^': + case '`': + case '{': + case '|': + case '}': + case '~': + return TRUE; + default: + return FALSE; + } + } +} + +static DWORD copy_escape( WCHAR *dst, const WCHAR *src, DWORD len ) +{ + static const WCHAR hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + DWORD ret = len; + unsigned int i; + WCHAR *p = dst; + + for (i = 0; i < len; i++, p++) + { + if (need_escape( src[i] )) + { + p[0] = '%'; + p[1] = hex[(src[i] >> 4) & 0xf]; + p[2] = hex[src[i] & 0xf]; + ret += 2; + p += 2; + } + else *p = src[i]; + } + dst[ret] = 0; + return ret; +} + +static DWORD comp_length( DWORD len, DWORD flags, WCHAR *comp ) +{ + DWORD ret; + unsigned int i; + + ret = len ? len : strlenW( comp ); + if (!(flags & ICU_ESCAPE)) return ret; + for (i = 0; i < len; i++) if (need_escape( comp[i] )) ret += 2; + return ret; +} + +static BOOL calc_length( URL_COMPONENTS *uc, DWORD flags, LPDWORD len ) +{ + static const WCHAR formatW[] = {'%','d',0}; + INTERNET_SCHEME scheme; + + *len = 0; + if (uc->lpszScheme) + { + DWORD scheme_len = comp_length( uc->dwSchemeLength, 0, uc->lpszScheme ); + *len += scheme_len; + scheme = get_scheme( uc->lpszScheme, scheme_len ); + } + else + { + scheme = uc->nScheme; + if (!scheme) scheme = INTERNET_SCHEME_HTTP; + *len += strlenW( get_scheme_string( scheme ) ); + } + *len += 1; /* ':' */ + if (uc->lpszHostName) *len += 2; /* "//" */ + + if (uc->lpszUserName) + { + *len += comp_length( uc->dwUserNameLength, 0, uc->lpszUserName ); + *len += 1; /* "@" */ + } + else + { + if (uc->lpszPassword) + { + set_last_error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + } + if (uc->lpszPassword) + { + *len += 1; /* ":" */ + *len += comp_length( uc->dwPasswordLength, 0, uc->lpszPassword ); + } + if (uc->lpszHostName) + { + *len += comp_length( uc->dwHostNameLength, 0, uc->lpszHostName ); + + if (!uses_default_port( scheme, uc->nPort )) + { + WCHAR port[sizeof("65535")]; + + sprintfW( port, formatW, uc->nPort ); + *len += strlenW( port ); + *len += 1; /* ":" */ + } + if (uc->lpszUrlPath && *uc->lpszUrlPath != '/') *len += 1; /* '/' */ + } + if (uc->lpszUrlPath) *len += comp_length( uc->dwUrlPathLength, flags, uc->lpszUrlPath ); + if (uc->lpszExtraInfo) *len += comp_length( uc->dwExtraInfoLength, flags, uc->lpszExtraInfo ); + return TRUE; +} + +/*********************************************************************** + * WinHttpCreateUrl (winhttp.@) + */ +BOOL WINAPI WinHttpCreateUrl( LPURL_COMPONENTS uc, DWORD flags, LPWSTR url, LPDWORD required ) +{ + static const WCHAR formatW[] = {'%','d',0}; + static const WCHAR twoslashW[] = {'/','/'}; + + DWORD len; + INTERNET_SCHEME scheme; + + TRACE("%p, 0x%08x, %p, %p\n", uc, flags, url, required); + + if (!uc || uc->dwStructSize != sizeof(URL_COMPONENTS) || !required) + { + set_last_error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!calc_length( uc, flags, &len )) return FALSE; + + if (!url || *required < len) + { + *required = len + 1; + set_last_error( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + + url[0] = 0; + *required = len; + if (uc->lpszScheme) + { + len = comp_length( uc->dwSchemeLength, 0, uc->lpszScheme ); + memcpy( url, uc->lpszScheme, len * sizeof(WCHAR) ); + url += len; + + scheme = get_scheme( uc->lpszScheme, len ); + } + else + { + const WCHAR *schemeW; + scheme = uc->nScheme; + + if (!scheme) scheme = INTERNET_SCHEME_HTTP; + + schemeW = get_scheme_string( scheme ); + len = strlenW( schemeW ); + memcpy( url, schemeW, len * sizeof(WCHAR) ); + url += len; + } + + /* all schemes are followed by at least a colon */ + *url = ':'; + url++; + + if (uc->lpszHostName) + { + memcpy( url, twoslashW, sizeof(twoslashW) ); + url += sizeof(twoslashW) / sizeof(twoslashW[0]); + } + if (uc->lpszUserName) + { + len = comp_length( uc->dwUserNameLength, 0, uc->lpszUserName ); + memcpy( url, uc->lpszUserName, len * sizeof(WCHAR) ); + url += len; + + if (uc->lpszPassword) + { + *url = ':'; + url++; + + len = comp_length( uc->dwPasswordLength, 0, uc->lpszPassword ); + memcpy( url, uc->lpszPassword, len * sizeof(WCHAR) ); + url += len; + } + *url = '@'; + url++; + } + if (uc->lpszHostName) + { + len = comp_length( uc->dwHostNameLength, 0, uc->lpszHostName ); + memcpy( url, uc->lpszHostName, len * sizeof(WCHAR) ); + url += len; + + if (!uses_default_port( scheme, uc->nPort )) + { + WCHAR port[sizeof("65535")]; + + sprintfW( port, formatW, uc->nPort ); + *url = ':'; + url++; + + len = strlenW( port ); + memcpy( url, port, len * sizeof(WCHAR) ); + url += len; + } + + /* add slash between hostname and path if necessary */ + if (uc->lpszUrlPath && *uc->lpszUrlPath != '/') + { + *url = '/'; + url++; + } + } + if (uc->lpszUrlPath) + { + len = comp_length( uc->dwUrlPathLength, 0, uc->lpszUrlPath ); + if (flags & ICU_ESCAPE) url += copy_escape( url, uc->lpszUrlPath, len ); + else + { + memcpy( url, uc->lpszUrlPath, len * sizeof(WCHAR) ); + url += len; + } + } + if (uc->lpszExtraInfo) + { + len = comp_length( uc->dwExtraInfoLength, 0, uc->lpszExtraInfo ); + if (flags & ICU_ESCAPE) url += copy_escape( url, uc->lpszExtraInfo, len ); + else + { + memcpy( url, uc->lpszExtraInfo, len * sizeof(WCHAR) ); + url += len; + } + } + *url = 0; + return TRUE; +} diff --git a/dlls/wintrust/softpub.c b/dlls/wintrust/softpub.c index f8bf69e2215..52df73d3a70 100644 --- a/dlls/wintrust/softpub.c +++ b/dlls/wintrust/softpub.c @@ -552,6 +552,20 @@ BOOL WINAPI SoftpubCheckCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner, return ret; } +static DWORD WINTRUST_TrustStatusToConfidence(DWORD errorStatus) +{ + DWORD confidence = 0; + + confidence = 0; + if (!(errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID)) + confidence |= CERT_CONFIDENCE_SIG; + if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_VALID)) + confidence |= CERT_CONFIDENCE_TIME; + if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED)) + confidence |= CERT_CONFIDENCE_TIMENEST; + return confidence; +} + static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx) { BOOL ret; @@ -559,6 +573,11 @@ static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx) data->pasSigners[signerIdx].pChainContext->rgpChain[0]; DWORD i; + data->pasSigners[signerIdx].pasCertChain[0].dwConfidence = + WINTRUST_TrustStatusToConfidence( + simpleChain->rgpElement[0]->TrustStatus.dwErrorStatus); + data->pasSigners[signerIdx].pasCertChain[0].dwError = + simpleChain->rgpElement[0]->TrustStatus.dwErrorStatus; data->pasSigners[signerIdx].pasCertChain[0].pChainElement = simpleChain->rgpElement[0]; ret = TRUE; @@ -567,8 +586,15 @@ static BOOL WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx) ret = data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0, simpleChain->rgpElement[i]->pCertContext); if (ret) + { data->pasSigners[signerIdx].pasCertChain[i].pChainElement = simpleChain->rgpElement[i]; + data->pasSigners[signerIdx].pasCertChain[i].dwConfidence = + WINTRUST_TrustStatusToConfidence( + simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus); + data->pasSigners[signerIdx].pasCertChain[i].dwError = + simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus; + } } return ret; } @@ -580,6 +606,11 @@ static void WINTRUST_CreateChainPolicyCreateInfo( chainPara->cbSize = sizeof(CERT_CHAIN_PARA); if (data->pRequestUsage) chainPara->RequestedUsage = *data->pRequestUsage; + else + { + chainPara->RequestedUsage.dwType = 0; + chainPara->RequestedUsage.Usage.cUsageIdentifier = 0; + } info->u.cbSize = sizeof(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO); info->hChainEngine = NULL; info->pChainPara = chainPara; @@ -599,7 +630,20 @@ static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data, PCERT_CHAIN_PARA chainPara) { BOOL ret = TRUE; + HCERTSTORE store = NULL; + + if (data->chStores) + { + store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + if (store) + { + DWORD i; + for (i = 0; i < data->chStores; i++) + CertAddStoreToCollection(store, data->pahStores[i], 0, 0); + } + } /* Expect the end certificate for each signer to be the only cert in the * chain: */ @@ -608,8 +652,7 @@ static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data, /* Create a certificate chain for each signer */ ret = CertGetCertificateChain(createInfo->hChainEngine, data->pasSigners[signer].pasCertChain[0].pCert, - &data->pasSigners[signer].sftVerifyAsOf, - data->chStores ? data->pahStores[0] : NULL, + &data->pasSigners[signer].sftVerifyAsOf, store, chainPara, createInfo->dwFlags, createInfo->pvReserved, &data->pasSigners[signer].pChainContext); if (ret) @@ -622,11 +665,17 @@ static BOOL WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data, else { if ((ret = WINTRUST_CopyChain(data, signer))) - ret = data->psPfns->pfnCertCheckPolicy(data, signer, FALSE, - 0); + { + if (data->psPfns->pfnCertCheckPolicy) + ret = data->psPfns->pfnCertCheckPolicy(data, signer, + FALSE, 0); + else + TRACE("no cert check policy, skipping policy check\n"); + } } } } + CertCloseStore(store, 0); return ret; } @@ -735,27 +784,60 @@ HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *data) ret = TRUE; for (i = 0; ret && i < data->csSigners; i++) { - CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 }; - - if (data->dwRegPolicySettings & WTPF_TRUSTTEST) - policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG; - if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID) - policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG; - if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION) - policyPara.dwFlags |= - CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | - CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG | - CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG; - if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION) - policyPara.dwFlags |= - CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG | - CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG | - CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG | - CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG; - CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, - data->pasSigners[i].pChainContext, &policyPara, &policyStatus); - if (policyStatus.dwError != NO_ERROR) - ret = FALSE; + BYTE hash[20]; + DWORD size = sizeof(hash); + + /* First make sure cert isn't disallowed */ + if ((ret = CertGetCertificateContextProperty( + data->pasSigners[i].pasCertChain[0].pCert, + CERT_SIGNATURE_HASH_PROP_ID, hash, &size))) + { + static const WCHAR disallowedW[] = + { 'D','i','s','a','l','l','o','w','e','d',0 }; + HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, + X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, + disallowedW); + + if (disallowed) + { + PCCERT_CONTEXT found = CertFindCertificateInStore( + disallowed, X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, + hash, NULL); + + if (found) + { + /* Disallowed! Can't verify it. */ + policyStatus.dwError = TRUST_E_SUBJECT_NOT_TRUSTED; + ret = FALSE; + CertFreeCertificateContext(found); + } + CertCloseStore(disallowed, 0); + } + } + if (ret) + { + CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 }; + + if (data->dwRegPolicySettings & WTPF_TRUSTTEST) + policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG; + if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID) + policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG; + if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION) + policyPara.dwFlags |= + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | + CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG | + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG; + if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION) + policyPara.dwFlags |= + CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG | + CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG | + CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG | + CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG; + CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, + data->pasSigners[i].pChainContext, &policyPara, &policyStatus); + if (policyStatus.dwError != NO_ERROR) + ret = FALSE; + } } } if (!ret) diff --git a/dlls/wintrust/wintrust_main.c b/dlls/wintrust/wintrust_main.c index 84bd2aa2c95..2218ca04866 100644 --- a/dlls/wintrust/wintrust_main.c +++ b/dlls/wintrust/wintrust_main.c @@ -33,6 +33,7 @@ #include "mscat.h" #include "objbase.h" #include "winuser.h" +#include "cryptdlg.h" #include "wintrust_priv.h" #include "wine/debug.h" @@ -88,15 +89,9 @@ static DWORD WINTRUST_ExecuteSteps(const struct wintrust_step *steps, return err; } -static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID, - WINTRUST_DATA *data) +static CRYPT_PROVIDER_DATA *WINTRUST_AllocateProviderData(void) { - DWORD err = ERROR_SUCCESS, numSteps = 0; CRYPT_PROVIDER_DATA *provData; - BOOL ret; - struct wintrust_step verifySteps[5]; - - TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); provData = WINTRUST_Alloc(sizeof(CRYPT_PROVIDER_DATA)); if (!provData) @@ -118,6 +113,69 @@ static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID, if (!provData->psPfns) goto oom; provData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS); + return provData; + +oom: + if (provData) + { + WINTRUST_Free(provData->padwTrustStepErrors); + WINTRUST_Free(provData->u.pPDSip); + WINTRUST_Free(provData->psPfns); + WINTRUST_Free(provData); + } + return NULL; +} + +/* Adds trust steps for each function in psPfns. Assumes steps has at least + * 5 entries. Returns the number of steps added. + */ +static DWORD WINTRUST_AddTrustStepsFromFunctions(struct wintrust_step *steps, + const CRYPT_PROVIDER_FUNCTIONS *psPfns) +{ + DWORD numSteps = 0; + + if (psPfns->pfnInitialize) + { + steps[numSteps].func = psPfns->pfnInitialize; + steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT; + } + if (psPfns->pfnObjectTrust) + { + steps[numSteps].func = psPfns->pfnObjectTrust; + steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV; + } + if (psPfns->pfnSignatureTrust) + { + steps[numSteps].func = psPfns->pfnSignatureTrust; + steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV; + } + if (psPfns->pfnCertificateTrust) + { + steps[numSteps].func = psPfns->pfnCertificateTrust; + steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV; + } + if (psPfns->pfnFinalPolicy) + { + steps[numSteps].func = psPfns->pfnFinalPolicy; + steps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV; + } + return numSteps; +} + +static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID, + WINTRUST_DATA *data) +{ + DWORD err = ERROR_SUCCESS, numSteps = 0; + CRYPT_PROVIDER_DATA *provData; + BOOL ret; + struct wintrust_step verifySteps[5]; + + TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); + + provData = WINTRUST_AllocateProviderData(); + if (!provData) + return ERROR_OUTOFMEMORY; + ret = WintrustLoadFunctionPointers(actionID, provData->psPfns); if (!ret) { @@ -134,36 +192,11 @@ static LONG WINTRUST_DefaultVerify(HWND hwnd, GUID *actionID, provData->pgActionID = actionID; WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings); - if (provData->psPfns->pfnInitialize) - { - verifySteps[numSteps].func = provData->psPfns->pfnInitialize; - verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_WVTINIT; - } - if (provData->psPfns->pfnObjectTrust) - { - verifySteps[numSteps].func = provData->psPfns->pfnObjectTrust; - verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_OBJPROV; - } - if (provData->psPfns->pfnSignatureTrust) - { - verifySteps[numSteps].func = provData->psPfns->pfnSignatureTrust; - verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_SIGPROV; - } - if (provData->psPfns->pfnCertificateTrust) - { - verifySteps[numSteps].func = provData->psPfns->pfnCertificateTrust; - verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_CERTPROV; - } - if (provData->psPfns->pfnFinalPolicy) - { - verifySteps[numSteps].func = provData->psPfns->pfnFinalPolicy; - verifySteps[numSteps++].error_index = TRUSTERROR_STEP_FINAL_POLICYPROV; - } + numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps, + provData->psPfns); err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData); goto done; -oom: - err = ERROR_OUTOFMEMORY; error: if (provData) { @@ -235,6 +268,184 @@ static LONG WINTRUST_PublishedSoftware(HWND hwnd, GUID *actionID, return WINTRUST_DefaultVerifyAndClose(hwnd, actionID, &wintrust_data); } +/* Sadly, the function to load the cert for the CERT_CERTIFICATE_ACTION_VERIFY + * action is not stored in the registry and is located in wintrust, not in + * cryptdlg along with the rest of the implementation (verified by running the + * action with a native wintrust.dll.) + */ +static HRESULT WINAPI WINTRUST_CertVerifyObjTrust(CRYPT_PROVIDER_DATA *data) +{ + BOOL ret; + + TRACE("(%p)\n", data); + + if (!data->padwTrustStepErrors) + return S_FALSE; + + switch (data->pWintrustData->dwUnionChoice) + { + case WTD_CHOICE_BLOB: + if (data->pWintrustData->u.pBlob && + data->pWintrustData->u.pBlob->cbStruct == sizeof(WINTRUST_BLOB_INFO) && + data->pWintrustData->u.pBlob->cbMemObject == + sizeof(CERT_VERIFY_CERTIFICATE_TRUST) && + data->pWintrustData->u.pBlob->pbMemObject) + { + CERT_VERIFY_CERTIFICATE_TRUST *pCert = + (CERT_VERIFY_CERTIFICATE_TRUST *) + data->pWintrustData->u.pBlob->pbMemObject; + + if (pCert->cbSize == sizeof(CERT_VERIFY_CERTIFICATE_TRUST) && + pCert->pccert) + { + CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } }; + DWORD i; + SYSTEMTIME sysTime; + + /* Add a signer with nothing but the time to verify, so we can + * add a cert to it + */ + GetSystemTime(&sysTime); + SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf); + ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer); + if (!ret) + goto error; + ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0, + pCert->pccert); + if (!ret) + goto error; + for (i = 0; ret && i < pCert->cRootStores; i++) + ret = data->psPfns->pfnAddStore2Chain(data, + pCert->rghstoreRoots[i]); + for (i = 0; ret && i < pCert->cStores; i++) + ret = data->psPfns->pfnAddStore2Chain(data, + pCert->rghstoreCAs[i]); + for (i = 0; ret && i < pCert->cTrustStores; i++) + ret = data->psPfns->pfnAddStore2Chain(data, + pCert->rghstoreTrust[i]); + } + else + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + } + else + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + break; + default: + FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice); + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + +error: + if (!ret) + data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = + GetLastError(); + TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE, + data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]); + return ret ? S_OK : S_FALSE; +} + +static LONG WINTRUST_CertVerify(HWND hwnd, GUID *actionID, + WINTRUST_DATA *data) +{ + DWORD err = ERROR_SUCCESS, numSteps = 0; + CRYPT_PROVIDER_DATA *provData; + BOOL ret; + struct wintrust_step verifySteps[5]; + + TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); + + provData = WINTRUST_AllocateProviderData(); + if (!provData) + return ERROR_OUTOFMEMORY; + + ret = WintrustLoadFunctionPointers(actionID, provData->psPfns); + if (!ret) + { + err = GetLastError(); + goto error; + } + if (!provData->psPfns->pfnObjectTrust) + provData->psPfns->pfnObjectTrust = WINTRUST_CertVerifyObjTrust; + /* Not sure why, but native skips the policy check */ + provData->psPfns->pfnCertCheckPolicy = NULL; + + data->hWVTStateData = (HANDLE)provData; + provData->pWintrustData = data; + if (hwnd == INVALID_HANDLE_VALUE) + provData->hWndParent = GetDesktopWindow(); + else + provData->hWndParent = hwnd; + provData->pgActionID = actionID; + WintrustGetRegPolicyFlags(&provData->dwRegPolicySettings); + + numSteps = WINTRUST_AddTrustStepsFromFunctions(verifySteps, + provData->psPfns); + err = WINTRUST_ExecuteSteps(verifySteps, numSteps, provData); + goto done; + +error: + if (provData) + { + WINTRUST_Free(provData->padwTrustStepErrors); + WINTRUST_Free(provData->u.pPDSip); + WINTRUST_Free(provData->psPfns); + WINTRUST_Free(provData); + } +done: + TRACE("returning %08x\n", err); + return err; +} + +static LONG WINTRUST_CertVerifyAndClose(HWND hwnd, GUID *actionID, + WINTRUST_DATA *data) +{ + LONG err; + + TRACE("(%p, %s, %p)\n", hwnd, debugstr_guid(actionID), data); + + err = WINTRUST_CertVerify(hwnd, actionID, data); + WINTRUST_DefaultClose(hwnd, actionID, data); + TRACE("returning %08x\n", err); + return err; +} + +static LONG WINTRUST_CertActionVerify(HWND hwnd, GUID *actionID, + WINTRUST_DATA *data) +{ + DWORD stateAction; + LONG err = ERROR_SUCCESS; + + if (WVT_ISINSTRUCT(WINTRUST_DATA, data->cbStruct, dwStateAction)) + stateAction = data->dwStateAction; + else + { + TRACE("no dwStateAction, assuming WTD_STATEACTION_IGNORE\n"); + stateAction = WTD_STATEACTION_IGNORE; + } + switch (stateAction) + { + case WTD_STATEACTION_IGNORE: + err = WINTRUST_CertVerifyAndClose(hwnd, actionID, data); + break; + case WTD_STATEACTION_VERIFY: + err = WINTRUST_CertVerify(hwnd, actionID, data); + break; + case WTD_STATEACTION_CLOSE: + err = WINTRUST_DefaultClose(hwnd, actionID, data); + break; + default: + FIXME("unimplemented for %d\n", data->dwStateAction); + } + return err; +} + static void dump_file_info(WINTRUST_FILE_INFO *pFile) { TRACE("%p\n", pFile); @@ -370,6 +581,7 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData ) static const GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; static const GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY; static const GUID generic_chain_verify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY; + static const GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY; LONG err = ERROR_SUCCESS; WINTRUST_DATA *actionData = (WINTRUST_DATA *)ActionData; @@ -379,6 +591,8 @@ LONG WINAPI WinVerifyTrust( HWND hwnd, GUID *ActionID, LPVOID ActionData ) /* Support for known old-style callers: */ if (IsEqualGUID(ActionID, &published_software)) err = WINTRUST_PublishedSoftware(hwnd, ActionID, ActionData); + else if (IsEqualGUID(ActionID, &cert_action_verify)) + err = WINTRUST_CertActionVerify(hwnd, ActionID, ActionData); else { DWORD stateAction; diff --git a/include/Makefile.in b/include/Makefile.in index 415ac1b3597..f28cfab44ae 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -373,6 +373,7 @@ SRCDIR_INCLUDES = \ sensapi.h \ setupapi.h \ sfc.h \ + shdispid.h \ shellapi.h \ shlguid.h \ shlobj.h \ diff --git a/include/config.h.in b/include/config.h.in index 6ce0751831b..49ed198d667 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -1068,6 +1068,9 @@ /* Define to the soname of the libGLU library. */ #undef SONAME_LIBGLU +/* Define to the soname of the libgnutls library. */ +#undef SONAME_LIBGNUTLS + /* Define to the soname of the libhal library. */ #undef SONAME_LIBHAL diff --git a/include/d3d8types.h b/include/d3d8types.h index 2ed2bf9c978..21e30b5e63c 100644 --- a/include/d3d8types.h +++ b/include/d3d8types.h @@ -1131,6 +1131,8 @@ typedef struct _D3DPRESENT_PARAMETERS_ { } D3DPRESENT_PARAMETERS; +#define D3DPRESENTFLAG_LOCKABLE_BACKBUFFER 0x00000001 + typedef struct _D3DRANGE { UINT Offset; UINT Size; diff --git a/include/d3d9types.h b/include/d3d9types.h index 86423392634..61e321c2e95 100644 --- a/include/d3d9types.h +++ b/include/d3d9types.h @@ -201,6 +201,8 @@ #define D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL 0x00000002 /* Discard Z buffer */ #define D3DPRESENTFLAG_DEVICECLIP 0x00000004 /* Clip the window blited into the client area 2k + xp only */ #define D3DPRESENTFLAG_VIDEO 0x00000010 /* backbuffer 'may' contain video data */ +#define D3DPRESENTFLAG_NOAUTOROTATE 0x00000020 /* d3d9ex, ignore display rotation */ +#define D3DPRESENTFLAG_UNPRUNEDMODE 0x00000040 /* d3d9ex, specify invalid display modes */ #define D3DPRESENT_BACK_BUFFERS_MAX 3L #define D3DPRESENT_RATE_DEFAULT 0x00000000 diff --git a/include/rpcdce.h b/include/rpcdce.h index 8c10233d9bd..1fca11bff37 100644 --- a/include/rpcdce.h +++ b/include/rpcdce.h @@ -79,6 +79,12 @@ typedef struct RPC_IF_ID *IfId[1]; } RPC_IF_ID_VECTOR; +typedef struct +{ + unsigned int Count; + unsigned long Stats[1]; +} RPC_STATS_VECTOR; + typedef I_RPC_HANDLE *RPC_EP_INQ_HANDLE; #define RPC_C_EP_ALL_ELTS 0 diff --git a/include/shdispid.h b/include/shdispid.h new file mode 100644 index 00000000000..5b3fc40d1ef --- /dev/null +++ b/include/shdispid.h @@ -0,0 +1,30 @@ +/* + * DispIds for Shell Interfaces + * + * Copyright (C) 2008 Robert Shearman + * + * 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 + */ + +#ifndef _SHDISPID_H_ +#define _SHDISPID_H_ + +#define DISPID_SELECTIONCHANGED 200 +#define DISPID_FILELISTENUMDONE 201 +#define DISPID_VERBINVOKED 202 +#define DISPID_DEFAULTVERBINVOKED 203 +#define DISPID_BEGINDRAG 204 + +#endif /* defined _SHDISPID_H_ */ diff --git a/include/shldisp.idl b/include/shldisp.idl index ee722611304..28c2357bdd7 100644 --- a/include/shldisp.idl +++ b/include/shldisp.idl @@ -25,6 +25,8 @@ import "shtypes.idl"; import "servprov.idl"; import "comcat.idl"; +#include + /***************************************************************************** * IAutoComplete interface */ @@ -85,6 +87,29 @@ interface IFolderViewOC : IDispatch } [ + uuid(62112aa2-ebe4-11cf-a5fb-0020afe7292d) +] +dispinterface DShellFolderViewEvents +{ + properties: + methods: + [id(DISPID_SELECTIONCHANGED)] + void SelectionChanged(); + + [id(DISPID_FILELISTENUMDONE)] + void EnumDone(); + + [id(DISPID_VERBINVOKED)] + VARIANT_BOOL VerbInvoked(); + + [id(DISPID_DEFAULTVERBINVOKED)] + VARIANT_BOOL DefaultVerbInvoked(); + + [id(DISPID_BEGINDRAG)] + VARIANT_BOOL BeginDrag(); +} + +[ uuid(9ba05971-f6a8-11cf-a442-00a0c90a8f39), hidden ] diff --git a/include/wine/wined3d_types.h b/include/wine/wined3d_types.h index 5b722e775c0..2e7d5d7f339 100644 --- a/include/wine/wined3d_types.h +++ b/include/wine/wined3d_types.h @@ -888,6 +888,13 @@ typedef struct _WINED3DPRESENT_PARAMETERS { UINT PresentationInterval; } WINED3DPRESENT_PARAMETERS; +#define WINED3DPRESENTFLAG_LOCKABLE_BACKBUFFER 0x00000001 +#define WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL 0x00000002 +#define WINED3DPRESENTFLAG_DEVICECLIP 0x00000004 +#define WINED3DPRESENTFLAG_VIDEO 0x00000010 +#define WINED3DPRESENTFLAG_NOAUTOROTATE 0x00000020 +#define WINED3DPRESENTFLAG_UNPRUNEDMODE 0x00000040 + typedef enum _WINED3DRESOURCETYPE { WINED3DRTYPE_SURFACE = 1, WINED3DRTYPE_VOLUME = 2, diff --git a/include/winhttp.h b/include/winhttp.h index e67d6c2a830..17fc38a8f02 100644 --- a/include/winhttp.h +++ b/include/winhttp.h @@ -36,6 +36,8 @@ typedef INTERNET_PORT *LPINTERNET_PORT; #define INTERNET_SCHEME_HTTPS 2 typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; +#define ICU_ESCAPE 0x80000000 + /* flags for WinHttpOpen */ #define WINHTTP_FLAG_ASYNC 0x10000000 diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index 3ee7370dbbe..9178d4efe6a 100644 --- a/programs/regedit/regproc.c +++ b/programs/regedit/regproc.c @@ -576,8 +576,10 @@ static void processRegEntry(WCHAR* stdInput, BOOL isUnicode) delete_registry_key(stdInput + 1); } else if ( openKeyW(stdInput) != ERROR_SUCCESS ) { + char* stdInputA = GetMultiByteString(stdInput); fprintf(stderr,"%s: setValue failed to open key %s\n", - getAppName(), stdInput); + getAppName(), stdInputA); + HeapFree(GetProcessHeap(), 0, stdInputA); } } else if( currentKeyHandle && (( stdInput[0] == '@') || /* reading a default @=data pair */ @@ -885,7 +887,7 @@ static void REGPROC_export_string(WCHAR **line_buf, DWORD *line_buf_size, DWORD DWORD i; DWORD extra = 0; - REGPROC_resize_char_buffer(line_buf, line_buf_size, len + 10); + REGPROC_resize_char_buffer(line_buf, line_buf_size, len + *line_size + 10); /* escaping characters */ for (i = 0; i < len; i++) { @@ -895,37 +897,36 @@ static void REGPROC_export_string(WCHAR **line_buf, DWORD *line_buf_size, DWORD { const WCHAR escape[] = {'\\','\\'}; + REGPROC_resize_char_buffer(line_buf, line_buf_size, len + *line_size + extra + 1); + memcpy(*line_buf + *line_size + i + extra - 1, escape, 2 * sizeof(WCHAR)); extra++; - REGPROC_resize_char_buffer(line_buf, line_buf_size, len + extra); - memcpy(*line_buf + *line_size - 1, escape, 2 * sizeof(WCHAR)); break; } - case '\"': + case '"': { const WCHAR escape[] = {'\\','"'}; + REGPROC_resize_char_buffer(line_buf, line_buf_size, len + *line_size + extra + 1); + memcpy(*line_buf + *line_size + i + extra - 1, escape, 2 * sizeof(WCHAR)); extra++; - REGPROC_resize_char_buffer(line_buf, line_buf_size, len + extra); - memcpy(*line_buf + *line_size - 1, escape, 2 * sizeof(WCHAR)); break; } case '\n': { - const WCHAR escape[] = {'\\','\n'}; + const WCHAR escape[] = {'\\','n'}; + REGPROC_resize_char_buffer(line_buf, line_buf_size, len + *line_size + extra + 1); + memcpy(*line_buf + *line_size + i + extra - 1, escape, 2 * sizeof(WCHAR)); extra++; - REGPROC_resize_char_buffer(line_buf, line_buf_size, len + extra); - memcpy(*line_buf + *line_size - 1, escape, 2 * sizeof(WCHAR)); break; } default: - memcpy(*line_buf + *line_size - 1, &c, sizeof(WCHAR)); + memcpy(*line_buf + *line_size + i + extra - 1, &c, sizeof(WCHAR)); break; } - *line_size += 1; } + *line_size += len + extra; *(*line_buf + *line_size - 1) = 0; - *line_size += extra; } /****************************************************************************** @@ -939,7 +940,7 @@ static void REGPROC_write_line(FILE *file, const WCHAR* str, BOOL unicode) } else { char* strA = GetMultiByteString(str); - fprintf(file, strA); + fputs(strA, file); HeapFree(GetProcessHeap(), 0, strA); } } @@ -1064,11 +1065,17 @@ static void export_hkey(FILE *file, HKEY key, } default: + { + char* key_nameA = GetMultiByteString(*reg_key_name_buf); + char* value_nameA = GetMultiByteString(*val_name_buf); fprintf(stderr,"%s: warning - unsupported registry format '%d', " "treat as binary\n", getAppName(), value_type); - fprintf(stderr,"key name: \"%s\"\n", *reg_key_name_buf); - fprintf(stderr,"value name:\"%s\"\n\n", *val_name_buf); + fprintf(stderr,"key name: \"%s\"\n", key_nameA); + fprintf(stderr,"value name:\"%s\"\n\n", value_nameA); + HeapFree(GetProcessHeap(), 0, key_nameA); + HeapFree(GetProcessHeap(), 0, value_nameA); + } /* falls through */ case REG_MULTI_SZ: /* falls through */ -- 2.11.4.GIT