From a924911af9611ff395ea2be36fc5031883434910 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Mon, 9 Mar 2009 20:13:14 +0100 Subject: [PATCH] push 8079c4124d1355f652d7dbd6f1862eb95d83e2de --- .gitignore | 8 - Make.rules.in | 14 +- Makefile.in | 1 + configure | 164 ++- configure.ac | 28 +- dlls/Makedll.rules.in | 6 +- dlls/Makefile.in | 14 +- dlls/advapi32/advapi32.spec | 2 +- dlls/advapi32/eventlog.c | 9 + dlls/advapi32/tests/security.c | 2 +- dlls/comcat/tests/comcat.c | 2 +- dlls/comctl32/status.c | 11 + dlls/comctl32/tests/listview.c | 7 +- dlls/comctl32/tests/monthcal.c | 5 +- dlls/comctl32/tests/rebar.c | 2 +- dlls/comctl32/tests/status.c | 30 +- dlls/comctl32/tests/toolbar.c | 2 +- dlls/comctl32/tests/tooltips.c | 13 +- dlls/comctl32/tests/treeview.c | 8 +- dlls/comctl32/treeview.c | 18 +- dlls/comdlg32/printdlg.c | 3 +- dlls/{d3dx9_36/tests => comm.drv16}/Makefile.in | 13 +- .../comm.drv.spec => comm.drv16/comm.drv16.spec} | 0 dlls/crypt32/tests/msg.c | 73 +- dlls/cryptui/main.c | 5 +- dlls/d3d10/d3d10_main.c | 2 + dlls/d3d10/d3d10_private.h | 17 + dlls/d3d10/effect.c | 267 +++- dlls/d3d10core/Makefile.in | 2 + dlls/d3d10core/d3d10core_private.h | 32 + dlls/d3d10core/device.c | 82 +- dlls/d3d10core/inputlayout.c | 118 ++ dlls/d3d10core/shader.c | 304 +++++ dlls/d3d8/d3d8_private.h | 2 +- dlls/d3d8/device.c | 52 +- dlls/d3d8/vertexbuffer.c | 22 +- dlls/d3d9/d3d9_private.h | 2 +- dlls/d3d9/device.c | 89 +- dlls/d3d9/tests/device.c | 7 +- dlls/d3d9/tests/query.c | 2 +- dlls/d3d9/tests/vertexdeclaration.c | 4 +- dlls/d3d9/tests/visual.c | 18 +- dlls/d3d9/vertexbuffer.c | 22 +- dlls/d3dx9_36/sprite.c | 39 +- dlls/d3dx9_36/tests/Makefile.in | 3 +- dlls/d3dx9_36/tests/core.c | 311 +++++ dlls/dbghelp/Makefile.in | 1 + dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/device.c | 236 +--- dlls/ddraw/direct3d.c | 2 +- dlls/ddraw/tests/dsurface.c | 3 +- dlls/ddraw/vertexbuffer.c | 24 +- dlls/ddraw/viewport.c | 47 +- dlls/dinput/keyboard.c | 16 +- dlls/dispdib.dll16/Makefile.in | 15 + dlls/{gdi32 => dispdib.dll16}/dispdib.c | 0 .../dispdib.dll16.spec} | 0 dlls/display.drv16/Makefile.in | 19 + dlls/{user32 => display.drv16}/display.c | 13 +- .../display.drv16.spec} | 8 +- .../{user32/resources => display.drv16}/display.rc | 4 +- dlls/display.drv16/oic_hand.ico | Bin 0 -> 766 bytes dlls/dmloader/container.c | 2 +- dlls/dmloader/loader.c | 6 +- dlls/dsound/buffer.c | 2 +- dlls/gdi32/Makefile.in | 2 - dlls/gdi32/tests/bitmap.c | 23 +- dlls/gdi32/tests/clipping.c | 19 +- dlls/gdiplus/gdiplus.spec | 2 +- dlls/gdiplus/image.c | 10 + dlls/gdiplus/tests/image.c | 14 +- dlls/gdiplus/tests/region.c | 6 +- dlls/iphlpapi/Makefile.in | 2 +- dlls/iphlpapi/iphlpapi_main.c | 92 -- dlls/iphlpapi/ipstats.c | 1344 ++++++++++---------- dlls/iphlpapi/ipstats.h | 20 - dlls/iphlpapi/tests/iphlpapi.c | 12 +- dlls/kernel32/Makefile.in | 11 +- dlls/kernel32/sync.c | 3 +- dlls/kernel32/tests/atom.c | 2 + dlls/kernel32/tests/console.c | 3 +- dlls/kernel32/tests/pipe.c | 112 ++ dlls/kernel32/win87em.spec | 4 - dlls/keyboard.drv16/Makefile.in | 15 + dlls/{user32/kbd16.c => keyboard.drv16/keyboard.c} | 39 +- .../keyboard.drv16.spec} | 6 +- dlls/mlang/mlang.c | 26 +- dlls/mouse.drv16/Makefile.in | 19 + dlls/{user32/mouse16.c => mouse.drv16/mouse.c} | 6 +- .../mouse.drv16.spec} | 6 +- dlls/{user32/resources => mouse.drv16}/mouse.rc | 0 dlls/msacm32/internal.c | 2 +- dlls/mscms/mscms_main.c | 20 + dlls/mscms/tests/profile.c | 11 +- dlls/msctf/msctf.c | 4 +- dlls/mshtml/dispex.c | 5 + dlls/mshtml/htmlcurstyle.c | 11 +- dlls/mshtml/htmlstyle.c | 143 ++- dlls/mshtml/htmlstyle.h | 7 + dlls/mshtml/mshtml_private.h | 5 + dlls/mshtml/tests/dom.c | 255 +++- dlls/msi/tests/package.c | 6 + dlls/msvcrt/scanf.h | 2 +- dlls/netapi32/access.c | 5 +- dlls/netapi32/nbt.c | 26 +- dlls/netapi32/netbios.c | 2 +- dlls/netapi32/tests/apibuf.c | 14 +- dlls/netapi32/wksta.c | 3 +- dlls/ntdll/serial.c | 2 +- dlls/ntdll/signal_i386.c | 10 +- dlls/ntdll/tests/port.c | 69 +- dlls/ole32/compobj.c | 1 + dlls/ole32/ole2.c | 5 +- dlls/ole32/tests/dragdrop.c | 3 - dlls/ole32/tests/propvariant.c | 150 ++- dlls/qmgr/qmgr.c | 7 + dlls/qmgr/service.c | 2 + dlls/qmgr/tests/job.c | 74 +- dlls/riched20/editor.c | 55 +- dlls/riched20/tests/editor.c | 6 +- dlls/riched20/txthost.c | 5 +- dlls/rsaenh/tests/rsaenh.c | 2 +- dlls/sane.ds/capability.c | 524 +++++++- dlls/sane.ds/ds_ctrl.c | 273 +--- dlls/sane.ds/ds_image.c | 226 ++-- dlls/sane.ds/options.c | 81 ++ dlls/sane.ds/sane_i.h | 8 + dlls/sane.ds/sane_main.c | 258 +--- dlls/sane.ds/ui.c | 8 +- dlls/setupapi/dialog.c | 45 + dlls/setupapi/stubs.c | 14 - dlls/setupapi/tests/parser.c | 8 +- dlls/shdocvw/tests/shdocvw.c | 1 + dlls/shell32/regsvr.c | 7 + dlls/shell32/tests/autocomplete.c | 18 +- dlls/shell32/tests/shlfolder.c | 38 +- dlls/shlwapi/tests/ordinal.c | 9 +- dlls/shlwapi/tests/path.c | 6 +- dlls/shlwapi/tests/shreg.c | 52 +- dlls/snmpapi/tests/util.c | 14 +- dlls/stress.dll16/Makefile.in | 15 + dlls/{kernel32 => stress.dll16}/stress.c | 0 .../stress.spec => stress.dll16/stress.dll16.spec} | 0 dlls/twain_32/README | 54 - dlls/twain_32/TWAIN | 172 --- dlls/twain_32/dsm_ctrl.c | 2 +- dlls/twain_32/tests/dsm.c | 216 +++- dlls/urlmon/Makefile.in | 1 + dlls/urlmon/ftp.c | 115 +- dlls/urlmon/gopher.c | 299 +++++ dlls/urlmon/tests/misc.c | 15 +- dlls/urlmon/tests/protocol.c | 275 +++- dlls/urlmon/tests/url.c | 29 +- dlls/urlmon/umon.c | 452 +------ dlls/urlmon/umstream.c | 336 ----- dlls/urlmon/urlmon_main.c | 4 + dlls/urlmon/urlmon_main.h | 14 +- dlls/user32/Makefile.in | 20 - dlls/user32/edit.c | 4 +- dlls/user32/menu.c | 50 +- dlls/user32/scroll.c | 3 + dlls/user32/tests/menu.c | 181 ++- dlls/user32/tests/msg.c | 57 +- dlls/user32/tests/scroll.c | 19 +- dlls/usp10/tests/usp10.c | 194 --- dlls/win87em.dll16/Makefile.in | 15 + dlls/{kernel32 => win87em.dll16}/win87em.c | 23 +- dlls/win87em.dll16/win87em.dll16.spec | 4 + dlls/windebug.dll16/Makefile.in | 15 + dlls/{kernel32 => windebug.dll16}/windebug.c | 0 .../windebug.dll16.spec} | 0 dlls/wined3d/arb_program_shader.c | 15 +- dlls/wined3d/ati_fragment_shader.c | 3 +- dlls/wined3d/buffer.c | 1125 +++++++--------- dlls/wined3d/context.c | 55 +- dlls/wined3d/device.c | 279 ++-- dlls/wined3d/directx.c | 1 + dlls/wined3d/drawprim.c | 143 +-- dlls/wined3d/glsl_shader.c | 78 +- dlls/wined3d/nvidia_texture_shader.c | 8 +- dlls/wined3d/state.c | 58 +- dlls/wined3d/stateblock.c | 34 +- dlls/wined3d/utils.c | 7 +- dlls/wined3d/wined3d_gl.h | 37 + dlls/wined3d/wined3d_private.h | 129 +- dlls/winedos/dosaspi.c | 2 +- dlls/winedos/int10.c | 2 +- dlls/winedos/int21.c | 23 +- dlls/winedos/int31.c | 10 +- dlls/winedos/int33.c | 2 +- dlls/winedos/interrupts.c | 4 +- dlls/winedos/module.c | 8 +- dlls/winedos/relay.c | 2 +- dlls/winedos/xms.c | 2 +- dlls/winhttp/net.c | 4 +- dlls/wininet/ftp.c | 4 +- dlls/wininet/http.c | 16 +- dlls/wininet/internet.c | 3 +- dlls/wininet/netconnection.c | 4 +- dlls/wininet/tests/http.c | 54 + dlls/wininet/tests/internet.c | 27 +- dlls/wininet/tests/url.c | 25 +- dlls/wininet/urlcache.c | 9 + dlls/wininet/wininet.spec | 2 +- include/config.h.in | 6 + include/d3dx9.h | 6 + include/d3dx9core.h | 4 +- include/d3dx9mesh.h | 4 +- include/d3dx9shader.h | 4 +- include/dbghelp.h | 50 + include/shlguid.h | 2 + include/wine/wined3d.idl | 70 +- include/winnt.h | 16 +- libs/port/interlocked.c | 2 +- libs/wine/mmap.c | 8 +- programs/Makeprog.rules.in | 2 +- programs/cmd/Cs.rc | 1 + programs/cmd/Da.rc | 1 + programs/cmd/De.rc | 1 + programs/cmd/En.rc | 1 + programs/cmd/Es.rc | 1 + programs/cmd/Fr.rc | 1 + programs/cmd/Ja.rc | 1 + programs/cmd/Ko.rc | 3 +- programs/cmd/Nl.rc | 1 + programs/cmd/No.rc | 1 + programs/cmd/Pl.rc | 1 + programs/cmd/Pt.rc | 1 + programs/cmd/Ru.rc | 1 + programs/cmd/Si.rc | 1 + programs/cmd/Tr.rc | 1 + programs/cmd/wcmd.h | 1 + programs/cmd/wcmdmain.c | 22 +- programs/expand/expand.c | 2 +- programs/regedit/framewnd.c | 2 +- programs/regedit/regproc.c | 28 +- programs/taskmgr/taskmgr.c | 6 +- programs/uninstaller/Makefile.in | 3 +- programs/uninstaller/main.c | 13 +- programs/winedbg/be_i386.c | 9 +- programs/winedbg/break.c | 2 +- programs/winedbg/types.c | 2 +- programs/winetest/main.c | 3 +- programs/winhlp32/winhelp.c | 40 +- server/async.c | 2 +- server/fd.c | 10 +- server/file.h | 3 +- server/named_pipe.c | 3 +- tools/fnt2bdf.c | 6 +- tools/widl/expr.c | 48 +- tools/widl/header.c | 64 +- tools/widl/header.h | 4 +- tools/widl/parser.l | 1 - tools/widl/parser.y | 349 ++--- tools/widl/proxy.c | 8 +- tools/widl/server.c | 5 +- tools/widl/typegen.c | 419 +++--- tools/widl/typegen.h | 3 +- tools/widl/typelib.c | 75 +- tools/widl/typetree.c | 181 ++- tools/widl/typetree.h | 55 +- tools/widl/widltypes.h | 122 +- tools/widl/write_msft.c | 31 +- tools/wine.inf.in | 4 +- tools/winebuild/build.h | 1 + tools/winebuild/import.c | 2 +- tools/winebuild/main.c | 21 +- tools/winebuild/parser.c | 10 + tools/winebuild/spec16.c | 6 + tools/winebuild/spec32.c | 3 +- tools/winedump/output.c | 2 +- tools/winedump/pdb.c | 4 +- 272 files changed, 7555 insertions(+), 5507 deletions(-) copy dlls/{d3dx9_36/tests => comm.drv16}/Makefile.in (50%) rename dlls/{kernel32/comm.drv.spec => comm.drv16/comm.drv16.spec} (100%) create mode 100644 dlls/d3d10core/inputlayout.c create mode 100644 dlls/d3d10core/shader.c create mode 100644 dlls/d3dx9_36/tests/core.c create mode 100644 dlls/dispdib.dll16/Makefile.in rename dlls/{gdi32 => dispdib.dll16}/dispdib.c (100%) rename dlls/{gdi32/dispdib.spec => dispdib.dll16/dispdib.dll16.spec} (100%) create mode 100644 dlls/display.drv16/Makefile.in rename dlls/{user32 => display.drv16}/display.c (87%) rename dlls/{user32/display.drv.spec => display.drv16/display.drv16.spec} (83%) rename dlls/{user32/resources => display.drv16}/display.rc (96%) create mode 100644 dlls/display.drv16/oic_hand.ico delete mode 100644 dlls/kernel32/win87em.spec create mode 100644 dlls/keyboard.drv16/Makefile.in rename dlls/{user32/kbd16.c => keyboard.drv16/keyboard.c} (84%) rename dlls/{user32/keyboard.drv.spec => keyboard.drv16/keyboard.drv16.spec} (86%) create mode 100644 dlls/mouse.drv16/Makefile.in rename dlls/{user32/mouse16.c => mouse.drv16/mouse.c} (94%) rename dlls/{user32/mouse.drv.spec => mouse.drv16/mouse.drv16.spec} (53%) rename dlls/{user32/resources => mouse.drv16}/mouse.rc (100%) create mode 100644 dlls/stress.dll16/Makefile.in rename dlls/{kernel32 => stress.dll16}/stress.c (100%) rename dlls/{kernel32/stress.spec => stress.dll16/stress.dll16.spec} (100%) delete mode 100644 dlls/twain_32/README delete mode 100644 dlls/twain_32/TWAIN create mode 100644 dlls/urlmon/gopher.c create mode 100644 dlls/win87em.dll16/Makefile.in rename dlls/{kernel32 => win87em.dll16}/win87em.c (90%) create mode 100644 dlls/win87em.dll16/win87em.dll16.spec create mode 100644 dlls/windebug.dll16/Makefile.in rename dlls/{kernel32 => windebug.dll16}/windebug.c (100%) rename dlls/{kernel32/windebug.spec => windebug.dll16/windebug.dll16.spec} (100%) diff --git a/.gitignore b/.gitignore index 868b7859bdf..4f084d3fa2f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,14 +26,11 @@ dlls/advapi32/svcctl.h dlls/advapi32/svcctl_c.c dlls/atl/atliface.h dlls/avifile.dll16 -dlls/comm.drv16 dlls/commdlg.dll16 dlls/compobj.dll16 dlls/ctl3d.dll16 dlls/ctl3dv2.dll16 dlls/ddeml.dll16 -dlls/dispdib.dll16 -dlls/display.drv16 dlls/gdi.exe16 dlls/imm.dll16 dlls/jscript/jsglobal.tlb @@ -44,14 +41,12 @@ dlls/kernel32/nls/winerr_enu.mc.rc dlls/kernel32/nls/winerr_fra.mc.rc dlls/kernel32/nls/winerr_kor.mc.rc dlls/kernel32/nls/winerr_nor.mc.rc -dlls/keyboard.drv16 dlls/krnl386.exe16 dlls/libd3dx9.def dlls/libwinspool.def dlls/libxinput.def dlls/lzexpand.dll16 dlls/mmsystem.dll16 -dlls/mouse.drv16 dlls/msacm.dll16 dlls/mshtml.tlb/mshtml_tlb.tlb dlls/mshtml/nsiface.h @@ -110,7 +105,6 @@ dlls/sound.drv16 dlls/stdole2.tlb/std_ole_v2.tlb dlls/stdole32.tlb/std_ole_v1.tlb dlls/storage.dll16 -dlls/stress.dll16 dlls/system.drv16 dlls/toolhelp.dll16 dlls/twain.dll16 @@ -119,9 +113,7 @@ dlls/user.exe16 dlls/ver.dll16 dlls/w32sys.dll16 dlls/win32s16.dll16 -dlls/win87em.dll16 dlls/winaspi.dll16 -dlls/windebug.dll16 dlls/wineps16.drv16 dlls/wing.dll16 dlls/winnls.dll16 diff --git a/Make.rules.in b/Make.rules.in index 3645603fcfe..5dc88840a74 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -271,10 +271,10 @@ $(SUBDIRS:%=%/__install-dev__): dummy $(SUBDIRS:%=%/__uninstall__): dummy @cd `dirname $@` && $(MAKE) uninstall -install:: $(INSTALLSUBDIRS:%=%/__install__) -install-lib:: $(INSTALLSUBDIRS:%=%/__install-lib__) -install-dev:: $(INSTALLSUBDIRS:%=%/__install-dev__) -uninstall:: $(INSTALLSUBDIRS:%=%/__uninstall__) +install:: $(INSTALLSUBDIRS:%=%/__install__) dummy +install-lib:: $(INSTALLSUBDIRS:%=%/__install-lib__) dummy +install-dev:: $(INSTALLSUBDIRS:%=%/__install-dev__) dummy +uninstall:: $(INSTALLSUBDIRS:%=%/__uninstall__) dummy $(INSTALLDIRS): $(MKINSTALLDIRS) $@ @@ -294,11 +294,11 @@ $(TESTSUBDIRS:%=%/__crosstest__): dummy $(TESTSUBDIRS:%=%/__testclean__): dummy @cd `dirname $@` && $(MAKE) testclean -check test:: $(TESTSUBDIRS:%=%/__test__) +check test:: $(TESTSUBDIRS:%=%/__test__) dummy -crosstest:: $(TESTSUBDIRS:%=%/__crosstest__) +crosstest:: $(TESTSUBDIRS:%=%/__crosstest__) dummy -testclean:: $(TESTSUBDIRS:%=%/__testclean__) +testclean:: $(TESTSUBDIRS:%=%/__testclean__) dummy .PHONY: check test testclean crosstest $(TESTSUBDIRS:%=%/__test__) $(TESTSUBDIRS:%=%/__crosstest__) $(TESTSUBDIRS:%=%/__testclean__) diff --git a/Makefile.in b/Makefile.in index 1dd8ef118fd..5d9039a3f56 100644 --- a/Makefile.in +++ b/Makefile.in @@ -150,6 +150,7 @@ Makefile $(ALL_MAKERULES) $(ALL_MAKEFILES): config.status @./config.status $@ .INIT: Makefile .BEGIN: Makefile +.MAKEFILEDEPS: $(RECURSE_TARGETS) $(MAKEDEP): $(ALL_MAKEFILES) diff --git a/configure b/configure index 2fcb441a67e..1df46796e0e 100755 --- a/configure +++ b/configure @@ -762,6 +762,7 @@ ALSALIBS AUDIOIOLIBS CUPSINCL FONTCONFIGINCL +LIBKSTAT EXTRACFLAGS BUILTINFLAG LDPATH @@ -3752,9 +3753,15 @@ if test "x$enable_win16" != "xyes" then WIN16_FILES="" WIN16_INSTALL="" + enable_comm_drv16=${enable_comm_drv16:-no} + enable_dispdib_dll16=${enable_dispdib_dll16:-no} + enable_display_drv16=${enable_display_drv16:-no} enable_ifsmgr_vxd=${enable_ifsmgr_vxd:-no} + enable_keyboard_drv16=${enable_keyboard_drv16:-no} enable_mmdevldr_vxd=${enable_mmdevldr_vxd:-no} enable_monodebg_vxd=${enable_monodebg_vxd:-no} + enable_mouse_drv16=${enable_mouse_drv16:-no} + enable_stress_dll16=${enable_stress_dll16:-no} enable_vdhcp_vxd=${enable_vdhcp_vxd:-no} enable_vmm_vxd=${enable_vmm_vxd:-no} enable_vnbt_vxd=${enable_vnbt_vxd:-no} @@ -3762,6 +3769,8 @@ then enable_vtdapi_vxd=${enable_vtdapi_vxd:-no} enable_vwin32_vxd=${enable_vwin32_vxd:-no} enable_w32skrnl=${enable_w32skrnl:-no} + enable_win87em_dll16=${enable_win87em_dll16:-no} + enable_windebug_dll16=${enable_windebug_dll16:-no} enable_winedos=${enable_winedos:-no} enable_winevdm=${enable_winevdm:-no} enable_winhelp_exe16=${enable_winhelp_exe16:-no} @@ -5938,6 +5947,7 @@ done + for ac_header in \ AudioUnit/AudioUnit.h \ Carbon/Carbon.h \ @@ -5963,6 +5973,7 @@ for ac_header in \ io.h \ jack/jack.h \ jpeglib.h \ + kstat.h \ lber.h \ lcms.h \ lcms/lcms.h \ @@ -16436,6 +16447,81 @@ esac fi +if test "$ac_cv_header_kstat_h" = "yes" +then + { echo "$as_me:$LINENO: checking for kstat_open in -lkstat" >&5 +echo $ECHO_N "checking for kstat_open in -lkstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_kstat_kstat_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $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 kstat_open (); +int +main () +{ +return kstat_open (); + ; + 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_lib_kstat_kstat_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kstat_kstat_open=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_kstat_open" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_kstat_open" >&6; } +if test $ac_cv_lib_kstat_kstat_open = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBKSTAT="-lkstat" + +fi + +fi + { echo "$as_me:$LINENO: checking for -lodbc" >&5 echo $ECHO_N "checking for -lodbc... $ECHO_C" >&6; } if test "${ac_cv_lib_soname_odbc+set}" = set; then @@ -22881,10 +22967,11 @@ DEPENDENCIES="### Dependencies: .INIT: Makefile .BEGIN: Makefile +.MAKEFILEDEPS: Makefile: dummy -\$(MAKEDEP) -C\$(SRCDIR) -S\$(TOPSRCDIR) -T\$(TOPOBJDIR) \$(EXTRAINCL) \$(DEPEND_SRCS) -\$(OBJS): \$(IDL_GEN_HEADERS) +\$(OBJS) \$(C_SRCS16:.c=.o): \$(IDL_GEN_HEADERS) \$(IDL_GEN_C_SRCS:.c=.o): \$(IDL_GEN_C_SRCS) \$(RC_SRCS:.rc=.res): \$(IDL_TLB_SRCS:.idl=.tlb) \$(LEX_SRCS:.l=.yy.o): \$(LEX_SRCS:.l=.yy.c) @@ -23215,6 +23302,14 @@ dlls/comdlg32/tests/Makefile: dlls/comdlg32/tests/Makefile.in dlls/Maketest.rule ac_config_files="$ac_config_files dlls/comdlg32/tests/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/comm.drv16/Makefile" +test "x$enable_comm_drv16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + comm.drv16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/comm.drv16/Makefile: dlls/comm.drv16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/comm.drv16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/compstui/Makefile" test "x$enable_compstui" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ compstui" @@ -23671,6 +23766,22 @@ dlls/dinput8/Makefile: dlls/dinput8/Makefile.in dlls/Makedll.rules" ac_config_files="$ac_config_files dlls/dinput8/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/dispdib.dll16/Makefile" +test "x$enable_dispdib_dll16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + dispdib.dll16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/dispdib.dll16/Makefile: dlls/dispdib.dll16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/dispdib.dll16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/display.drv16/Makefile" +test "x$enable_display_drv16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + display.drv16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/display.drv16/Makefile: dlls/display.drv16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/display.drv16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/dmband/Makefile" test "x$enable_dmband" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ dmband" @@ -24247,6 +24358,14 @@ dlls/kernel32/tests/Makefile: dlls/kernel32/tests/Makefile.in dlls/Maketest.rule ac_config_files="$ac_config_files dlls/kernel32/tests/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/keyboard.drv16/Makefile" +test "x$enable_keyboard_drv16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + keyboard.drv16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/keyboard.drv16/Makefile: dlls/keyboard.drv16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/keyboard.drv16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/loadperf/Makefile" test "x$enable_loadperf" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ loadperf" @@ -24407,6 +24526,14 @@ dlls/mountmgr.sys/Makefile: dlls/mountmgr.sys/Makefile.in dlls/Makedll.rules" ac_config_files="$ac_config_files dlls/mountmgr.sys/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/mouse.drv16/Makefile" +test "x$enable_mouse_drv16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + mouse.drv16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/mouse.drv16/Makefile: dlls/mouse.drv16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/mouse.drv16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/mpr/Makefile" test "x$enable_mpr" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ mpr" @@ -25487,6 +25614,14 @@ dlls/sti/Makefile: dlls/sti/Makefile.in dlls/Makedll.rules" ac_config_files="$ac_config_files dlls/sti/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/stress.dll16/Makefile" +test "x$enable_stress_dll16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + stress.dll16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/stress.dll16/Makefile: dlls/stress.dll16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/stress.dll16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/strmiids/Makefile" test "x$enable_strmiids" != xno && ALL_IMPLIB_DIRS="$ALL_IMPLIB_DIRS \\ strmiids" @@ -25735,6 +25870,22 @@ dlls/w32skrnl/Makefile: dlls/w32skrnl/Makefile.in dlls/Makedll.rules" ac_config_files="$ac_config_files dlls/w32skrnl/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/win87em.dll16/Makefile" +test "x$enable_win87em_dll16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + win87em.dll16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/win87em.dll16/Makefile: dlls/win87em.dll16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/win87em.dll16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/windebug.dll16/Makefile" +test "x$enable_windebug_dll16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + windebug.dll16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/windebug.dll16/Makefile: dlls/windebug.dll16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/windebug.dll16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/winealsa.drv/Makefile" test "x$enable_winealsa_drv" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ winealsa.drv" @@ -27297,6 +27448,7 @@ do "dlls/comctl32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/comctl32/tests/Makefile" ;; "dlls/comdlg32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/comdlg32/Makefile" ;; "dlls/comdlg32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/comdlg32/tests/Makefile" ;; + "dlls/comm.drv16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/comm.drv16/Makefile" ;; "dlls/compstui/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/compstui/Makefile" ;; "dlls/credui/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/credui/Makefile" ;; "dlls/credui/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/credui/tests/Makefile" ;; @@ -27354,6 +27506,8 @@ do "dlls/dinput/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dinput/Makefile" ;; "dlls/dinput/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dinput/tests/Makefile" ;; "dlls/dinput8/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dinput8/Makefile" ;; + "dlls/dispdib.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dispdib.dll16/Makefile" ;; + "dlls/display.drv16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/display.drv16/Makefile" ;; "dlls/dmband/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dmband/Makefile" ;; "dlls/dmcompos/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dmcompos/Makefile" ;; "dlls/dmime/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/dmime/Makefile" ;; @@ -27426,6 +27580,7 @@ do "dlls/jscript/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/jscript/tests/Makefile" ;; "dlls/kernel32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/kernel32/Makefile" ;; "dlls/kernel32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/kernel32/tests/Makefile" ;; + "dlls/keyboard.drv16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/keyboard.drv16/Makefile" ;; "dlls/loadperf/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/loadperf/Makefile" ;; "dlls/localspl/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/localspl/Makefile" ;; "dlls/localspl/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/localspl/tests/Makefile" ;; @@ -27446,6 +27601,7 @@ do "dlls/mmdevldr.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mmdevldr.vxd/Makefile" ;; "dlls/monodebg.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/monodebg.vxd/Makefile" ;; "dlls/mountmgr.sys/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mountmgr.sys/Makefile" ;; + "dlls/mouse.drv16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mouse.drv16/Makefile" ;; "dlls/mpr/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mpr/Makefile" ;; "dlls/mprapi/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mprapi/Makefile" ;; "dlls/msacm32.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/msacm32.drv/Makefile" ;; @@ -27581,6 +27737,7 @@ do "dlls/stdole2.tlb/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/stdole2.tlb/Makefile" ;; "dlls/stdole32.tlb/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/stdole32.tlb/Makefile" ;; "dlls/sti/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/sti/Makefile" ;; + "dlls/stress.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/stress.dll16/Makefile" ;; "dlls/strmiids/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/strmiids/Makefile" ;; "dlls/svrapi/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/svrapi/Makefile" ;; "dlls/sxs/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/sxs/Makefile" ;; @@ -27612,6 +27769,8 @@ do "dlls/vtdapi.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/vtdapi.vxd/Makefile" ;; "dlls/vwin32.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/vwin32.vxd/Makefile" ;; "dlls/w32skrnl/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/w32skrnl/Makefile" ;; + "dlls/win87em.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/win87em.dll16/Makefile" ;; + "dlls/windebug.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/windebug.dll16/Makefile" ;; "dlls/winealsa.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winealsa.drv/Makefile" ;; "dlls/wineaudioio.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/wineaudioio.drv/Makefile" ;; "dlls/winecoreaudio.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winecoreaudio.drv/Makefile" ;; @@ -27999,6 +28158,7 @@ ALSALIBS!$ALSALIBS$ac_delim AUDIOIOLIBS!$AUDIOIOLIBS$ac_delim CUPSINCL!$CUPSINCL$ac_delim FONTCONFIGINCL!$FONTCONFIGINCL$ac_delim +LIBKSTAT!$LIBKSTAT$ac_delim EXTRACFLAGS!$EXTRACFLAGS$ac_delim BUILTINFLAG!$BUILTINFLAG$ac_delim LDPATH!$LDPATH$ac_delim @@ -28025,7 +28185,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.ac b/configure.ac index b109694f301..8a11b04b9a0 100644 --- a/configure.ac +++ b/configure.ac @@ -139,9 +139,15 @@ if test "x$enable_win16" != "xyes" then WIN16_FILES="" WIN16_INSTALL="" + enable_comm_drv16=${enable_comm_drv16:-no} + enable_dispdib_dll16=${enable_dispdib_dll16:-no} + enable_display_drv16=${enable_display_drv16:-no} enable_ifsmgr_vxd=${enable_ifsmgr_vxd:-no} + enable_keyboard_drv16=${enable_keyboard_drv16:-no} enable_mmdevldr_vxd=${enable_mmdevldr_vxd:-no} enable_monodebg_vxd=${enable_monodebg_vxd:-no} + enable_mouse_drv16=${enable_mouse_drv16:-no} + enable_stress_dll16=${enable_stress_dll16:-no} enable_vdhcp_vxd=${enable_vdhcp_vxd:-no} enable_vmm_vxd=${enable_vmm_vxd:-no} enable_vnbt_vxd=${enable_vnbt_vxd:-no} @@ -149,6 +155,8 @@ then enable_vtdapi_vxd=${enable_vtdapi_vxd:-no} enable_vwin32_vxd=${enable_vwin32_vxd:-no} enable_w32skrnl=${enable_w32skrnl:-no} + enable_win87em_dll16=${enable_win87em_dll16:-no} + enable_windebug_dll16=${enable_windebug_dll16:-no} enable_winedos=${enable_winedos:-no} enable_winevdm=${enable_winevdm:-no} enable_winhelp_exe16=${enable_winhelp_exe16:-no} @@ -275,6 +283,7 @@ AC_CHECK_HEADERS(\ io.h \ jack/jack.h \ jpeglib.h \ + kstat.h \ lber.h \ lcms.h \ lcms/lcms.h \ @@ -1312,6 +1321,14 @@ fi WINE_WARNING_WITH(png,[test "x$ac_cv_lib_soname_png" = "x"], [libpng ${notice_platform}development files not found, PNG won't be supported.]) +dnl **** Check for libkstat **** +if test "$ac_cv_header_kstat_h" = "yes" +then + AC_CHECK_LIB(kstat,kstat_open, + [AC_DEFINE(HAVE_LIBKSTAT, 1, [Define to 1 if you have the `kstat' library (-lkstat).]) + AC_SUBST(LIBKSTAT,"-lkstat")]) +fi + dnl **** Check for libodbc **** WINE_CHECK_SONAME(odbc,SQLConnect,,[AC_DEFINE_UNQUOTED(SONAME_LIBODBC,["libodbc.$LIBEXT"])]) @@ -1854,10 +1871,11 @@ AC_SUBST(DEPENDENCIES,["### Dependencies: .INIT: Makefile .BEGIN: Makefile +.MAKEFILEDEPS: Makefile: dummy -\$(MAKEDEP) -C\$(SRCDIR) -S\$(TOPSRCDIR) -T\$(TOPOBJDIR) \$(EXTRAINCL) \$(DEPEND_SRCS) -\$(OBJS): \$(IDL_GEN_HEADERS) +\$(OBJS) \$(C_SRCS16:.c=.o): \$(IDL_GEN_HEADERS) \$(IDL_GEN_C_SRCS:.c=.o): \$(IDL_GEN_C_SRCS) \$(RC_SRCS:.rc=.res): \$(IDL_TLB_SRCS:.idl=.tlb) \$(LEX_SRCS:.l=.yy.o): \$(LEX_SRCS:.l=.yy.c) @@ -1923,6 +1941,7 @@ WINE_CONFIG_MAKEFILE([dlls/comctl32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_D WINE_CONFIG_MAKEFILE([dlls/comctl32/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) WINE_CONFIG_MAKEFILE([dlls/comdlg32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/comdlg32/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) +WINE_CONFIG_MAKEFILE([dlls/comm.drv16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/compstui/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/credui/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/credui/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) @@ -1980,6 +1999,8 @@ WINE_CONFIG_MAKEFILE([dlls/devenum/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DL WINE_CONFIG_MAKEFILE([dlls/dinput/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/dinput/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) WINE_CONFIG_MAKEFILE([dlls/dinput8/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/dispdib.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/display.drv16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/dmband/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/dmcompos/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/dmime/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) @@ -2052,6 +2073,7 @@ WINE_CONFIG_MAKEFILE([dlls/jscript/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DL WINE_CONFIG_MAKEFILE([dlls/jscript/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) WINE_CONFIG_MAKEFILE([dlls/kernel32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/kernel32/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) +WINE_CONFIG_MAKEFILE([dlls/keyboard.drv16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/loadperf/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/localspl/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/localspl/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) @@ -2072,6 +2094,7 @@ WINE_CONFIG_MAKEFILE([dlls/mlang/tests/Makefile],[dlls/Maketest.rules],[dlls],[A WINE_CONFIG_MAKEFILE([dlls/mmdevldr.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/monodebg.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/mountmgr.sys/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/mouse.drv16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/mpr/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/mprapi/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/msacm32.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) @@ -2207,6 +2230,7 @@ WINE_CONFIG_MAKEFILE([dlls/spoolss/tests/Makefile],[dlls/Maketest.rules],[dlls], WINE_CONFIG_MAKEFILE([dlls/stdole2.tlb/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/stdole32.tlb/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/sti/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/stress.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/strmiids/Makefile],[dlls/Makeimplib.rules],[dlls],[ALL_IMPLIB_DIRS]) WINE_CONFIG_MAKEFILE([dlls/svrapi/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/sxs/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) @@ -2238,6 +2262,8 @@ WINE_CONFIG_MAKEFILE([dlls/vnetbios.vxd/Makefile],[dlls/Makedll.rules],[dlls],[A WINE_CONFIG_MAKEFILE([dlls/vtdapi.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/vwin32.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/w32skrnl/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/win87em.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/windebug.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/winealsa.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/wineaudioio.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/winecoreaudio.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) diff --git a/dlls/Makedll.rules.in b/dlls/Makedll.rules.in index ca9e972abc9..76747b6c418 100644 --- a/dlls/Makedll.rules.in +++ b/dlls/Makedll.rules.in @@ -62,9 +62,9 @@ $(SUBDIRS): implib # Rules for testing -check test:: $(SUBDIRS:%=%/__test__) +check test:: $(SUBDIRS:%=%/__test__) dummy -crosstest:: $(SUBDIRS:%=%/__crosstest__) +crosstest:: $(SUBDIRS:%=%/__crosstest__) dummy # Rules for auto documentation @@ -97,7 +97,7 @@ $(IMPLIB_SRCS:%=_install_static_implib_/%): install_static_implib_$(IMPLIBEXT) install install-lib:: $(MODULE)$(DLLEXT) $(DESTDIR)$(dlldir) dummy $(INSTALL_PROGRAM) $(MODULE)$(DLLEXT) $(DESTDIR)$(dlldir)/$(MODULE)$(DLLEXT) -install install-dev:: $(IMPORTLIB:%=_install_/%) $(IMPLIB_SRCS:%=_install_static_implib_/%) +install install-dev:: $(IMPORTLIB:%=_install_/%) $(IMPLIB_SRCS:%=_install_static_implib_/%) dummy uninstall:: -cd $(DESTDIR)$(dlldir) && $(RM) $(MODULE)$(DLLEXT) $(IMPORTLIBFILE) $(STATICIMPLIB) diff --git a/dlls/Makefile.in b/dlls/Makefile.in index b35daf0efe7..84f9363e9a5 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -19,21 +19,16 @@ DOCSUBDIRS = $(DLLSUBDIRS) WIN16_FILES = \ avifile.dll16 \ - comm.drv16 \ commdlg.dll16 \ compobj.dll16 \ ctl3d.dll16 \ ctl3dv2.dll16 \ ddeml.dll16 \ - dispdib.dll16 \ - display.drv16 \ gdi.exe16 \ imm.dll16 \ - keyboard.drv16 \ krnl386.exe16 \ lzexpand.dll16 \ mmsystem.dll16 \ - mouse.drv16 \ msacm.dll16 \ msvideo.dll16 \ ole2.dll16 \ @@ -49,7 +44,6 @@ WIN16_FILES = \ shell.dll16 \ sound.drv16 \ storage.dll16 \ - stress.dll16 \ system.drv16 \ toolhelp.dll16 \ twain.dll16 \ @@ -58,9 +52,7 @@ WIN16_FILES = \ ver.dll16 \ w32sys.dll16 \ win32s16.dll16 \ - win87em.dll16 \ winaspi.dll16 \ - windebug.dll16 \ wineps16.drv16 \ wing.dll16 \ winnls.dll16 \ @@ -85,13 +77,13 @@ commdlg.dll16: ctl3d.dll16 ctl3dv2.dll16: echo "ctl3d32.dll" >$@ -dispdib.dll16 gdi.exe16 wing.dll16: +gdi.exe16 wing.dll16: echo "gdi32.dll" >$@ imm.dll16: echo "imm32.dll" >$@ -comm.drv16 krnl386.exe16 stress.dll16 system.drv16 toolhelp.dll16 win87em.dll16 windebug.dll16: +krnl386.exe16 system.drv16 toolhelp.dll16: echo "kernel32.dll" >$@ lzexpand.dll16: @@ -127,7 +119,7 @@ shell.dll16: twain.dll16: echo "twain_32.dll" >$@ -ddeml.dll16 display.drv16 keyboard.drv16 mouse.drv16 user.exe16: +ddeml.dll16 user.exe16: echo "user32.dll" >$@ ver.dll16: diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index bcb20479700..9d56c46d13d 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -635,7 +635,7 @@ @ stdcall SystemFunction036(ptr long) # RtlGenRandom @ stdcall SystemFunction040(ptr long long) # RtlEncryptMemory @ stdcall SystemFunction041(ptr long long) # RtlDecryptMemory -@ stub TraceEvent +@ stdcall TraceEvent(double ptr) @ stub TraceEventInstance @ stub TraceMessage @ stub TraceMessageVa diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c index d7f50a55941..15cf4d56e99 100644 --- a/dlls/advapi32/eventlog.c +++ b/dlls/advapi32/eventlog.c @@ -492,6 +492,15 @@ ULONG WINAPI RegisterTraceGuidsA( WMIDPREQUEST RequestAddress, } /****************************************************************************** + * TraceEvent [ADVAPI32.@] + */ +ULONG WINAPI TraceEvent( TRACEHANDLE SessionHandle, PEVENT_TRACE_HEADER EventTrace ) +{ + FIXME("%s %p\n", wine_dbgstr_longlong(SessionHandle), EventTrace); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +/****************************************************************************** * UnregisterTraceGuids [ADVAPI32.@] * * See RegisterTraceGuids diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 1d5a769993b..e82167a9752 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -1196,7 +1196,7 @@ static void test_token_attr(void) ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); if (ret) { - BYTE buf[1024]; + DWORD buf[256]; /* GetTokenInformation wants a dword-aligned buffer */ Size = sizeof(buf); ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size); ok(ret, "GetTokenInformation failed with error %d\n", GetLastError()); diff --git a/dlls/comcat/tests/comcat.c b/dlls/comcat/tests/comcat.c index 49e5afe7c41..029d2e30ab3 100644 --- a/dlls/comcat/tests/comcat.c +++ b/dlls/comcat/tests/comcat.c @@ -29,7 +29,7 @@ #include "wine/test.h" -#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x \n", hr) +#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) static BOOL register_testentry(void) { diff --git a/dlls/comctl32/status.c b/dlls/comctl32/status.c index a56c2a0bade..17ba1e9123e 100644 --- a/dlls/comctl32/status.c +++ b/dlls/comctl32/status.c @@ -762,6 +762,7 @@ STATUSBAR_SetTextT (STATUS_INFO *infoPtr, INT nPart, WORD style, part->text = (LPWSTR)text; } else { LPWSTR ntext; + WCHAR *idx; if (text && !isW) { LPCSTR atxt = (LPCSTR)text; @@ -775,6 +776,16 @@ STATUSBAR_SetTextT (STATUS_INFO *infoPtr, INT nPart, WORD style, strcpyW (ntext, text); } else ntext = 0; + /* replace nonprintable characters with spaces */ + if (ntext) { + idx = ntext; + while (*idx) { + if(!isprintW(*idx)) + *idx = ' '; + idx++; + } + } + /* check if text is unchanged -> no need to redraw */ if (text) { if (!changed && part->text && !lstrcmpW(ntext, part->text)) { diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 4033e9e683a..4562f2e871b 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -748,13 +748,16 @@ static HIMAGELIST test_create_imagelist; static LRESULT CALLBACK create_test_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + LRESULT ret; + if (uMsg == WM_CREATE) { LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; lpcs->style |= LVS_REPORT; - SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)test_create_imagelist); } - return CallWindowProc(listviewWndProc, hwnd, uMsg, wParam, lParam); + ret = CallWindowProc(listviewWndProc, hwnd, uMsg, wParam, lParam); + if (uMsg == WM_CREATE) SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)test_create_imagelist); + return ret; } static void test_create(void) diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c index cccb1b9ea0b..f116da52ec1 100644 --- a/dlls/comctl32/tests/monthcal.c +++ b/dlls/comctl32/tests/monthcal.c @@ -53,7 +53,8 @@ static const struct message create_parent_window_seq[] = { { WM_SHOWWINDOW, sent|wparam, 1 }, { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, { WM_QUERYNEWPALETTE, sent|optional }, - { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, 0 }, + { WM_WINDOWPOSCHANGED, sent|optional }, { WM_ACTIVATEAPP, sent|wparam, 1 }, { WM_NCACTIVATE, sent|wparam, 1 }, { WM_ACTIVATE, sent|wparam, 1 }, @@ -447,7 +448,7 @@ static HWND create_parent_window(void) assert(hwnd); /* check for message sequences */ - ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_window_seq, "create parent window", TRUE); + ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_window_seq, "create parent window", FALSE); return hwnd; } diff --git a/dlls/comctl32/tests/rebar.c b/dlls/comctl32/tests/rebar.c index 933d515ff01..d055d8aec8f 100644 --- a/dlls/comctl32/tests/rebar.c +++ b/dlls/comctl32/tests/rebar.c @@ -157,7 +157,7 @@ static void dump_sizes(HWND hRebar) printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom, rbi.fStyle, rbi.cx); } - printf("\n }, }, \n"); + printf("\n }, },\n"); } #define check_sizes() dump_sizes(hRebar); diff --git a/dlls/comctl32/tests/status.c b/dlls/comctl32/tests/status.c index 4ae663f9281..f1cbda47f0d 100644 --- a/dlls/comctl32/tests/status.c +++ b/dlls/comctl32/tests/status.c @@ -258,6 +258,8 @@ static void test_status_control(void) RECT rc; CHAR charArray[20]; HICON hIcon; + char ch; + char chstr[10] = "Inval id"; hWndStatus = create_status_control(WS_VISIBLE, 0); @@ -307,7 +309,7 @@ static void test_status_control(void) /* Test resetting text with different characters */ r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)"First@Again"); expect(TRUE,r); - r = SendMessage(hWndStatus, SB_SETTEXT, 1, (LPARAM)"InvalidChars\\7\7"); + r = SendMessage(hWndStatus, SB_SETTEXT, 1, (LPARAM)"Invalid\tChars\\7\7"); expect(TRUE,r); r = SendMessage(hWndStatus, SB_SETTEXT, 2, (LPARAM)"InvalidChars\\n\n"); expect(TRUE,r); @@ -318,20 +320,28 @@ static void test_status_control(void) expect(11,LOWORD(r)); expect(0,HIWORD(r)); r = SendMessage(hWndStatus, SB_GETTEXT, 1, (LPARAM) charArray); - todo_wine - { - ok(strcmp(charArray,"InvalidChars\\7 ") == 0, "Expected InvalidChars\\7 , got %s\n", charArray); - } - expect(15,LOWORD(r)); + ok(strcmp(charArray,"Invalid\tChars\\7 ") == 0, "Expected Invalid\tChars\\7 , got %s\n", charArray); + + expect(16,LOWORD(r)); expect(0,HIWORD(r)); r = SendMessage(hWndStatus, SB_GETTEXT, 2, (LPARAM) charArray); - todo_wine - { - ok(strcmp(charArray,"InvalidChars\\n ") == 0, "Expected InvalidChars\\n , got %s\n", charArray); - } + ok(strcmp(charArray,"InvalidChars\\n ") == 0, "Expected InvalidChars\\n , got %s\n", charArray); + expect(15,LOWORD(r)); expect(0,HIWORD(r)); + /* test more nonprintable chars */ + for(ch = 0x00; ch < 0x7F; ch++) { + chstr[5] = ch; + r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)chstr); + expect(TRUE,r); + r = SendMessage(hWndStatus, SB_GETTEXT, 0, (LPARAM)charArray); + /* substitution with single space */ + if (ch > 0x00 && ch < 0x20 && ch != '\t') + chstr[5] = ' '; + ok(strcmp(charArray, chstr) == 0, "Expected %s, got %s\n", chstr, charArray); + } + /* Set background color */ r = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, RGB(255,0,0)); ok(r == CLR_DEFAULT || diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c index 02601cf2d3a..0c560b17e75 100644 --- a/dlls/comctl32/tests/toolbar.c +++ b/dlls/comctl32/tests/toolbar.c @@ -592,7 +592,7 @@ static void dump_sizes(HWND hToolbar) SendMessageA(hToolbar, TB_GETITEMRECT, i, &r); printf("%s{%3d, %3d, %3d, %3d}, ", (i%3==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom); } - printf("\n }, }, \n"); + printf("\n }, },\n"); } #define check_sizes() dump_sizes(hToolbar); diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c index 4c708a094e4..2b4f43ffd1b 100644 --- a/dlls/comctl32/tests/tooltips.c +++ b/dlls/comctl32/tests/tooltips.c @@ -291,11 +291,14 @@ static void test_gettext(void) r = SendMessageW(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoW); ok(r, "Adding the tool to the tooltip failed\n"); - toolinfoW.hwnd = NULL; - toolinfoW.uId = 0x1234ABCD; - toolinfoW.lpszText = bufW; - SendMessageW(hwnd, TTM_GETTEXTW, 0, (LPARAM)&toolinfoW); - ok(toolinfoW.lpszText[0] == 0, "lpszText should be an empty string\n"); + if (0) /* crashes on NT4 */ + { + toolinfoW.hwnd = NULL; + toolinfoW.uId = 0x1234ABCD; + toolinfoW.lpszText = bufW; + SendMessageW(hwnd, TTM_GETTEXTW, 0, (LPARAM)&toolinfoW); + ok(toolinfoW.lpszText[0] == 0, "lpszText should be an empty string\n"); + } DestroyWindow(hwnd); } diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c index f93b4856f5d..9ef6a99c70d 100644 --- a/dlls/comctl32/tests/treeview.c +++ b/dlls/comctl32/tests/treeview.c @@ -427,11 +427,9 @@ static void TestGetSetBkColor(void) { COLORREF crColor = RGB(0,0,0); - todo_wine{ - /* If the value is -1, the control is using the system color for the background color. */ - crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); - ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor); - } + /* If the value is -1, the control is using the system color for the background color. */ + crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); + ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor); /* Test for black background */ SendMessage( hTree, TVM_SETBKCOLOR, 0, (LPARAM)RGB(0,0,0) ); diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index abc6fc7fa10..43ae7b67556 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -2306,11 +2306,13 @@ TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITE & (TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS)) > TVS_LINESATROOT); HBRUSH hbr, hbrOld; + COLORREF clrBk = infoPtr->clrBk == -1 ? GetSysColor(COLOR_WINDOW): + infoPtr->clrBk; if (!lar && item->iLevel == 0) return; - hbr = CreateSolidBrush(infoPtr->clrBk); + hbr = CreateSolidBrush(clrBk); hbrOld = SelectObject(hdc, hbr); centerx = (item->linesOffset + item->stateOffset) / 2; @@ -2423,8 +2425,8 @@ TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITE { Rectangle(hdc, centerx - 1, centery - plussize + 1, centerx + 2, centery + plussize); - SetPixel(hdc, centerx - 1, centery, infoPtr->clrBk); - SetPixel(hdc, centerx + 1, centery, infoPtr->clrBk); + SetPixel(hdc, centerx - 1, centery, clrBk); + SetPixel(hdc, centerx + 1, centery, clrBk); } } } @@ -2472,7 +2474,8 @@ TREEVIEW_DrawItem(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem } else { - nmcdhdr.clrTextBk = infoPtr->clrBk; + nmcdhdr.clrTextBk = infoPtr->clrBk == -1 ? GetSysColor(COLOR_WINDOW): + infoPtr->clrBk; if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (wineItem == infoPtr->hotItem)) nmcdhdr.clrText = comctl32_color.clrHighlight; else if (infoPtr->clrText == -1) @@ -2782,9 +2785,12 @@ TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr) static LRESULT TREEVIEW_EraseBackground(const TREEVIEW_INFO *infoPtr, HDC hDC) { - HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk); + HBRUSH hBrush; + COLORREF clrBk = infoPtr->clrBk == -1 ? GetSysColor(COLOR_WINDOW): + infoPtr->clrBk; RECT rect; + hBrush = CreateSolidBrush(clrBk); GetClientRect(infoPtr->hwnd, &rect); FillRect(hDC, &rect, hBrush); DeleteObject(hBrush); @@ -4937,7 +4943,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->scrollX = 0; - infoPtr->clrBk = GetSysColor(COLOR_WINDOW); + infoPtr->clrBk = -1; /* use system color */ infoPtr->clrText = -1; /* use system color */ infoPtr->clrLine = RGB(128, 128, 128); infoPtr->clrInsertMark = GetSysColor(COLOR_BTNTEXT); diff --git a/dlls/comdlg32/printdlg.c b/dlls/comdlg32/printdlg.c index 318c82b7a45..6726c6a9cba 100644 --- a/dlls/comdlg32/printdlg.c +++ b/dlls/comdlg32/printdlg.c @@ -3412,8 +3412,7 @@ PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) */ static LRESULT CALLBACK pagesetup_margin_editproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - switch(msg) - case WM_CHAR: + if (msg == WM_CHAR) { WCHAR decimal = get_decimal_sep(); WCHAR wc = (WCHAR)wparam; diff --git a/dlls/d3dx9_36/tests/Makefile.in b/dlls/comm.drv16/Makefile.in similarity index 50% copy from dlls/d3dx9_36/tests/Makefile.in copy to dlls/comm.drv16/Makefile.in index 40500e23d66..481b9332d37 100644 --- a/dlls/d3dx9_36/tests/Makefile.in +++ b/dlls/comm.drv16/Makefile.in @@ -1,14 +1,13 @@ TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../../.. +TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ -TESTDLL = d3dx9_36.dll -IMPORTS = d3dx9 kernel32 +MODULE = comm.drv16 +IMPORTS = kernel32 +EXTRADLLFLAGS = -Wb,--subsystem,win16 -CTESTS = \ - math.c \ - shader.c +SPEC_SRCS = comm.drv16.spec -@MAKE_TEST_RULES@ +@MAKE_DLL_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/kernel32/comm.drv.spec b/dlls/comm.drv16/comm.drv16.spec similarity index 100% rename from dlls/kernel32/comm.drv.spec rename to dlls/comm.drv16/comm.drv16.spec diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c index 42da890463f..5f74aeed354 100644 --- a/dlls/crypt32/tests/msg.c +++ b/dlls/crypt32/tests/msg.c @@ -1685,7 +1685,8 @@ static void test_signed_msg_encoding(void) detachedSignedContent, sizeof(detachedSignedContent)); SetLastError(0xdeadbeef); ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size); - ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, + ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX || + broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)), "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError()); check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER, signedEncodedSigner, sizeof(signedEncodedSigner)); @@ -1837,7 +1838,13 @@ static void test_signed_msg_get_param(void) /* Content and bare content are always gettable */ size = 0; ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); - ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n", + GetLastError()); + if (!ret) + { + skip("message parameters are broken, skipping tests\n"); + return; + } size = 0; ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); @@ -2193,7 +2200,8 @@ static void test_decode_msg_update(void) msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE); - ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), + "CryptMsgUpdate failed: %08x\n", GetLastError()); CryptMsgClose(msg); /* while with specified type it fails. */ msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, @@ -2201,8 +2209,9 @@ static void test_decode_msg_update(void) SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE); ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || - GetLastError() == OSS_PDU_MISMATCH /* Win9x */), - "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", + GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || + GetLastError() == OSS_DATA_ERROR /* some Win9x */), + "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", GetLastError()); CryptMsgClose(msg); /* On the other hand, decoding the bare content of an empty hash message @@ -2213,8 +2222,9 @@ static void test_decode_msg_update(void) ret = CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent), TRUE); ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || - GetLastError() == OSS_PDU_MISMATCH /* Win9x */), - "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", + GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || + GetLastError() == OSS_DATA_ERROR /* some Win9x */), + "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", GetLastError()); CryptMsgClose(msg); /* but succeeds with explicit type. */ @@ -2222,7 +2232,8 @@ static void test_decode_msg_update(void) NULL); ret = CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent), TRUE); - ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */), + "CryptMsgUpdate failed: %x\n", GetLastError()); CryptMsgClose(msg); /* And again, opening a (non-empty) hash message with unspecified type @@ -2239,8 +2250,9 @@ static void test_decode_msg_update(void) SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE); ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || - GetLastError() == OSS_PDU_MISMATCH /* Win9x */), - "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", + GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || + GetLastError() == OSS_DATA_ERROR /* some Win9x */), + "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", GetLastError()); CryptMsgClose(msg); /* and decoding the bare content of a non-empty hash message fails with @@ -2250,8 +2262,9 @@ static void test_decode_msg_update(void) SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE); ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || - GetLastError() == OSS_PDU_MISMATCH /* Win9x */), - "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", + GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || + GetLastError() == OSS_DATA_ERROR /* some Win9x */), + "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", GetLastError()); CryptMsgClose(msg); /* but succeeds with explicit type. */ @@ -2278,8 +2291,10 @@ static void test_decode_msg_update(void) SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent, sizeof(signedWithCertAndCrlBareContent), TRUE); - ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG, - "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); + ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || + GetLastError() == OSS_DATA_ERROR /* Win9x */), + "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", + GetLastError()); CryptMsgClose(msg); msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, NULL); @@ -2467,7 +2482,8 @@ static void test_decode_msg_get_param(void) ok(value == 1, "Expected 1 signer, got %d\n", value); size = 0; ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size); - ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), + "CryptMsgGetParam failed: %08x\n", GetLastError()); if (ret) buf = CryptMemAlloc(size); else @@ -2489,7 +2505,8 @@ static void test_decode_msg_get_param(void) /* Getting the CMS signer info of a PKCS7 message is possible. */ size = 0; ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size); - ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */), + "CryptMsgGetParam failed: %08x\n", GetLastError()); if (ret) buf = CryptMemAlloc(size); else @@ -3083,17 +3100,22 @@ static void test_msg_get_and_verify_signer(void) CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent, sizeof(signedWithCertWithValidPubKeyContent), TRUE); ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL); - ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), + "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); /* the signer index can be retrieved, .. */ signerIndex = 0xdeadbeef; ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex); - ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); - ok(signerIndex == 0, "expected 0, got %d\n", signerIndex); + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), + "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); + if (ret) + ok(signerIndex == 0, "expected 0, got %d\n", signerIndex); /* as can the signer cert. */ signer = (PCCERT_CONTEXT)0xdeadbeef; ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL); - ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); - ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef, + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), + "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); + if (ret) + ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef, "expected a valid signer\n"); if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef) CertFreeCertificateContext(signer); @@ -3111,7 +3133,8 @@ static void test_msg_get_and_verify_signer(void) SetLastError(0xdeadbeef); ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, + ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER || + broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)), "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes * the message signer not to be found. @@ -3121,7 +3144,8 @@ static void test_msg_get_and_verify_signer(void) SetLastError(0xdeadbeef); ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG, NULL, NULL); - ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, + ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER || + broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)), "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey), @@ -3134,7 +3158,8 @@ static void test_msg_get_and_verify_signer(void) SetLastError(0xdeadbeef); ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG, NULL, NULL); - ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); + ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), + "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); CertCloseStore(store, 0); CryptMsgClose(msg); } diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index af864088c76..ddbea8e299b 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -3236,8 +3236,7 @@ static WCHAR *get_cert_property_as_string(PCCERT_CONTEXT cert, DWORD prop) name = HeapAlloc(GetProcessHeap(), 0, cb); if (name) { - if (!CertGetCertificateContextProperty(cert, prop, (LPBYTE)name, - &cb)) + if (!CertGetCertificateContextProperty(cert, prop, name, &cb)) { HeapFree(GetProcessHeap(), 0, name); name = NULL; @@ -4460,7 +4459,7 @@ static BOOL is_ca_cert(PCCERT_CONTEXT cert, BOOL defaultIfNotSpecified) if (CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS, ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, - NULL, (LPBYTE)&info, &size)) + NULL, &info, &size)) { if (info->SubjectType.cbData == 1) isCA = info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG; diff --git a/dlls/d3d10/d3d10_main.c b/dlls/d3d10/d3d10_main.c index 88fd12bce8c..5746fbae79e 100644 --- a/dlls/d3d10/d3d10_main.c +++ b/dlls/d3d10/d3d10_main.c @@ -224,6 +224,8 @@ HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT fl object->vtbl = &d3d10_effect_vtbl; object->refcount = 1; + ID3D10Device_AddRef(device); + object->device = device; hr = d3d10_effect_parse(object, data, data_size); if (FAILED(hr)) diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index 956d5ae602c..1488b99d99a 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -40,8 +40,22 @@ enum d3d10_effect_variable_type struct d3d10_effect_variable { + struct d3d10_effect_pass *pass; enum d3d10_effect_variable_type type; DWORD idx_offset; + void *data; +}; + +struct d3d10_effect_shader_variable +{ + char *input_signature; + UINT input_signature_size; + union + { + ID3D10VertexShader *vs; + ID3D10PixelShader *ps; + ID3D10GeometryShader *gs; + } shader; }; /* ID3D10EffectPass */ @@ -49,6 +63,7 @@ struct d3d10_effect_pass { const struct ID3D10EffectPassVtbl *vtbl; + struct d3d10_effect_technique *technique; char *name; DWORD start; DWORD variable_count; @@ -60,6 +75,7 @@ struct d3d10_effect_technique { const struct ID3D10EffectTechniqueVtbl *vtbl; + struct d3d10_effect *effect; char *name; DWORD start; DWORD pass_count; @@ -73,6 +89,7 @@ struct d3d10_effect const struct ID3D10EffectVtbl *vtbl; LONG refcount; + ID3D10Device *device; DWORD technique_count; DWORD index_offset; DWORD blendstate_count; diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 61b4a6fc6ac..eecf511ba77 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -29,6 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10); ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) #define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') #define TAG_FX10 MAKE_TAG('F', 'X', '1', '0') +#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') static const struct ID3D10EffectTechniqueVtbl d3d10_effect_technique_vtbl; static const struct ID3D10EffectPassVtbl d3d10_effect_pass_vtbl; @@ -52,6 +53,18 @@ static inline void skip_dword_unknown(const char **ptr, unsigned int count) } } +static inline void write_dword(char **ptr, DWORD d) +{ + memcpy(*ptr, &d, sizeof(d)); + *ptr += sizeof(d); +} + +static inline void write_dword_unknown(char **ptr, DWORD d) +{ + FIXME("Writing unknown DWORD 0x%08x\n", d); + write_dword(ptr, d); +} + static inline void read_tag(const char **ptr, DWORD *t, char t_str[5]) { read_dword(ptr, t); @@ -60,7 +73,7 @@ static inline void read_tag(const char **ptr, DWORD *t, char t_str[5]) } static HRESULT parse_dxbc(const char *data, SIZE_T data_size, - HRESULT (*chunk_handler)(const char *data, void *ctx), void *ctx) + HRESULT (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) { const char *ptr = data; HRESULT hr = S_OK; @@ -92,12 +105,19 @@ static HRESULT parse_dxbc(const char *data, SIZE_T data_size, for (i = 0; i < chunk_count; ++i) { + DWORD chunk_tag, chunk_size; + const char *chunk_ptr; DWORD chunk_offset; read_dword(&ptr, &chunk_offset); TRACE("chunk %u at offset %#x\n", i, chunk_offset); - hr = chunk_handler(data + chunk_offset, ctx); + chunk_ptr = data + chunk_offset; + + read_dword(&chunk_ptr, &chunk_tag); + read_dword(&chunk_ptr, &chunk_size); + + hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx); if (FAILED(hr)) break; } @@ -125,13 +145,17 @@ static HRESULT parse_fx10_pass_index(struct d3d10_effect_pass *p, const char **p for (i = 0; i < p->variable_count; ++i) { - read_dword(ptr, &p->variables[i].type); - TRACE("Variable %u is of type %#x\n", i, p->variables[i].type); + struct d3d10_effect_variable *v = &p->variables[i]; + + v->pass = p; + + read_dword(ptr, &v->type); + TRACE("Variable %u is of type %#x\n", i, v->type); skip_dword_unknown(ptr, 2); - read_dword(ptr, &p->variables[i].idx_offset); - TRACE("Variable %u idx is at offset %#x\n", i, p->variables[i].idx_offset); + read_dword(ptr, &v->idx_offset); + TRACE("Variable %u idx is at offset %#x\n", i, v->idx_offset); } return S_OK; @@ -162,6 +186,7 @@ static HRESULT parse_fx10_technique_index(struct d3d10_effect_technique *t, cons struct d3d10_effect_pass *p = &t->passes[i]; p->vtbl = &d3d10_effect_pass_vtbl; + p->technique = t; hr = parse_fx10_pass_index(p, ptr); if (FAILED(hr)) break; @@ -170,21 +195,62 @@ static HRESULT parse_fx10_technique_index(struct d3d10_effect_technique *t, cons return hr; } -static HRESULT shader_chunk_handler(const char *data, void *ctx) +static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) { - const char *ptr = data; - DWORD chunk_size; + struct d3d10_effect_shader_variable *s = ctx; char tag_str[5]; - DWORD tag; - read_tag(&ptr, &tag, tag_str); + memcpy(tag_str, &tag, 4); + tag_str[4] = '\0'; TRACE("tag: %s\n", tag_str); - read_dword(&ptr, &chunk_size); - TRACE("chunk size: %#x\n", chunk_size); + TRACE("chunk size: %#x\n", data_size); switch(tag) { + case TAG_ISGN: + { + /* 32 (DXBC header) + 1 * 4 (chunk index) + 2 * 4 (chunk header) + data_size (chunk data) */ + UINT size = 44 + data_size; + char *ptr; + + s->input_signature = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (!s->input_signature) + { + ERR("Failed to allocate input signature data\n"); + return E_OUTOFMEMORY; + } + s->input_signature_size = size; + + ptr = s->input_signature; + + write_dword(&ptr, TAG_DXBC); + + /* signature(?) */ + write_dword_unknown(&ptr, 0); + write_dword_unknown(&ptr, 0); + write_dword_unknown(&ptr, 0); + write_dword_unknown(&ptr, 0); + + /* seems to be always 1 */ + write_dword_unknown(&ptr, 1); + + /* DXBC size */ + write_dword(&ptr, size); + + /* chunk count */ + write_dword(&ptr, 1); + + /* chunk index */ + write_dword(&ptr, (ptr - s->input_signature) + 4); + + /* chunk */ + write_dword(&ptr, TAG_ISGN); + write_dword(&ptr, data_size); + memcpy(ptr, data, data_size); + break; + } + default: FIXME("Unhandled chunk %s\n", tag_str); break; @@ -195,13 +261,44 @@ static HRESULT shader_chunk_handler(const char *data, void *ctx) static HRESULT parse_shader(struct d3d10_effect_variable *v, const char *data) { + ID3D10Device *device = v->pass->technique->effect->device; + struct d3d10_effect_shader_variable *s; const char *ptr = data; DWORD dxbc_size; + HRESULT hr; + + v->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct d3d10_effect_shader_variable)); + if (!v->data) + { + ERR("Failed to allocate shader variable memory\n"); + return E_OUTOFMEMORY; + } + + if (!ptr) return S_OK; + + s = v->data; read_dword(&ptr, &dxbc_size); TRACE("dxbc size: %#x\n", dxbc_size); - return parse_dxbc(ptr, dxbc_size, shader_chunk_handler, v); + switch (v->type) + { + case D3D10_EVT_VERTEXSHADER: + hr = ID3D10Device_CreateVertexShader(device, ptr, dxbc_size, &s->shader.vs); + if (FAILED(hr)) return hr; + break; + + case D3D10_EVT_PIXELSHADER: + hr = ID3D10Device_CreatePixelShader(device, ptr, dxbc_size, &s->shader.ps); + if (FAILED(hr)) return hr; + break; + case D3D10_EVT_GEOMETRYSHADER: + hr = ID3D10Device_CreateGeometryShader(device, ptr, dxbc_size, &s->shader.gs); + if (FAILED(hr)) return hr; + break; + } + + return parse_dxbc(ptr, dxbc_size, shader_chunk_handler, s); } static HRESULT parse_fx10_variable(struct d3d10_effect_variable *v, const char *data) @@ -219,10 +316,13 @@ static HRESULT parse_fx10_variable(struct d3d10_effect_variable *v, const char * if (offset == 1) { WARN("Skipping variable\n"); - return S_OK; + ptr = NULL; + } + else + { + ptr = data + offset; } - ptr = data + offset; switch (v->type) { case D3D10_EVT_VERTEXSHADER: @@ -331,6 +431,7 @@ static HRESULT parse_fx10_body(struct d3d10_effect *e, const char *data, DWORD d struct d3d10_effect_technique *t = &e->techniques[i]; t->vtbl = &d3d10_effect_technique_vtbl; + t->effect = e; hr = parse_fx10_technique_index(t, &ptr); if (FAILED(hr)) break; @@ -393,32 +494,26 @@ static HRESULT parse_fx10(struct d3d10_effect *e, const char *data, DWORD data_s return parse_fx10_body(e, ptr, data_size - (ptr - data)); } -static HRESULT fx10_chunk_handler(const char *data, void *ctx) +static HRESULT fx10_chunk_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) { struct d3d10_effect *e = ctx; - const char *ptr = data; - DWORD chunk_size; char tag_str[5]; - DWORD tag; - read_tag(&ptr, &tag, tag_str); + memcpy(tag_str, &tag, 4); + tag_str[4] = '\0'; TRACE("tag: %s\n", tag_str); - read_dword(&ptr, &chunk_size); - TRACE("chunk size: %#x\n", chunk_size); + TRACE("chunk size: %#x\n", data_size); switch(tag) { case TAG_FX10: - parse_fx10(e, ptr, chunk_size); - break; + return parse_fx10(e, data, data_size); default: FIXME("Unhandled chunk %s\n", tag_str); - break; + return S_OK; } - - return S_OK; } HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T data_size) @@ -426,14 +521,70 @@ HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T d return parse_dxbc(data, data_size, fx10_chunk_handler, This); } +static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v) +{ + TRACE("variable %p\n", v); + + switch(v->type) + { + case D3D10_EVT_VERTEXSHADER: + case D3D10_EVT_PIXELSHADER: + case D3D10_EVT_GEOMETRYSHADER: + HeapFree(GetProcessHeap(), 0, ((struct d3d10_effect_shader_variable *)v->data)->input_signature); + break; + + default: + break; + } + HeapFree(GetProcessHeap(), 0, v->data); +} + +static HRESULT d3d10_effect_variable_apply(struct d3d10_effect_variable *v) +{ + ID3D10Device *device = v->pass->technique->effect->device; + + TRACE("variable %p, type %#x\n", v, v->type); + + switch(v->type) + { + case D3D10_EVT_VERTEXSHADER: + ID3D10Device_VSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.vs); + return S_OK; + + case D3D10_EVT_PIXELSHADER: + ID3D10Device_PSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.ps); + return S_OK; + + case D3D10_EVT_GEOMETRYSHADER: + ID3D10Device_GSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.gs); + return S_OK; + + default: + FIXME("Unhandled variable type %#x\n", v->type); + return E_FAIL; + } +} + static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p) { + TRACE("pass %p\n", p); + HeapFree(GetProcessHeap(), 0, p->name); - HeapFree(GetProcessHeap(), 0, p->variables); + if (p->variables) + { + unsigned int i; + for (i = 0; i < p->variable_count; ++i) + { + d3d10_effect_variable_destroy(&p->variables[i]); + } + HeapFree(GetProcessHeap(), 0, p->variables); + } } static void d3d10_effect_technique_destroy(struct d3d10_effect_technique *t) { + TRACE("technique %p\n", t); + HeapFree(GetProcessHeap(), 0, t->name); if (t->passes) { @@ -494,6 +645,7 @@ static ULONG STDMETHODCALLTYPE d3d10_effect_Release(ID3D10Effect *iface) } HeapFree(GetProcessHeap(), 0, This->techniques); } + ID3D10Device_Release(This->device); HeapFree(GetProcessHeap(), 0, This); } @@ -518,9 +670,14 @@ static BOOL STDMETHODCALLTYPE d3d10_effect_IsPool(ID3D10Effect *iface) static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDevice(ID3D10Effect *iface, ID3D10Device **device) { - FIXME("iface %p, device %p stub!\n", iface, device); + struct d3d10_effect *This = (struct d3d10_effect *)iface; - return E_NOTIMPL; + TRACE("iface %p, device %p\n", iface, device); + + ID3D10Device_AddRef(This->device); + *device = This->device; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d10_effect_GetDesc(ID3D10Effect *iface, D3D10_EFFECT_DESC *desc) @@ -658,9 +815,16 @@ static BOOL STDMETHODCALLTYPE d3d10_effect_technique_IsValid(ID3D10EffectTechniq static HRESULT STDMETHODCALLTYPE d3d10_effect_technique_GetDesc(ID3D10EffectTechnique *iface, D3D10_TECHNIQUE_DESC *desc) { - FIXME("iface %p, desc %p stub!\n", iface, desc); + struct d3d10_effect_technique *This = (struct d3d10_effect_technique *)iface; - return E_NOTIMPL; + TRACE("iface %p, desc %p\n", iface, desc); + + desc->Name = This->name; + desc->Passes = This->pass_count; + WARN("Annotations not implemented\n"); + desc->Annotations = 0; + + return S_OK; } static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_technique_GetAnnotationByIndex( @@ -752,9 +916,26 @@ static BOOL STDMETHODCALLTYPE d3d10_effect_pass_IsValid(ID3D10EffectPass *iface) static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *iface, D3D10_PASS_DESC *desc) { - FIXME("iface %p, desc %p stub!\n", iface, desc); + struct d3d10_effect_pass *This = (struct d3d10_effect_pass *)iface; + unsigned int i; - return E_NOTIMPL; + FIXME("iface %p, desc %p partial stub!\n", iface, desc); + + memset(desc, 0, sizeof(*desc)); + desc->Name = This->name; + for (i = 0; i < This->variable_count; ++i) + { + struct d3d10_effect_variable *v = &This->variables[i]; + if (v->type == D3D10_EVT_VERTEXSHADER) + { + struct d3d10_effect_shader_variable *s = v->data; + desc->pIAInputSignature = (BYTE *)s->input_signature; + desc->IAInputSignatureSize = s->input_signature_size; + break; + } + } + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetVertexShaderDesc(ID3D10EffectPass *iface, @@ -799,9 +980,21 @@ static struct ID3D10EffectVariable * STDMETHODCALLTYPE d3d10_effect_pass_GetAnno static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface, UINT flags) { - FIXME("iface %p, flags %#x stub!\n", iface, flags); + struct d3d10_effect_pass *This = (struct d3d10_effect_pass *)iface; + HRESULT hr = S_OK; + unsigned int i; - return E_NOTIMPL; + TRACE("iface %p, flags %#x\n", iface, flags); + + if (flags) FIXME("Ignoring flags (%#x)\n", flags); + + for (i = 0; i < This->variable_count; ++i) + { + hr = d3d10_effect_variable_apply(&This->variables[i]); + if (FAILED(hr)) break; + } + + return hr; } static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_ComputeStateBlockMask(ID3D10EffectPass *iface, diff --git a/dlls/d3d10core/Makefile.in b/dlls/d3d10core/Makefile.in index 80f0def5d03..e94d44237af 100644 --- a/dlls/d3d10core/Makefile.in +++ b/dlls/d3d10core/Makefile.in @@ -10,6 +10,8 @@ C_SRCS = \ buffer.c \ d3d10core_main.c \ device.c \ + inputlayout.c \ + shader.c \ texture2d.c \ utils.c \ view.c diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index a05f773edf3..97038219175 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -89,6 +89,38 @@ struct d3d10_rendertarget_view D3D10_RENDER_TARGET_VIEW_DESC desc; }; +/* ID3D10InputLayout */ +extern const struct ID3D10InputLayoutVtbl d3d10_input_layout_vtbl; +struct d3d10_input_layout +{ + const struct ID3D10InputLayoutVtbl *vtbl; + LONG refcount; +}; + +/* ID3D10VertexShader */ +extern const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl; +struct d3d10_vertex_shader +{ + const struct ID3D10VertexShaderVtbl *vtbl; + LONG refcount; +}; + +/* ID3D10GeometryShader */ +extern const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl; +struct d3d10_geometry_shader +{ + const struct ID3D10GeometryShaderVtbl *vtbl; + LONG refcount; +}; + +/* ID3D10PixelShader */ +extern const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl; +struct d3d10_pixel_shader +{ + const struct ID3D10PixelShaderVtbl *vtbl; + LONG refcount; +}; + /* Layered device */ enum dxgi_device_layer_id { diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 4f0fb31070d..1406c38ddf6 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -146,8 +146,12 @@ static void STDMETHODCALLTYPE d3d10_device_DrawIndexed(ID3D10Device *iface, static void STDMETHODCALLTYPE d3d10_device_Draw(ID3D10Device *iface, UINT vertex_count, UINT start_vertex_location) { - FIXME("iface %p, vertex_count %u, start_vertex_location %u stub!\n", + struct d3d10_device *This = (struct d3d10_device *)iface; + + TRACE("iface %p, vertex_count %u, start_vertex_location %u\n", iface, vertex_count, start_vertex_location); + + IWineD3DDevice_DrawPrimitive(This->wined3d_device, start_vertex_location, vertex_count); } static void STDMETHODCALLTYPE d3d10_device_PSSetConstantBuffers(ID3D10Device *iface, @@ -210,7 +214,11 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetShader(ID3D10Device *iface, ID3D static void STDMETHODCALLTYPE d3d10_device_IASetPrimitiveTopology(ID3D10Device *iface, D3D10_PRIMITIVE_TOPOLOGY topology) { - FIXME("iface %p, topology %s stub!\n", iface, debug_d3d10_primitive_topology(topology)); + struct d3d10_device *This = (struct d3d10_device *)iface; + + TRACE("iface %p, topology %s\n", iface, debug_d3d10_primitive_topology(topology)); + + IWineD3DDevice_SetPrimitiveType(This->wined3d_device, (WINED3DPRIMITIVETYPE)topology); } static void STDMETHODCALLTYPE d3d10_device_VSSetShaderResources(ID3D10Device *iface, @@ -424,7 +432,11 @@ static void STDMETHODCALLTYPE d3d10_device_GSGetShader(ID3D10Device *iface, ID3D static void STDMETHODCALLTYPE d3d10_device_IAGetPrimitiveTopology(ID3D10Device *iface, D3D10_PRIMITIVE_TOPOLOGY *topology) { - FIXME("iface %p, topology %p stub!\n", iface, topology); + struct d3d10_device *This = (struct d3d10_device *)iface; + + TRACE("iface %p, topology %p\n", iface, topology); + + IWineD3DDevice_GetPrimitiveType(This->wined3d_device, (WINED3DPRIMITIVETYPE *)topology); } static void STDMETHODCALLTYPE d3d10_device_VSGetShaderResources(ID3D10Device *iface, @@ -894,30 +906,72 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateInputLayout(ID3D10Device *if const D3D10_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, ID3D10InputLayout **input_layout) { + struct d3d10_input_layout *object; + FIXME("iface %p, element_descs %p, element_count %u, shader_byte_code %p," "\tshader_byte_code_length %lu, input_layout %p stub!\n", iface, element_descs, element_count, shader_byte_code, shader_byte_code_length, input_layout); - return E_NOTIMPL; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate D3D10 input layout object memory\n"); + return E_OUTOFMEMORY; + } + + object->vtbl = &d3d10_input_layout_vtbl; + object->refcount = 1; + + *input_layout = (ID3D10InputLayout *)object; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d10_device_CreateVertexShader(ID3D10Device *iface, const void *byte_code, SIZE_T byte_code_length, ID3D10VertexShader **shader) { + struct d3d10_vertex_shader *object; + FIXME("iface %p, byte_code %p, byte_code_length %lu, shader %p stub!\n", iface, byte_code, byte_code_length, shader); - return E_NOTIMPL; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate D3D10 vertex shader object memory\n"); + return E_OUTOFMEMORY; + } + + object->vtbl = &d3d10_vertex_shader_vtbl; + object->refcount = 1; + + *shader = (ID3D10VertexShader *)object; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShader(ID3D10Device *iface, const void *byte_code, SIZE_T byte_code_length, ID3D10GeometryShader **shader) { + struct d3d10_geometry_shader *object; + FIXME("iface %p, byte_code %p, byte_code_length %lu, shader %p stub!\n", iface, byte_code, byte_code_length, shader); - return E_NOTIMPL; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate D3D10 geometry shader object memory\n"); + return E_OUTOFMEMORY; + } + + object->vtbl = &d3d10_geometry_shader_vtbl; + object->refcount = 1; + + *shader = (ID3D10GeometryShader *)object; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShaderWithStreamOutput(ID3D10Device *iface, @@ -935,10 +989,24 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShaderWithStreamOutp static HRESULT STDMETHODCALLTYPE d3d10_device_CreatePixelShader(ID3D10Device *iface, const void *byte_code, SIZE_T byte_code_length, ID3D10PixelShader **shader) { + struct d3d10_pixel_shader *object; + FIXME("iface %p, byte_code %p, byte_code_length %lu, shader %p stub!\n", iface, byte_code, byte_code_length, shader); - return E_NOTIMPL; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate D3D10 pixel shader object memory\n"); + return E_OUTOFMEMORY; + } + + object->vtbl = &d3d10_pixel_shader_vtbl; + object->refcount = 1; + + *shader = (ID3D10PixelShader *)object; + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBlendState(ID3D10Device *iface, diff --git a/dlls/d3d10core/inputlayout.c b/dlls/d3d10core/inputlayout.c new file mode 100644 index 00000000000..034a642d199 --- /dev/null +++ b/dlls/d3d10core/inputlayout.c @@ -0,0 +1,118 @@ +/* + * Copyright 2009 Henri Verbeet 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 "wine/port.h" + +#include "d3d10core_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_QueryInterface(ID3D10InputLayout *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D10InputLayout) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_input_layout_AddRef(ID3D10InputLayout *iface) +{ + struct d3d10_input_layout *This = (struct d3d10_input_layout *)iface; + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_input_layout_Release(ID3D10InputLayout *iface) +{ + struct d3d10_input_layout *This = (struct d3d10_input_layout *)iface; + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_input_layout_GetDevice(ID3D10InputLayout *iface, ID3D10Device **device) +{ + FIXME("iface %p, device %p stub!\n", iface, device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_GetPrivateData(ID3D10InputLayout *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_SetPrivateData(ID3D10InputLayout *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_input_layout_SetPrivateDataInterface(ID3D10InputLayout *iface, + REFGUID guid, const IUnknown *data) +{ + FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data); + + return E_NOTIMPL; +} + +const struct ID3D10InputLayoutVtbl d3d10_input_layout_vtbl = +{ + /* IUnknown methods */ + d3d10_input_layout_QueryInterface, + d3d10_input_layout_AddRef, + d3d10_input_layout_Release, + /* ID3D10DeviceChild methods */ + d3d10_input_layout_GetDevice, + d3d10_input_layout_GetPrivateData, + d3d10_input_layout_SetPrivateData, + d3d10_input_layout_SetPrivateDataInterface, +}; diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c new file mode 100644 index 00000000000..b614779bec1 --- /dev/null +++ b/dlls/d3d10core/shader.c @@ -0,0 +1,304 @@ +/* + * Copyright 2009 Henri Verbeet 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 "wine/port.h" + +#include "d3d10core_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d10core); + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D10VertexShader) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface) +{ + struct d3d10_vertex_shader *This = (struct d3d10_vertex_shader *)iface; + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface) +{ + struct d3d10_vertex_shader *This = (struct d3d10_vertex_shader *)iface; + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device) +{ + FIXME("iface %p, device %p stub!\n", iface, device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface, + REFGUID guid, const IUnknown *data) +{ + FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data); + + return E_NOTIMPL; +} + +const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl = +{ + /* IUnknown methods */ + d3d10_vertex_shader_QueryInterface, + d3d10_vertex_shader_AddRef, + d3d10_vertex_shader_Release, + /* ID3D10DeviceChild methods */ + d3d10_vertex_shader_GetDevice, + d3d10_vertex_shader_GetPrivateData, + d3d10_vertex_shader_SetPrivateData, + d3d10_vertex_shader_SetPrivateDataInterface, +}; + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D10GeometryShader) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface) +{ + struct d3d10_geometry_shader *This = (struct d3d10_geometry_shader *)iface; + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface) +{ + struct d3d10_geometry_shader *This = (struct d3d10_geometry_shader *)iface; + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device) +{ + FIXME("iface %p, device %p stub!\n", iface, device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface, + REFGUID guid, const IUnknown *data) +{ + FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data); + + return E_NOTIMPL; +} + +const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl = +{ + /* IUnknown methods */ + d3d10_geometry_shader_QueryInterface, + d3d10_geometry_shader_AddRef, + d3d10_geometry_shader_Release, + /* ID3D10DeviceChild methods */ + d3d10_geometry_shader_GetDevice, + d3d10_geometry_shader_GetPrivateData, + d3d10_geometry_shader_SetPrivateData, + d3d10_geometry_shader_SetPrivateDataInterface, +}; + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D10PixelShader) + || IsEqualGUID(riid, &IID_ID3D10DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface) +{ + struct d3d10_pixel_shader *This = (struct d3d10_pixel_shader *)iface; + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface) +{ + struct d3d10_pixel_shader *This = (struct d3d10_pixel_shader *)iface; + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* ID3D10DeviceChild methods */ + +static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device) +{ + FIXME("iface %p, device %p stub!\n", iface, device); +} + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", + iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface, + REFGUID guid, const IUnknown *data) +{ + FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data); + + return E_NOTIMPL; +} + +const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl = +{ + /* IUnknown methods */ + d3d10_pixel_shader_QueryInterface, + d3d10_pixel_shader_AddRef, + d3d10_pixel_shader_Release, + /* ID3D10DeviceChild methods */ + d3d10_pixel_shader_GetDevice, + d3d10_pixel_shader_GetPrivateData, + d3d10_pixel_shader_SetPrivateData, + d3d10_pixel_shader_SetPrivateDataInterface, +}; diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 70926906efc..9878a1fed18 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -320,7 +320,7 @@ struct IDirect3DVertexBuffer8Impl LONG ref; /* IDirect3DResource8 fields */ - IWineD3DVertexBuffer *wineD3DVertexBuffer; + IWineD3DBuffer *wineD3DVertexBuffer; /* Parent reference */ LPDIRECT3DDEVICE8 parentDevice; diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 643cdbce300..33edbe82c28 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -136,6 +136,32 @@ WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format) } } +static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count) +{ + switch(primitive_type) + { + case D3DPT_POINTLIST: + return primitive_count; + + case D3DPT_LINELIST: + return primitive_count * 2; + + case D3DPT_LINESTRIP: + return primitive_count + 1; + + case D3DPT_TRIANGLELIST: + return primitive_count * 3; + + case D3DPT_TRIANGLESTRIP: + case D3DPT_TRIANGLEFAN: + return primitive_count + 2; + + default: + FIXME("Unhandled primitive type %#x\n", primitive_type); + return 0; + } +} + /* Shader handle functions */ static shader_handle *alloc_shader_handle(IDirect3DDevice8Impl *This) { if (This->free_shader_handles) { @@ -1512,7 +1538,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex, + vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount)); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -1524,7 +1552,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices, + startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount)); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -1535,7 +1565,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 ifa TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, + vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), + pVertexStreamZeroData, VertexStreamZeroStride); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -1549,9 +1582,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, - NumVertexIndices, PrimitiveCount, pIndexData, wined3dformat_from_d3dformat(IndexDataFormat), - pVertexStreamZeroData, VertexStreamZeroStride); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices, + vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData, + wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -2228,7 +2262,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 ifa static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IWineD3DVertexBuffer *retStream = NULL; + IWineD3DBuffer *retStream = NULL; HRESULT rc = D3D_OK; TRACE("(%p) Relay\n" , This); @@ -2240,8 +2274,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 ifa EnterCriticalSection(&d3d8_cs); rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, 0 /* Offset in bytes */, pStride); if (rc == D3D_OK && NULL != retStream) { - IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream); - IWineD3DVertexBuffer_Release(retStream); + IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream); + IWineD3DBuffer_Release(retStream); }else{ if (rc != D3D_OK){ FIXME("Call to GetStreamSource failed %p\n", pStride); diff --git a/dlls/d3d8/vertexbuffer.c b/dlls/d3d8/vertexbuffer.c index 113218157ff..c26f00dd6ec 100644 --- a/dlls/d3d8/vertexbuffer.c +++ b/dlls/d3d8/vertexbuffer.c @@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 i if (ref == 0) { EnterCriticalSection(&d3d8_cs); - IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer); + IWineD3DBuffer_Release(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d8_cs); IUnknown_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); @@ -85,7 +85,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEX TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags); + hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -96,7 +96,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEX TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData); + hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -107,7 +107,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid); + hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -118,7 +118,7 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - ret = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew); + ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew); LeaveCriticalSection(&d3d8_cs); return ret; } @@ -129,7 +129,7 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - ret = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer); + ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d8_cs); return ret; } @@ -139,7 +139,7 @@ static void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 if TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer); + IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d8_cs); } @@ -149,7 +149,7 @@ static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - type = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer); + type = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d8_cs); return type; } @@ -161,7 +161,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 if TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags); + hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -172,7 +172,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer); + hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -183,7 +183,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc); LeaveCriticalSection(&d3d8_cs); if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format); diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index c1ea36b7306..2a4b10d8003 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -345,7 +345,7 @@ typedef struct IDirect3DVertexBuffer9Impl LONG ref; /* IDirect3DResource9 fields */ - IWineD3DVertexBuffer *wineD3DVertexBuffer; + IWineD3DBuffer *wineD3DVertexBuffer; /* Parent reference */ LPDIRECT3DDEVICE9EX parentDevice; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index d551ff6122e..8a3325ffc86 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -155,6 +155,32 @@ WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format) } } +static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count) +{ + switch(primitive_type) + { + case D3DPT_POINTLIST: + return primitive_count; + + case D3DPT_LINELIST: + return primitive_count * 2; + + case D3DPT_LINESTRIP: + return primitive_count + 1; + + case D3DPT_TRIANGLELIST: + return primitive_count * 3; + + case D3DPT_TRIANGLESTRIP: + case D3DPT_TRIANGLEFAN: + return primitive_count + 2; + + default: + FIXME("Unhandled primitive type %#x\n", primitive_type); + return 0; + } +} + /* IDirect3D IUnknown parts follow: */ static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(LPDIRECT3DDEVICE9EX iface, REFIID riid, LPVOID* ppobj) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; @@ -444,7 +470,7 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data break; case WINED3DRTYPE_VERTEXBUFFER: - IWineD3DVertexBuffer_GetDesc((IWineD3DVertexBuffer *) resource, &vertex_desc); + IWineD3DBuffer_GetDesc((IWineD3DBuffer *)resource, &vertex_desc); pool = vertex_desc.Pool; break; @@ -1357,7 +1383,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(LPDIRECT3DDEVICE9EX ifa TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex, + vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount)); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -1371,7 +1399,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVI /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */ EnterCriticalSection(&d3d9_cs); IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex); - hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices, + startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount)); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -1382,7 +1412,10 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9EX TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, + vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), + pVertexStreamZeroData, VertexStreamZeroStride); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -1395,9 +1428,10 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDE TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, - NumVertexIndices, PrimitiveCount, pIndexData, wined3dformat_from_d3dformat(IndexDataFormat), - pVertexStreamZeroData, VertexStreamZeroStride); + IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices, + vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData, + wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -1473,26 +1507,31 @@ static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; - HRESULT hr = S_OK; + IDirect3DVertexDeclaration9 *decl; + HRESULT hr; + TRACE("(%p) Relay\n" , This); - EnterCriticalSection(&d3d9_cs); - if (0 != FVF) { - IDirect3DVertexDeclaration9* pDecl = getConvertedDecl(This, FVF); + if (!FVF) + { + WARN("%#x is not a valid FVF\n", FVF); + return D3D_OK; + } - if(!pDecl) { - /* Any situation when this should happen, except out of memory? */ - ERR("Failed to create a converted vertex declaration\n"); - LeaveCriticalSection(&d3d9_cs); - return D3DERR_DRIVERINTERNALERROR; - } + EnterCriticalSection(&d3d9_cs); - hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, pDecl); - if (hr != S_OK) { - LeaveCriticalSection(&d3d9_cs); - return hr; - } + decl = getConvertedDecl(This, FVF); + if (!decl) + { + /* Any situation when this should happen, except out of memory? */ + ERR("Failed to create a converted vertex declaration\n"); + LeaveCriticalSection(&d3d9_cs); + return D3DERR_DRIVERINTERNALERROR; } + + hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl); + if (FAILED(hr)) ERR("Failed to set vertex declaration\n"); + LeaveCriticalSection(&d3d9_cs); return hr; @@ -1542,7 +1581,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX i static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; - IWineD3DVertexBuffer *retStream = NULL; + IWineD3DBuffer *retStream = NULL; HRESULT rc = D3D_OK; TRACE("(%p) Relay\n" , This); @@ -1554,8 +1593,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX i EnterCriticalSection(&d3d9_cs); rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride); if (rc == D3D_OK && NULL != retStream) { - IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream); - IWineD3DVertexBuffer_Release(retStream); + IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream); + IWineD3DBuffer_Release(retStream); }else{ if (rc != D3D_OK){ FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 702b77671a6..4b09316acfc 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -79,11 +79,8 @@ static int get_refcount(IUnknown *object) if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \ } -static void check_mipmap_levels( - IDirect3DDevice9* device, - int width, int height, int count) +static void check_mipmap_levels(IDirect3DDevice9 *device, UINT width, UINT height, UINT count) { - IDirect3DBaseTexture9* texture = NULL; HRESULT hr = IDirect3DDevice9_CreateTexture( device, width, height, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DTexture9**) &texture, NULL ); @@ -2049,7 +2046,7 @@ static void test_display_formats(void) static void test_scissor_size(void) { IDirect3D9 *d3d9_ptr = 0; - int i; + unsigned int i; static const struct { int winx; int winy; int backx; int backy; BOOL window; } scts[] = { /* scissor tests */ diff --git a/dlls/d3d9/tests/query.c b/dlls/d3d9/tests/query.c index c4e7874d1b7..51a86686395 100644 --- a/dlls/d3d9/tests/query.c +++ b/dlls/d3d9/tests/query.c @@ -83,7 +83,7 @@ static void test_query_support(IDirect3D9 *pD3d, HWND hwnd) IDirect3DDevice9 *pDevice = NULL; D3DPRESENT_PARAMETERS d3dpp; D3DDISPLAYMODE d3ddm; - int i; + unsigned int i; IDirect3DQuery9 *pQuery = NULL; BOOL supported; diff --git a/dlls/d3d9/tests/vertexdeclaration.c b/dlls/d3d9/tests/vertexdeclaration.c index 4207cbeecd6..bf10459cc66 100644 --- a/dlls/d3d9/tests/vertexdeclaration.c +++ b/dlls/d3d9/tests/vertexdeclaration.c @@ -750,7 +750,7 @@ static void test_vertex_declaration_alignment( HRESULT hr; IDirect3DVertexDeclaration9* result_decl = NULL; - int i; + unsigned int i; CONST D3DVERTEXELEMENT9 test_elements[5][3] = { @@ -796,7 +796,7 @@ static void test_unused_type( HRESULT hr; IDirect3DVertexDeclaration9* result_decl = NULL; - int i; + unsigned int i; static const D3DVERTEXELEMENT9 test_elements[][3] = { diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 4cb34970680..3564de3aad1 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -8578,23 +8578,23 @@ static void pointsize_test(IDirect3DDevice9 *device) /* ptsize = 16, ptsize_max = 1 --> point has size 1 */ color = getPixelColor(device, 448-4, 64-4); - ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); + ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color); color = getPixelColor(device, 448+4, 64+4); - ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); + ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color); /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */ color = getPixelColor(device, 512-4, 64-4); - ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); + ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color); color = getPixelColor(device, 512+4, 64+4); - ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); + ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color); /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16 * Don't be overly picky - just show that the point is bigger than 1 pixel */ color = getPixelColor(device, 576-4, 64-4); - ok(color == 0x00ffffff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); + ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); color = getPixelColor(device, 576+4, 64+4); - ok(color == 0x00ffffff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); + ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig))); ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr); @@ -8878,7 +8878,7 @@ static void pixelshader_blending_test(IDirect3DDevice9 *device) b0 >= max(b1, 1) - 1 && b0 <= b1 + 1, "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending); } else { - /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS. + /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS. * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */ color = getPixelColor(device, 320, 240); @@ -9101,11 +9101,11 @@ static void stream_test(IDirect3DDevice9 *device) hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0)); ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr); hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind); - ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr); + ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr); hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0)); ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr); hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind); - ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr); + ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr); /* set the default value back */ hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1); diff --git a/dlls/d3d9/vertexbuffer.c b/dlls/d3d9/vertexbuffer.c index b58001b947c..a831336e00e 100644 --- a/dlls/d3d9/vertexbuffer.c +++ b/dlls/d3d9/vertexbuffer.c @@ -59,7 +59,7 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 i if (ref == 0) { EnterCriticalSection(&d3d9_cs); - IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer); + IWineD3DBuffer_Release(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d9_cs); IDirect3DDevice9Ex_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); @@ -82,7 +82,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDevice(LPDIRECT3DVERTEXBUFFE static HRESULT WINAPI IDirect3DVertexBuffer9Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface; TRACE("(%p) Relay\n", This); - return IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags); + return IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags); } static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { @@ -91,7 +91,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEX TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData); + hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -102,7 +102,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_FreePrivateData(LPDIRECT3DVERTE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid); + hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -113,7 +113,7 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_SetPriority(LPDIRECT3DVERTEXBUFFE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew); + hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -124,7 +124,7 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_GetPriority(LPDIRECT3DVERTEXBUFFE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer); + hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -134,7 +134,7 @@ static void WINAPI IDirect3DVertexBuffer9Impl_PreLoad(LPDIRECT3DVERTEXBUFFER9 if TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer); + IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d9_cs); return ; } @@ -145,7 +145,7 @@ static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTE TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - ret = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer); + ret = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d9_cs); return ret; } @@ -157,7 +157,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Lock(LPDIRECT3DVERTEXBUFFER9 if TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags); + hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -168,7 +168,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer); + hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -179,7 +179,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc); LeaveCriticalSection(&d3d9_cs); if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format); diff --git a/dlls/d3dx9_36/sprite.c b/dlls/d3dx9_36/sprite.c index 36995088125..41767d84256 100644 --- a/dlls/d3dx9_36/sprite.c +++ b/dlls/d3dx9_36/sprite.c @@ -410,15 +410,39 @@ static HRESULT WINAPI ID3DXSpriteImpl_End(LPD3DXSPRITE iface) static HRESULT WINAPI ID3DXSpriteImpl_OnLostDevice(LPD3DXSPRITE iface) { ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; - FIXME("(%p): stub\n", This); - return E_NOTIMPL; + TRACE("(%p)\n", This); + + if(This->stateblock) IDirect3DStateBlock9_Release(This->stateblock); + if(This->vdecl) IDirect3DVertexDeclaration9_Release(This->vdecl); + This->vdecl=NULL; + This->stateblock=NULL; + + /* Reset some variables */ + ID3DXSprite_OnResetDevice(iface); + + return D3D_OK; } static HRESULT WINAPI ID3DXSpriteImpl_OnResetDevice(LPD3DXSPRITE iface) { ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; - FIXME("(%p): stub\n", This); - return E_NOTIMPL; + int i; + + TRACE("(%p)\n", This); + + for(i=0;isprite_count;i++) + if(This->sprites[i].texture) + IDirect3DTexture9_Release(This->sprites[i].texture); + + This->sprite_count=0; + + This->flags=0; + This->ready=FALSE; + + /* keep matrices */ + /* device objects get restored on Begin */ + + return D3D_OK; } static const ID3DXSpriteVtbl D3DXSprite_Vtbl = @@ -465,18 +489,15 @@ HRESULT WINAPI D3DXCreateSprite(LPDIRECT3DDEVICE9 device, LPD3DXSPRITE *sprite) D3DXMatrixIdentity(&object->transform); D3DXMatrixIdentity(&object->view); - object->flags=0; - object->ready=FALSE; - IDirect3DDevice9_GetDeviceCaps(device, &caps); object->texfilter_caps=caps.TextureFilterCaps; object->maxanisotropy=caps.MaxAnisotropy; object->alphacmp_caps=caps.AlphaCmpCaps; + ID3DXSprite_OnResetDevice((ID3DXSprite*)object); + object->sprites=NULL; - object->sprite_count=0; object->allocated_sprites=0; - *sprite=(ID3DXSprite*)object; return D3D_OK; diff --git a/dlls/d3dx9_36/tests/Makefile.in b/dlls/d3dx9_36/tests/Makefile.in index 40500e23d66..1ac8b7ecebc 100644 --- a/dlls/d3dx9_36/tests/Makefile.in +++ b/dlls/d3dx9_36/tests/Makefile.in @@ -3,9 +3,10 @@ TOPOBJDIR = ../../.. SRCDIR = @srcdir@ VPATH = @srcdir@ TESTDLL = d3dx9_36.dll -IMPORTS = d3dx9 kernel32 +IMPORTS = d3dx9 d3d9 user32 kernel32 CTESTS = \ + core.c \ math.c \ shader.c diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c new file mode 100644 index 00000000000..99ca08a0226 --- /dev/null +++ b/dlls/d3dx9_36/tests/core.c @@ -0,0 +1,311 @@ +/* + * Tests for the D3DX9 core interfaces + * + * Copyright 2009 Tony Wasserka + * + * 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 + */ + +#define COBJMACROS +#include "wine/test.h" +#include +#include "d3dx9core.h" + +static inline int get_ref(IUnknown *obj) +{ + IUnknown_AddRef(obj); + return IUnknown_Release(obj); +} + +static inline void check_ref(IUnknown *obj, int exp) +{ + int ref = get_ref(obj); + ok (exp == ref, "Invalid refcount. Expected %d, got %d\n", exp, ref); +} + +static inline void check_release(IUnknown *obj, int exp) +{ + int ref = IUnknown_Release(obj); + ok (ref == exp, "Invalid refcount. Expected %d, got %d\n", exp, ref); +} + +#define admitted_error 0.0001f +static inline void check_mat(D3DXMATRIX got, D3DXMATRIX exp) +{ + int i, j, equal=1; + for (i=0; i<4; i++) + for (j=0; j<4; j++) + if (fabs(U(exp).m[i][j]-U(got).m[i][j]) > admitted_error) + equal=0; + + ok(equal, "Got matrix\n\t(%f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f)\n" + "Expected matrix=\n\t(%f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f)\n", + U(got).m[0][0],U(got).m[0][1],U(got).m[0][2],U(got).m[0][3], + U(got).m[1][0],U(got).m[1][1],U(got).m[1][2],U(got).m[1][3], + U(got).m[2][0],U(got).m[2][1],U(got).m[2][2],U(got).m[2][3], + U(got).m[3][0],U(got).m[3][1],U(got).m[3][2],U(got).m[3][3], + U(exp).m[0][0],U(exp).m[0][1],U(exp).m[0][2],U(exp).m[0][3], + U(exp).m[1][0],U(exp).m[1][1],U(exp).m[1][2],U(exp).m[1][3], + U(exp).m[2][0],U(exp).m[2][1],U(exp).m[2][2],U(exp).m[2][3], + U(exp).m[3][0],U(exp).m[3][1],U(exp).m[3][2],U(exp).m[3][3]); +} + +static void test_ID3DXSprite(IDirect3DDevice9 *device) +{ + ID3DXSprite *sprite; + IDirect3D9 *d3d; + IDirect3DDevice9 *cmpdev; + IDirect3DTexture9 *tex1, *tex2; + D3DXMATRIX mat, cmpmat; + D3DVIEWPORT9 vp; + RECT rect; + D3DXVECTOR3 pos, center; + HRESULT hr; + + IDirect3DDevice9_GetDirect3D(device, &d3d); + hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_UNKNOWN, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8); + IDirect3D9_Release(d3d); + ok (hr == D3D_OK, "D3DFMT_A8R8G8B8 not supported\n"); + if (FAILED(hr)) return; + + hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL); + ok (hr == D3D_OK, "Failed to create first texture (error code: %#x)\n", hr); + if (FAILED(hr)) return; + + hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL); + ok (hr == D3D_OK, "Failed to create second texture (error code: %#x)\n", hr); + if (FAILED(hr)) { + IDirect3DTexture9_Release(tex1); + return; + } + + /* Test D3DXCreateSprite */ + hr = D3DXCreateSprite(device, NULL); + ok (hr == D3DERR_INVALIDCALL, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = D3DXCreateSprite(NULL, &sprite); + ok (hr == D3DERR_INVALIDCALL, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = D3DXCreateSprite(device, &sprite); + ok (hr == D3D_OK, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3D_OK); + + + /* Test ID3DXSprite_GetDevice */ + hr = ID3DXSprite_GetDevice(sprite, NULL); + ok (hr == D3DERR_INVALIDCALL, "GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = ID3DXSprite_GetDevice(sprite, &cmpdev); /* cmpdev == NULL */ + ok (hr == D3D_OK, "GetDevice returned %#x, expected %#x\n", hr, D3D_OK); + + hr = ID3DXSprite_GetDevice(sprite, &cmpdev); /* cmpdev != NULL */ + ok (hr == D3D_OK, "GetDevice returned %#x, expected %#x\n", hr, D3D_OK); + + IDirect3DDevice9_Release(device); + IDirect3DDevice9_Release(device); + + + /* Test ID3DXSprite_GetTransform */ + hr = ID3DXSprite_GetTransform(sprite, NULL); + ok (hr == D3DERR_INVALIDCALL, "GetTransform returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + hr = ID3DXSprite_GetTransform(sprite, &mat); + ok (hr == D3D_OK, "GetTransform returned %#x, expected %#x\n", hr, D3D_OK); + if(SUCCEEDED(hr)) { + D3DXMATRIX identity; + D3DXMatrixIdentity(&identity); + check_mat(mat, identity); + } + + /* Test ID3DXSprite_SetTransform */ + /* Set a transform and test if it gets returned correctly */ + U(mat).m[0][0]=2.1f; U(mat).m[0][1]=6.5f; U(mat).m[0][2]=-9.6f; U(mat).m[0][3]=1.7f; + U(mat).m[1][0]=4.2f; U(mat).m[1][1]=-2.5f; U(mat).m[1][2]=2.1f; U(mat).m[1][3]=5.5f; + U(mat).m[2][0]=-2.6f; U(mat).m[2][1]=0.3f; U(mat).m[2][2]=8.6f; U(mat).m[2][3]=8.4f; + U(mat).m[3][0]=6.7f; U(mat).m[3][1]=-5.1f; U(mat).m[3][2]=6.1f; U(mat).m[3][3]=2.2f; + + hr = ID3DXSprite_SetTransform(sprite, NULL); + ok (hr == D3DERR_INVALIDCALL, "SetTransform returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = ID3DXSprite_SetTransform(sprite, &mat); + ok (hr == D3D_OK, "SetTransform returned %#x, expected %#x\n", hr, D3D_OK); + if(SUCCEEDED(hr)) { + hr=ID3DXSprite_GetTransform(sprite, &cmpmat); + if(SUCCEEDED(hr)) check_mat(cmpmat, mat); + else skip("GetTransform returned %#x\n", hr); + } + + /* Test ID3DXSprite_SetWorldViewLH/RH */ + todo_wine { + hr = ID3DXSprite_SetWorldViewLH(sprite, &mat, &mat); + ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_SetWorldViewLH(sprite, NULL, &mat); + ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_SetWorldViewLH(sprite, &mat, NULL); + ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_SetWorldViewLH(sprite, NULL, NULL); + ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); + + hr = ID3DXSprite_SetWorldViewRH(sprite, &mat, &mat); + ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_SetWorldViewRH(sprite, NULL, &mat); + ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_SetWorldViewRH(sprite, &mat, NULL); + ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_SetWorldViewRH(sprite, NULL, NULL); + ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); + } + IDirect3DDevice9_BeginScene(device); + + /* Test ID3DXSprite_Begin*/ + hr = ID3DXSprite_Begin(sprite, 0); + ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); + + IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &mat); + D3DXMatrixIdentity(&cmpmat); + check_mat(mat, cmpmat); + + IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &mat); + check_mat(mat, cmpmat); + + IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &mat); + IDirect3DDevice9_GetViewport(device, &vp); + D3DXMatrixOrthoOffCenterLH(&cmpmat, vp.X+0.5f, (float)vp.Width+vp.X+0.5f, (float)vp.Height+vp.Y+0.5f, vp.Y+0.5f, vp.MinZ, vp.MaxZ); + check_mat(mat, cmpmat); + + /* Test ID3DXSprite_Flush and ID3DXSprite_End */ + hr = ID3DXSprite_Flush(sprite); + ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); + + hr = ID3DXSprite_End(sprite); + ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK); + + hr = ID3DXSprite_Flush(sprite); /* May not be called before next Begin */ + ok (hr == D3DERR_INVALIDCALL, "Flush returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + hr = ID3DXSprite_End(sprite); + ok (hr == D3DERR_INVALIDCALL, "End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + /* Test ID3DXSprite_Draw */ + hr = ID3DXSprite_Begin(sprite, 0); + ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); + + if(FAILED(hr)) skip("Couldn't ID3DXSprite_Begin, can't test ID3DXSprite_Draw\n"); + else { /* Feed the sprite batch */ + int texref1, texref2; + + SetRect(&rect, 53, 12, 142, 165); + pos.x = 2.2f; pos.y = 4.5f; pos.z = 5.1f; + center.x = 11.3f; center.y = 3.4f; center.z = 1.2f; + + texref1 = get_ref((IUnknown*)tex1); + texref2 = get_ref((IUnknown*)tex2); + + hr = ID3DXSprite_Draw(sprite, NULL, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); + ok (hr == D3DERR_INVALIDCALL, "Draw returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + hr = ID3DXSprite_Draw(sprite, tex1, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Draw(sprite, tex2, &rect, ¢er, &pos, D3DCOLOR_XRGB( 3, 45, 66)); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Draw(sprite, tex1, NULL, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Draw(sprite, tex1, &rect, NULL, &pos, D3DCOLOR_XRGB(255, 255, 255)); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Draw(sprite, tex1, &rect, ¢er, NULL, D3DCOLOR_XRGB(255, 255, 255)); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Draw(sprite, tex1, NULL, NULL, NULL, 0); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + + check_ref((IUnknown*)tex1, texref1+5); check_ref((IUnknown*)tex2, texref2+1); + hr = ID3DXSprite_Flush(sprite); + ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Flush(sprite); /* Flushing twice should work */ + ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); + check_ref((IUnknown*)tex1, texref1); check_ref((IUnknown*)tex2, texref2); + + hr = ID3DXSprite_End(sprite); + ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK); + } + + /* Test ID3DXSprite_OnLostDevice and ID3DXSprite_OnResetDevice */ + /* Both can be called twice */ + hr = ID3DXSprite_OnLostDevice(sprite); + ok (hr == D3D_OK, "OnLostDevice returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_OnLostDevice(sprite); + ok (hr == D3D_OK, "OnLostDevice returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_OnResetDevice(sprite); + ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_OnResetDevice(sprite); + ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK); + + /* Make sure everything works like before */ + hr = ID3DXSprite_Begin(sprite, 0); + ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Draw(sprite, tex2, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); + ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_Flush(sprite); + ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_End(sprite); + ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK); + + /* OnResetDevice makes the interface "forget" the Begin call */ + hr = ID3DXSprite_Begin(sprite, 0); + ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_OnResetDevice(sprite); + ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXSprite_End(sprite); + ok (hr == D3DERR_INVALIDCALL, "End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); + + IDirect3DDevice9_EndScene(device); + check_release((IUnknown*)sprite, 0); + check_release((IUnknown*)tex2, 0); + check_release((IUnknown*)tex1, 0); +} + +START_TEST(core) +{ + HWND wnd; + IDirect3D9 *d3d; + IDirect3DDevice9 *device; + D3DPRESENT_PARAMETERS d3dpp; + HRESULT hr; + + wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (!wnd) { + skip("Couldn't create application window\n"); + return; + } + if (!d3d) { + skip("Couldn't create IDirect3D9 object\n"); + DestroyWindow(wnd); + return; + } + + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device); + if(FAILED(hr)) { + skip("Failed to create IDirect3DDevice9 object %#x\n", hr); + IDirect3D9_Release(d3d); + DestroyWindow(wnd); + return; + } + + test_ID3DXSprite(device); + + check_release((IUnknown*)device, 0); + check_release((IUnknown*)d3d, 0); + if (wnd) DestroyWindow(wnd); +} diff --git a/dlls/dbghelp/Makefile.in b/dlls/dbghelp/Makefile.in index c089d6598b3..65dba5fd821 100644 --- a/dlls/dbghelp/Makefile.in +++ b/dlls/dbghelp/Makefile.in @@ -4,6 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = dbghelp.dll IMPORTLIB = dbghelp +EXTRADEFS = -D_IMAGEHLP_SOURCE_ IMPORTS = psapi kernel32 ntdll DELAYIMPORTS = version diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 27261a1c5f6..f5dc2510a91 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -681,7 +681,7 @@ struct IDirect3DVertexBufferImpl LONG ref; /*** WineD3D and ddraw links ***/ - IWineD3DVertexBuffer *wineD3DVertexBuffer; + IWineD3DBuffer *wineD3DVertexBuffer; IWineD3DVertexDeclaration *wineD3DVertexDeclaration; IDirectDrawImpl *ddraw; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 8f8437457e4..4d642e5021c 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3463,44 +3463,13 @@ IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface, DWORD Flags) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; - UINT PrimitiveCount, stride; + UINT stride; HRESULT hr; TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags); if(!Vertices) return DDERR_INVALIDPARAMS; - /* Get the vertex count */ - switch(PrimitiveType) - { - case D3DPT_POINTLIST: - PrimitiveCount = VertexCount; - break; - - case D3DPT_LINELIST: - PrimitiveCount = VertexCount / 2; - break; - - case D3DPT_LINESTRIP: - PrimitiveCount = VertexCount - 1; - break; - - case D3DPT_TRIANGLELIST: - PrimitiveCount = VertexCount / 3; - break; - - case D3DPT_TRIANGLESTRIP: - PrimitiveCount = VertexCount - 2; - break; - - case D3DPT_TRIANGLEFAN: - PrimitiveCount = VertexCount - 2; - break; - - default: - return DDERR_INVALIDPARAMS; - } - /* Get the stride */ stride = get_flexible_vertex_size(VertexType); @@ -3515,11 +3484,8 @@ IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface, } /* This method translates to the user pointer draw of WineD3D */ - hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, - PrimitiveType, - PrimitiveCount, - Vertices, - stride); + IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, VertexCount, Vertices, stride); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -3627,41 +3593,9 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, DWORD Flags) { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; - UINT PrimitiveCount = 0; HRESULT hr; TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); - /* Get the primitive number */ - switch(PrimitiveType) - { - case D3DPT_POINTLIST: - PrimitiveCount = IndexCount; - break; - - case D3DPT_LINELIST: - PrimitiveCount = IndexCount / 2; - break; - - case D3DPT_LINESTRIP: - PrimitiveCount = IndexCount - 1; - break; - - case D3DPT_TRIANGLELIST: - PrimitiveCount = IndexCount / 3; - break; - - case D3DPT_TRIANGLESTRIP: - PrimitiveCount = IndexCount - 2; - break; - - case D3DPT_TRIANGLEFAN: - PrimitiveCount = IndexCount - 2; - break; - - default: - return DDERR_INVALIDPARAMS; - } - /* Set the D3DDevice's FVF */ EnterCriticalSection(&ddraw_cs); hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, @@ -3673,9 +3607,10 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, return hr; } - hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, PrimitiveType, 0 /* MinVertexIndex */, - VertexCount /* UINT NumVertexIndex */, PrimitiveCount, Indices, WINED3DFMT_R16_UINT, Vertices, - get_flexible_vertex_size(VertexType)); + IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, 0 /* MinVertexIndex */, + VertexCount /* UINT NumVertexIndex */, IndexCount, Indices, WINED3DFMT_R16_UINT, + Vertices, get_flexible_vertex_size(VertexType)); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -3879,7 +3814,6 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; WineDirect3DVertexStridedData WineD3DStrided; DWORD i; - UINT PrimitiveCount; HRESULT hr; TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); @@ -3940,42 +3874,10 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, } } - /* Get the primitive count */ - switch(PrimitiveType) - { - case D3DPT_POINTLIST: - PrimitiveCount = VertexCount; - break; - - case D3DPT_LINELIST: - PrimitiveCount = VertexCount / 2; - break; - - case D3DPT_LINESTRIP: - PrimitiveCount = VertexCount - 1; - break; - - case D3DPT_TRIANGLELIST: - PrimitiveCount = VertexCount / 3; - break; - - case D3DPT_TRIANGLESTRIP: - PrimitiveCount = VertexCount - 2; - break; - - case D3DPT_TRIANGLEFAN: - PrimitiveCount = VertexCount - 2; - break; - - default: return DDERR_INVALIDPARAMS; - } - /* WineD3D doesn't need the FVF here */ EnterCriticalSection(&ddraw_cs); - hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, - PrimitiveType, - PrimitiveCount, - &WineD3DStrided); + IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, VertexCount, &WineD3DStrided); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -4053,7 +3955,6 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; WineDirect3DVertexStridedData WineD3DStrided; DWORD i; - UINT PrimitiveCount; HRESULT hr; TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); @@ -4114,40 +4015,11 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, } } - /* Get the primitive count */ - switch(PrimitiveType) - { - case D3DPT_POINTLIST: - PrimitiveCount = IndexCount; - break; - - case D3DPT_LINELIST: - PrimitiveCount = IndexCount / 2; - break; - - case D3DPT_LINESTRIP: - PrimitiveCount = IndexCount - 1; - break; - - case D3DPT_TRIANGLELIST: - PrimitiveCount = IndexCount / 3; - break; - - case D3DPT_TRIANGLESTRIP: - PrimitiveCount = IndexCount - 2; - break; - - case D3DPT_TRIANGLEFAN: - PrimitiveCount = IndexCount - 2; - break; - - default: return DDERR_INVALIDPARAMS; - } - /* WineD3D doesn't need the FVF here */ EnterCriticalSection(&ddraw_cs); - hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice, PrimitiveType, - PrimitiveCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT); + IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice, + IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -4230,7 +4102,6 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf; - UINT PrimitiveCount; HRESULT hr; DWORD stride; WINED3DVERTEXBUFFER_DESC Desc; @@ -4244,41 +4115,9 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, return DDERR_INVALIDPARAMS; } - /* Get the primitive count */ - switch(PrimitiveType) - { - case D3DPT_POINTLIST: - PrimitiveCount = NumVertices; - break; - - case D3DPT_LINELIST: - PrimitiveCount = NumVertices / 2; - break; - - case D3DPT_LINESTRIP: - PrimitiveCount = NumVertices - 1; - break; - - case D3DPT_TRIANGLELIST: - PrimitiveCount = NumVertices / 3; - break; - - case D3DPT_TRIANGLESTRIP: - PrimitiveCount = NumVertices - 2; - break; - - case D3DPT_TRIANGLEFAN: - PrimitiveCount = NumVertices - 2; - break; - - default: - return DDERR_INVALIDPARAMS; - } - /* Get the FVF of the vertex buffer, and its stride */ EnterCriticalSection(&ddraw_cs); - hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer, - &Desc); + hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc); if(hr != D3D_OK) { ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr); @@ -4310,10 +4149,8 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, } /* Now draw the primitives */ - hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, - PrimitiveType, - StartVertex, - PrimitiveCount); + IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType); + hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, StartVertex, NumVertices); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -4393,7 +4230,6 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf; DWORD stride; - UINT PrimitiveCount; WORD *LockedIndices; HRESULT hr; WINED3DVERTEXBUFFER_DESC Desc; @@ -4401,47 +4237,16 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags); /* Steps: - * 1) Calculate some things: Vertex count -> Primitive count, stride, ... + * 1) Calculate some things: stride, ... * 2) Upload the Indices to the index buffer * 3) Set the index source * 4) Set the Vertex Buffer as the Stream source * 5) Call IWineD3DDevice::DrawIndexedPrimitive */ - /* Get the primitive count */ - switch(PrimitiveType) - { - case D3DPT_POINTLIST: - PrimitiveCount = IndexCount; - break; - - case D3DPT_LINELIST: - PrimitiveCount = IndexCount / 2; - break; - - case D3DPT_LINESTRIP: - PrimitiveCount = IndexCount - 1; - break; - - case D3DPT_TRIANGLELIST: - PrimitiveCount = IndexCount / 3; - break; - - case D3DPT_TRIANGLESTRIP: - PrimitiveCount = IndexCount - 2; - break; - - case D3DPT_TRIANGLEFAN: - PrimitiveCount = IndexCount - 2; - break; - - default: return DDERR_INVALIDPARAMS; - } - EnterCriticalSection(&ddraw_cs); /* Get the FVF of the vertex buffer, and its stride */ - hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer, - &Desc); + hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc); if(hr != D3D_OK) { ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr); @@ -4505,12 +4310,9 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, } + IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType); hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, - PrimitiveType, - 0 /* minIndex */, - NumVertices, - 0 /* StartIndex */, - PrimitiveCount); + 0 /* minIndex */, NumVertices, 0 /* StartIndex */, IndexCount); LeaveCriticalSection(&ddraw_cs); return hr; diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c index f9e06f76643..2a051d0bcce 100644 --- a/dlls/ddraw/direct3d.c +++ b/dlls/ddraw/direct3d.c @@ -1043,7 +1043,7 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface, if(!object->wineD3DVertexDeclaration) { ERR("Cannot find the vertex declaration for fvf %08x\n", Desc->dwFVF); - IWineD3DVertexBuffer_Release(object->wineD3DVertexBuffer); + IWineD3DBuffer_Release(object->wineD3DVertexBuffer); HeapFree(GetProcessHeap(), 0, object); LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c index a12b9683585..f246807f3d0 100644 --- a/dlls/ddraw/tests/dsurface.c +++ b/dlls/ddraw/tests/dsurface.c @@ -1389,7 +1389,8 @@ static void AttachmentTest(void) hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1); ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr); hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */ - ok(hr == DD_OK, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr); + ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE), + "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr); if(SUCCEEDED(hr)) { hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3); diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index 18fe93eb231..277591c1c78 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -159,7 +159,7 @@ IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface) if (ref == 0) { - IWineD3DVertexBuffer *curVB = NULL; + IWineD3DBuffer *curVB = NULL; UINT offset, stride; EnterCriticalSection(&ddraw_cs); @@ -182,11 +182,11 @@ IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface) } if(curVB) { - IWineD3DVertexBuffer_Release(curVB); /* For the GetStreamSource */ + IWineD3DBuffer_Release(curVB); /* For the GetStreamSource */ } IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration); - IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer); + IWineD3DBuffer_Release(This->wineD3DVertexBuffer); LeaveCriticalSection(&ddraw_cs); HeapFree(GetProcessHeap(), 0, This); @@ -242,8 +242,7 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface, if(Size) { /* Get the size, for returning it, and for locking */ - hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, - &Desc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &Desc); if(hr != D3D_OK) { ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr); @@ -253,11 +252,8 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface, *Size = Desc.Size; } - hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, - 0 /* OffsetToLock */, - 0 /* SizeToLock, 0 == Full lock */, - (BYTE **) Data, - Flags); + hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, 0 /* OffsetToLock */, + 0 /* SizeToLock, 0 == Full lock */, (BYTE **)Data, Flags); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -291,7 +287,7 @@ IDirect3DVertexBufferImpl_Unlock(IDirect3DVertexBuffer7 *iface) TRACE("(%p)->()\n", This); EnterCriticalSection(&ddraw_cs); - hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer); + hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer); LeaveCriticalSection(&ddraw_cs); return hr; @@ -376,8 +372,7 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface, doClip); } - IWineD3DVertexBuffer_GetDesc(Src->wineD3DVertexBuffer, - &Desc); + IWineD3DBuffer_GetDesc(Src->wineD3DVertexBuffer, &Desc); IWineD3DDevice_SetStreamSource(D3D->wineD3DDevice, 0, /* Stream No */ Src->wineD3DVertexBuffer, @@ -447,8 +442,7 @@ IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface, if(!Desc) return DDERR_INVALIDPARAMS; EnterCriticalSection(&ddraw_cs); - hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, - &WDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &WDesc); if(hr != D3D_OK) { ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr); diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 299d92dd691..30d5e1821eb 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -829,8 +829,51 @@ IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface, DWORD dwFlags) { IDirect3DViewportImpl *This = (IDirect3DViewportImpl *)iface; - FIXME("(%p)->(%p,%p,%08x): stub!\n", This, lpDirect3DLight, lplpDirect3DLight, dwFlags); - return D3D_OK; + IDirect3DLightImpl *cur_light, *prev_light = NULL; + + TRACE("(%p)->(%p,%p,%08x)\n", This, lpDirect3DLight, lplpDirect3DLight, dwFlags); + + if (!lplpDirect3DLight) + return DDERR_INVALIDPARAMS; + + *lplpDirect3DLight = NULL; + + EnterCriticalSection(&ddraw_cs); + + cur_light = This->lights; + + switch (dwFlags) { + case D3DNEXT_NEXT: + if (!lpDirect3DLight) { + LeaveCriticalSection(&ddraw_cs); + return DDERR_INVALIDPARAMS; + } + while (cur_light != NULL) { + if (cur_light == (IDirect3DLightImpl *)lpDirect3DLight) { + *lplpDirect3DLight = (IDirect3DLight*)cur_light->next; + break; + } + cur_light = cur_light->next; + } + break; + case D3DNEXT_HEAD: + *lplpDirect3DLight = (IDirect3DLight*)This->lights; + break; + case D3DNEXT_TAIL: + while (cur_light != NULL) { + prev_light = cur_light; + cur_light = cur_light->next; + } + *lplpDirect3DLight = (IDirect3DLight*)prev_light; + break; + default: + ERR("Unknown flag %d\n", dwFlags); + break; + } + + LeaveCriticalSection(&ddraw_cs); + + return *lplpDirect3DLight ? D3D_OK : DDERR_INVALIDPARAMS; } /***************************************************************************** diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index f9c689b15db..de8c63c9fc0 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -87,11 +87,17 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM TRACE("(%p) %ld,%ld\n", iface, wparam, lparam); - dik_code = map_dik_code(hook->scanCode & 0xff,hook->vkCode); - /* R-Shift is special - it is an extended key with separate scan code */ - if (hook->flags & LLKHF_EXTENDED && dik_code != 0x36) - dik_code |= 0x80; - + switch (hook->vkCode) + { + /* R-Shift is special - it is an extended key with separate scan code */ + case VK_RSHIFT : dik_code = DIK_RSHIFT; break; + case VK_PAUSE : dik_code = DIK_PAUSE; break; + case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; + case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; + default: + dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode); + if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; + } new_diks = hook->flags & LLKHF_UP ? 0 : 0x80; /* returns now if key event already known */ diff --git a/dlls/dispdib.dll16/Makefile.in b/dlls/dispdib.dll16/Makefile.in new file mode 100644 index 00000000000..9671dd3d00e --- /dev/null +++ b/dlls/dispdib.dll16/Makefile.in @@ -0,0 +1,15 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = dispdib.dll16 +IMPORTS = kernel32 +EXTRADLLFLAGS = -Wb,--subsystem,win16 + +SPEC_SRCS = dispdib.dll16.spec + +C_SRCS = dispdib.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/gdi32/dispdib.c b/dlls/dispdib.dll16/dispdib.c similarity index 100% rename from dlls/gdi32/dispdib.c rename to dlls/dispdib.dll16/dispdib.c diff --git a/dlls/gdi32/dispdib.spec b/dlls/dispdib.dll16/dispdib.dll16.spec similarity index 100% rename from dlls/gdi32/dispdib.spec rename to dlls/dispdib.dll16/dispdib.dll16.spec diff --git a/dlls/display.drv16/Makefile.in b/dlls/display.drv16/Makefile.in new file mode 100644 index 00000000000..06c053130a1 --- /dev/null +++ b/dlls/display.drv16/Makefile.in @@ -0,0 +1,19 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = display.drv16 +IMPORTS = user32 kernel32 + +EXTRADLLFLAGS = -Wb,--subsystem,win16 +EXTRARCFLAGS = -O res16 + +SPEC_SRCS = display.drv16.spec + +C_SRCS = display.c + +RC_SRCS = display.rc + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/user32/display.c b/dlls/display.drv16/display.c similarity index 87% rename from dlls/user32/display.c rename to dlls/display.drv16/display.c index 42887381888..2476b630b3d 100644 --- a/dlls/user32/display.c +++ b/dlls/display.drv16/display.c @@ -23,7 +23,6 @@ #include "wine/debug.h" #include "windef.h" #include "winbase.h" -#include "user_private.h" #include "wine/winuser16.h" WINE_DEFAULT_DEBUG_CHANNEL(cursor); @@ -39,7 +38,7 @@ typedef struct tagCURSORINFO16 /*********************************************************************** * Inquire (DISPLAY.101) */ -WORD WINAPI DISPLAY_Inquire(LPCURSORINFO16 lpCursorInfo) +WORD WINAPI Inquire16(LPCURSORINFO16 lpCursorInfo) { lpCursorInfo->wXMickeys = 1; lpCursorInfo->wYMickeys = 1; @@ -52,21 +51,21 @@ WORD WINAPI DISPLAY_Inquire(LPCURSORINFO16 lpCursorInfo) */ VOID WINAPI DISPLAY_SetCursor( struct tagCURSORICONINFO *lpCursor ) { - USER_Driver->pSetCursor(lpCursor); + FIXME("stub\n" ); } /*********************************************************************** * MoveCursor (DISPLAY.103) */ -VOID WINAPI DISPLAY_MoveCursor( WORD wAbsX, WORD wAbsY ) +VOID WINAPI MoveCursor16( WORD wAbsX, WORD wAbsY ) { - USER_Driver->pSetCursorPos(wAbsX, wAbsY); + SetCursorPos( wAbsX, wAbsY ); } /*********************************************************************** * CheckCursor (DISPLAY.104) */ -VOID WINAPI DISPLAY_CheckCursor( void ) +VOID WINAPI CheckCursor16( void ) { TRACE("stub\n" ); } @@ -79,7 +78,7 @@ VOID WINAPI DISPLAY_CheckCursor( void ) * wQueriedResID is the ID USER asks about. * lpsResName does often contain "OEMBIN". */ -DWORD WINAPI DISPLAY_GetDriverResourceID( WORD wQueriedResID, LPSTR lpsResName ) +DWORD WINAPI GetDriverResourceID16( WORD wQueriedResID, LPSTR lpsResName ) { if (wQueriedResID == 3) return (DWORD)1; diff --git a/dlls/user32/display.drv.spec b/dlls/display.drv16/display.drv16.spec similarity index 83% rename from dlls/user32/display.drv.spec rename to dlls/display.drv16/display.drv16.spec index 2a805d699a2..dc4ee5db882 100644 --- a/dlls/user32/display.drv.spec +++ b/dlls/display.drv16/display.drv16.spec @@ -40,15 +40,15 @@ 90 stub Do_Polylines 91 stub Do_Scanlines 92 stub SaveScreenBitmap -101 pascal -ret16 Inquire(ptr) DISPLAY_Inquire +101 pascal -ret16 Inquire(ptr) Inquire16 102 pascal -ret16 SetCursor(ptr) DISPLAY_SetCursor -103 pascal -ret16 MoveCursor(word word) DISPLAY_MoveCursor -104 pascal -ret16 CheckCursor() DISPLAY_CheckCursor +103 pascal -ret16 MoveCursor(word word) MoveCursor16 +104 pascal -ret16 CheckCursor() CheckCursor16 400 stub PExtTextOut 401 stub PStrBlt 402 stub RExtTextOut 403 stub RStrBlt -450 pascal GetDriverResourceID(word str) DISPLAY_GetDriverResourceID +450 pascal GetDriverResourceID(word str) GetDriverResourceID16 500 pascal -ret16 UserRepaintDisable(word) UserRepaintDisable16 501 stub ORDINAL_ONLY1 502 stub ORDINAL_ONLY2 diff --git a/dlls/user32/resources/display.rc b/dlls/display.drv16/display.rc similarity index 96% rename from dlls/user32/resources/display.rc rename to dlls/display.drv16/display.rc index 243bf2d7380..570ab8fb0bb 100644 --- a/dlls/user32/resources/display.rc +++ b/dlls/display.drv16/display.rc @@ -53,5 +53,5 @@ 0x00000000L /* inactive caption text */ } -/* @makedep: resources/oic_hand.ico */ -1 ICON resources/oic_hand.ico +/* @makedep: oic_hand.ico */ +1 ICON oic_hand.ico diff --git a/dlls/display.drv16/oic_hand.ico b/dlls/display.drv16/oic_hand.ico new file mode 100644 index 0000000000000000000000000000000000000000..502f1acc3624f71a7e78d33c51e2aff91f758560 GIT binary patch literal 766 zcwT){J8r`;41J0Vc#OSN@Z^lWMSCP?(pX=?qb6TPN6FZ+V+sUiA1TX*4WyKwq(@TJ zhXfqk<jb=Vej_f#2jTEyw(*1~GFrzt=1H5XIHZ)Q5$h1ilQvc9U{Z$=hAmvk zQfPf`+t#lhb=$=lr?x1rF^kVTT(|Jan?s>gD0guaAC7!b_u0sgZBVmt8D~)k<+JEg zRO^FVmRadT7qf$z89+ISn7ME|n7Qz{n4j^Z{}ylP;_kfRaG&FSv42m4{du@pvp{sR32INzD$Z{h}2giFMjVfFQoIBdQZ WQKuZ|O!SQT&e%N1vGOXBTQ7g?7a+X= literal 0 HcwPel00001 diff --git a/dlls/dmloader/container.c b/dlls/dmloader/container.c index 3cd166edf06..a1fa878bd64 100644 --- a/dlls/dmloader/container.c +++ b/dlls/dmloader/container.c @@ -641,7 +641,7 @@ static HRESULT WINAPI IDirectMusicContainerImpl_IPersistStream_Load (LPPERSISTST DMUS_IO_CONTAINED_OBJECT_HEADER tmpObjectHeader; TRACE_(dmfile)(": contained object header chunk\n"); IStream_Read (pStm, &tmpObjectHeader, Chunk.dwSize, NULL); - TRACE_(dmdump)(": contained object header: \n%s\n", debugstr_DMUS_IO_CONTAINED_OBJECT_HEADER(&tmpObjectHeader)); + TRACE_(dmdump)(": contained object header:\n%s\n", debugstr_DMUS_IO_CONTAINED_OBJECT_HEADER(&tmpObjectHeader)); /* copy guidClass */ pNewEntry->Desc.dwValidData |= DMUS_OBJ_CLASS; pNewEntry->Desc.guidClass = tmpObjectHeader.guidClassID; diff --git a/dlls/dmloader/loader.c b/dlls/dmloader/loader.c index 8a31b62e7ef..17a8eb29cf0 100644 --- a/dlls/dmloader/loader.c +++ b/dlls/dmloader/loader.c @@ -26,7 +26,7 @@ static HRESULT DMUSIC_GetLoaderSettings (LPDIRECTMUSICLOADER8 iface, REFGUID pCl static HRESULT DMUSIC_SetLoaderSettings (LPDIRECTMUSICLOADER8 iface, REFGUID pClassID, WCHAR* wszSearchPath, LPBOOL pbCache); static HRESULT DMUSIC_CopyDescriptor (LPDMUS_OBJECTDESC pDst, LPDMUS_OBJECTDESC pSrc) { - TRACE(": copy \n%s\n", debugstr_DMUS_OBJECTDESC(pSrc)); + TRACE(": copy\n%s\n", debugstr_DMUS_OBJECTDESC(pSrc)); /* copy field by field */ if (pSrc->dwValidData & DMUS_OBJ_CLASS) pDst->guidClass = pSrc->guidClass; if (pSrc->dwValidData & DMUS_OBJ_OBJECT) pDst->guidObject = pSrc->guidObject; @@ -482,7 +482,7 @@ static HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_SetObject (LPDIR } /* add new entry */ - TRACE(": adding alias entry with following info: \n%s\n", debugstr_DMUS_OBJECTDESC(pDesc)); + TRACE(": adding alias entry with following info:\n%s\n", debugstr_DMUS_OBJECTDESC(pDesc)); pNewEntry = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(WINE_LOADER_ENTRY)); /* use this function instead of pure memcpy due to streams (memcpy just copies pointer), which is basically used further by app that called SetDescriptor... better safety than exception */ @@ -694,7 +694,7 @@ static HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_ReleaseObject (L } } if (result == S_OK) { - /*TRACE(": releasing: \n%s - bInvalidDefaultDLS = %i\n - pObject = %p\n", debugstr_DMUS_OBJECTDESC(&pObjectEntry->Desc), pObjectEntry->bInvalidDefaultDLS, pObjectEntry->pObject); */ + /*TRACE(": releasing:\n%s - bInvalidDefaultDLS = %i\n - pObject = %p\n", debugstr_DMUS_OBJECTDESC(&pObjectEntry->Desc), pObjectEntry->bInvalidDefaultDLS, pObjectEntry->pObject); */ IDirectMusicObject_Release (pObjectEntry->pObject); pObjectEntry->pObject = NULL; pObjectEntry->Desc.dwValidData &= ~DMUS_OBJ_LOADED; diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 688ad7183a1..251c436d14a 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -118,7 +118,7 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions( /* Make an internal copy of the caller-supplied array. * Replace the existing copy if one is already present. */ HeapFree(GetProcessHeap(), 0, This->dsb->notifies); - This->dsb->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + This->dsb->notifies = HeapAlloc(GetProcessHeap(), 0, howmuch * sizeof(DSBPOSITIONNOTIFY)); if (This->dsb->notifies == NULL) { diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in index dce15b80ba5..fbd2d476f7e 100644 --- a/dlls/gdi32/Makefile.in +++ b/dlls/gdi32/Makefile.in @@ -10,7 +10,6 @@ EXTRAINCL = @FREETYPEINCL@ @FONTCONFIGINCL@ EXTRALIBS = @CARBONLIB@ SPEC_SRCS16 = \ - dispdib.spec \ gdi.exe.spec \ wing.spec @@ -55,7 +54,6 @@ C_SRCS = \ C_SRCS16 = \ bidi16.c \ - dispdib.c \ env.c \ gdi16.c \ metafile16.c \ diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index b1ba7a0607c..9e2f0c953f7 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -72,7 +72,7 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE BITMAP bm; BITMAP bma[2]; INT ret, width_bytes; - char buf[512], buf_cmp[512]; + BYTE buf[512], buf_cmp[512]; DWORD gle; ret = GetObject(hbm, sizeof(bm), &bm); @@ -101,7 +101,10 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE memset(buf, 0xAA, sizeof(buf)); ret = GetBitmapBits(hbm, sizeof(buf), buf); ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); - ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n"); + if(bm.bmType == 21072) + win_skip("win9x does not initialize the bitmap\n"); + else + ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match, depth %d\n", bmih->biBitCount); /* test various buffer sizes for GetObject */ ret = GetObject(hbm, sizeof(*bma) * 2, bma); @@ -427,7 +430,9 @@ static void test_dib_bits_access( HBITMAP hdib, void *bits ) pbmi->bmiHeader.biCompression = BI_RGB; ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS ); - ok( ret == 16, "SetDIBits failed\n" ); + ok(ret == 16 || + broken(ret == 0), /* win9x */ + "SetDIBits failed: expected 16 got %d\n", ret); ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n"); @@ -716,7 +721,8 @@ static void test_dibsections(void) hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); ok(hdib != NULL, "CreateDIBSection failed\n"); ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); - ok(dibsec.dsBmih.biClrUsed == 2, + ok(dibsec.dsBmih.biClrUsed == 2 || + broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */ "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2); /* The colour table has already been grabbed from the dc, so we select back the @@ -808,7 +814,8 @@ static void test_dibsections(void) hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); ok(hdib != NULL, "CreateDIBSection failed\n"); ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); - ok(dibsec.dsBmih.biClrUsed == 256, + ok(dibsec.dsBmih.biClrUsed == 256 || + broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */ "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256); test_dib_info(hdib, bits, &pbmi->bmiHeader); @@ -1899,7 +1906,9 @@ static void test_select_object(void) memset(&bm, 0xAA, sizeof(bm)); bytes = GetObject(hbm, sizeof(bm), &bm); ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes); - ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType); + ok(bm.bmType == 0 || + broken(bm.bmType == 21072), /* win9x */ + "wrong bmType %d\n", bm.bmType); ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth); ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight); ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes); @@ -2185,7 +2194,7 @@ static void test_get16dibits(void) info->bmiHeader.biCompression = BI_RGB; ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0); - ok(ret != 0, "GetDIBits failed\n"); + ok(ret != 0, "GetDIBits failed got %d\n", ret); for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++) if (*p != '!') diff --git a/dlls/gdi32/tests/clipping.c b/dlls/gdi32/tests/clipping.c index 0ae3eb6ff56..eff87c3c463 100644 --- a/dlls/gdi32/tests/clipping.c +++ b/dlls/gdi32/tests/clipping.c @@ -162,12 +162,16 @@ static void verify_region(HRGN hrgn, const RECT *rc) if (IsRectEmpty(rc)) { ok(rgn.data.rdh.nCount == 0, "expected 0, got %u\n", rgn.data.rdh.nCount); - ok(rgn.data.rdh.nRgnSize == 0, "expected 0, got %u\n", rgn.data.rdh.nRgnSize); + ok(rgn.data.rdh.nRgnSize == 0 || + broken(rgn.data.rdh.nRgnSize == 168), /* NT4 */ + "expected 0, got %u\n", rgn.data.rdh.nRgnSize); } else { ok(rgn.data.rdh.nCount == 1, "expected 1, got %u\n", rgn.data.rdh.nCount); - ok(rgn.data.rdh.nRgnSize == sizeof(RECT), "expected sizeof(RECT), got %u\n", rgn.data.rdh.nRgnSize); + ok(rgn.data.rdh.nRgnSize == sizeof(RECT) || + broken(rgn.data.rdh.nRgnSize == 168), /* NT4 */ + "expected sizeof(RECT), got %u\n", rgn.data.rdh.nRgnSize); } ok(EqualRect(&rgn.data.rdh.rcBound, rc), "rects don't match\n"); } @@ -236,9 +240,14 @@ if (0) /* crashes under Win9x */ SetLastError(0xdeadbeef); hrgn = ExtCreateRegion(NULL, 1, &rgn.data); - ok(hrgn != 0, "ExtCreateRegion error %u\n", GetLastError()); - verify_region(hrgn, &rc); - DeleteObject(hrgn); + ok(hrgn != 0 || + broken(GetLastError() == 0xdeadbeef), /* NT4 */ + "ExtCreateRegion error %u\n", GetLastError()); + if(hrgn) + { + verify_region(hrgn, &rc); + DeleteObject(hrgn); + } xform.eM11 = 0.5; /* 50% width */ xform.eM12 = 0.0; diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 0037a74182f..17f4951c9fd 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -47,7 +47,7 @@ @ stdcall GdipBitmapUnlockBits(ptr ptr) @ stdcall GdipClearPathMarkers(ptr) @ stub GdipCloneBitmapArea -@ stub GdipCloneBitmapAreaI +@ stdcall GdipCloneBitmapAreaI(long long long long long ptr ptr) @ stdcall GdipCloneBrush(ptr ptr) @ stdcall GdipCloneCustomLineCap(ptr ptr) @ stdcall GdipCloneFont(ptr ptr) diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index a229f8b637d..8a4dcc27389 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -249,6 +249,14 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap, return Ok; } +GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height, + PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap) +{ + FIXME("(%i,%i,%i,%i,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap); + + return NotImplemented; +} + GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage) { IStream* stream; @@ -549,6 +557,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, ERR("could not make stream\n"); GdipFree(*bitmap); GdipFree(buff); + *bitmap = NULL; return GenericError; } @@ -558,6 +567,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, IStream_Release(stream); GdipFree(*bitmap); GdipFree(buff); + *bitmap = NULL; return GenericError; } diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 12fab7cb659..5d46c8b33eb 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -229,6 +229,7 @@ static void test_SavingImages(void) const REAL WIDTH = 10.0, HEIGHT = 20.0; REAL w, h; ImageCodecInfo *codecs; + static const CHAR filenameA[] = "a.bmp"; static const WCHAR filename[] = { 'a','.','b','m','p',0 }; codecs = NULL; @@ -280,7 +281,7 @@ static void test_SavingImages(void) GdipFree(codecs); if (bm) GdipDisposeImage((GpImage*)bm); - ok(DeleteFileW(filename), "Delete failed.\n"); + ok(DeleteFileA(filenameA), "Delete failed.\n"); } static void test_encoders(void) @@ -292,7 +293,7 @@ static void test_encoders(void) int i; int bmp_found; - static const WCHAR bmp_format[] = {'B', 'M', 'P', 0}; + static const CHAR bmp_format[] = "BMP"; stat = GdipGetImageEncodersSize(&n, &s); expect(stat, Ok); @@ -319,8 +320,13 @@ static void test_encoders(void) bmp_found = FALSE; for (i = 0; i < n; i++) { - if (CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, - codecs[i].FormatDescription, -1, + CHAR desc[32]; + + WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1, + desc, 32, 0, 0); + + if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, + desc, -1, bmp_format, -1) == CSTR_EQUAL) { bmp_found = TRUE; break; diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c index 689811cedc4..d48554c48b6 100644 --- a/dlls/gdiplus/tests/region.c +++ b/dlls/gdiplus/tests/region.c @@ -793,12 +793,14 @@ static void test_fromhrgn(void) status = GdipGetRegionDataSize(region, &needed); todo_wine{ expect(Ok, status); - expect(216, needed); + ok(needed == 216 || + needed == 196, /* win98 */ + "Got %.8x\n", needed); } status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); todo_wine expect(Ok, status); - if(status == Ok) + if(status == Ok && needed == 216) /* Don't try to test win98 layout */ { todo_wine{ expect(Ok, status); diff --git a/dlls/iphlpapi/Makefile.in b/dlls/iphlpapi/Makefile.in index 76315af9f38..09ed78d2780 100644 --- a/dlls/iphlpapi/Makefile.in +++ b/dlls/iphlpapi/Makefile.in @@ -5,7 +5,7 @@ VPATH = @srcdir@ MODULE = iphlpapi.dll IMPORTLIB = iphlpapi IMPORTS = advapi32 kernel32 -EXTRALIBS = @RESOLVLIBS@ +EXTRALIBS = @RESOLVLIBS@ @LIBKSTAT@ C_SRCS = \ icmp.c \ diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 3481f869c8a..547b6667b48 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -733,29 +733,6 @@ DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex) /****************************************************************** - * GetIcmpStatistics (IPHLPAPI.@) - * - * Get the ICMP statistics for the local computer. - * - * PARAMS - * pStats [Out] buffer for ICMP statistics - * - * RETURNS - * Success: NO_ERROR - * Failure: error code from winerror.h - */ -DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats) -{ - DWORD ret; - - TRACE("pStats %p\n", pStats); - ret = getICMPStats(pStats); - TRACE("returning %d\n", ret); - return ret; -} - - -/****************************************************************** * GetIfEntry (IPHLPAPI.@) * * Get information about an interface. @@ -1110,29 +1087,6 @@ DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize, BOOL bOr /****************************************************************** - * GetIpStatistics (IPHLPAPI.@) - * - * Get the IP statistics for the local computer. - * - * PARAMS - * pStats [Out] buffer for IP statistics - * - * RETURNS - * Success: NO_ERROR - * Failure: error code from winerror.h - */ -DWORD WINAPI GetIpStatistics(PMIB_IPSTATS pStats) -{ - DWORD ret; - - TRACE("pStats %p\n", pStats); - ret = getIPStats(pStats); - TRACE("returning %d\n", ret); - return ret; -} - - -/****************************************************************** * GetNetworkParams (IPHLPAPI.@) * * Get the network parameters for the local computer. @@ -1303,29 +1257,6 @@ BOOL WINAPI GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHo /****************************************************************** - * GetTcpStatistics (IPHLPAPI.@) - * - * Get the TCP statistics for the local computer. - * - * PARAMS - * pStats [Out] buffer for TCP statistics - * - * RETURNS - * Success: NO_ERROR - * Failure: error code from winerror.h - */ -DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats) -{ - DWORD ret; - - TRACE("pStats %p\n", pStats); - ret = getTCPStats(pStats); - TRACE("returning %d\n", ret); - return ret; -} - - -/****************************************************************** * GetTcpTable (IPHLPAPI.@) * * Get the table of active TCP connections. @@ -1375,29 +1306,6 @@ DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder) /****************************************************************** - * GetUdpStatistics (IPHLPAPI.@) - * - * Get the UDP statistics for the local computer. - * - * PARAMS - * pStats [Out] buffer for UDP statistics - * - * RETURNS - * Success: NO_ERROR - * Failure: error code from winerror.h - */ -DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats) -{ - DWORD ret; - - TRACE("pStats %p\n", pStats); - ret = getUDPStats(pStats); - TRACE("returning %d\n", ret); - return ret; -} - - -/****************************************************************** * GetUdpTable (IPHLPAPI.@) * * Get a table of active UDP connections. diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index f630906cd2c..a1b99818962 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -107,6 +107,9 @@ #ifdef HAVE_SYS_SYSCTL_H #include #endif +#ifdef HAVE_KSTAT_H +#include +#endif #ifndef ROUNDUP #define ROUNDUP(a) \ @@ -148,743 +151,712 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); -DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) +#ifdef HAVE_LIBKSTAT +static DWORD kstat_get_ui32( kstat_t *ksp, const char *name ) { -#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_IFLIST) - int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, if_nametoindex(name)}; -#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) + unsigned int i; + kstat_named_t *data = ksp->ks_data; - size_t needed; - char *buf, *end; - struct if_msghdr *ifm; - struct if_data ifdata; - if (!name || !entry) - return ERROR_INVALID_PARAMETER; - - if(sysctl(mib, MIB_LEN, NULL, &needed, NULL, 0) == -1) - { - ERR ("failed to get size of iflist\n"); - return ERROR_NOT_SUPPORTED; - } - buf = HeapAlloc (GetProcessHeap (), 0, needed); - if (!buf) return ERROR_NOT_SUPPORTED; - if(sysctl(mib, MIB_LEN, buf, &needed, NULL, 0) == -1) - { - ERR ("failed to get iflist\n"); - HeapFree (GetProcessHeap (), 0, buf); - return ERROR_NOT_SUPPORTED; - } - else - for ( end = buf + needed; buf < end; buf += ifm->ifm_msglen) - { - ifm = (struct if_msghdr *) buf; - if(ifm->ifm_type == RTM_IFINFO && ifm->ifm_data.ifi_type == IFT_ETHER) - { - ifdata = ifm->ifm_data; - entry->dwMtu = ifdata.ifi_mtu; - entry->dwSpeed = ifdata.ifi_baudrate; - entry->dwInOctets = ifdata.ifi_ibytes; - entry->dwInErrors = ifdata.ifi_ierrors; - entry->dwInDiscards = ifdata.ifi_iqdrops; - entry->dwInUcastPkts = ifdata.ifi_ipackets; - entry->dwInNUcastPkts = ifdata.ifi_imcasts; - entry->dwOutOctets = ifdata.ifi_obytes; - entry->dwOutUcastPkts = ifdata.ifi_opackets; - entry->dwOutErrors = ifdata.ifi_oerrors; - HeapFree (GetProcessHeap (), 0, buf); - return NO_ERROR; - } - } - HeapFree (GetProcessHeap (), 0, buf); - return ERROR_NOT_SUPPORTED; -#else - /* get interface stats from /proc/net/dev, no error if can't - no inUnknownProtos, outNUcastPkts, outQLen */ - FILE *fp; - - if (!name || !entry) - return ERROR_INVALID_PARAMETER; - fp = fopen("/proc/net/dev", "r"); - if (fp) { - char buf[512] = { 0 }, *ptr; - int nameLen = strlen(name), nameFound = 0; - - - ptr = fgets(buf, sizeof(buf), fp); - while (ptr && !nameFound) { - while (*ptr && isspace(*ptr)) - ptr++; - if (strncasecmp(ptr, name, nameLen) == 0 && *(ptr + nameLen) == ':') - nameFound = 1; - else - ptr = fgets(buf, sizeof(buf), fp); - } - if (nameFound) { - char *endPtr; + for (i = 0; i < ksp->ks_ndata; i++) + if (!strcmp( data[i].name, name )) return data[i].value.ui32; + return 0; +} - ptr += nameLen + 1; - if (ptr && *ptr) { - entry->dwInOctets = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInUcastPkts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInDiscards = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - strtoul(ptr, &endPtr, 10); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - strtoul(ptr, &endPtr, 10); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - strtoul(ptr, &endPtr, 10); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInNUcastPkts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutOctets = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutUcastPkts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutDiscards = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - } - fclose(fp); - } - else - { - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; - } - - return NO_ERROR; -#endif +static ULONGLONG kstat_get_ui64( kstat_t *ksp, const char *name ) +{ + unsigned int i; + kstat_named_t *data = ksp->ks_data; + + for (i = 0; i < ksp->ks_ndata; i++) + if (!strcmp( data[i].name, name )) return data[i].value.ui64; + return 0; } +#endif -DWORD getICMPStats(MIB_ICMP *stats) +DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) { -#if defined(HAVE_SYS_SYSCTL_H) && defined(ICMPCTL_STATS) - int mib[] = {CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS}; -#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) - size_t needed; - struct icmpstat icmp_stat; - int i; - - if (!stats) - return ERROR_INVALID_PARAMETER; - - needed = sizeof(icmp_stat); - if(sysctl(mib, MIB_LEN, &icmp_stat, &needed, NULL, 0) == -1) - { - ERR ("failed to get icmpstat\n"); - return ERROR_NOT_SUPPORTED; - } - - - /*in stats */ - stats->stats.icmpInStats.dwMsgs = icmp_stat.icps_badcode + icmp_stat.icps_checksum + icmp_stat.icps_tooshort + icmp_stat.icps_badlen; - for(i = 0; i <= ICMP_MAXTYPE; i++) - stats->stats.icmpInStats.dwMsgs += icmp_stat.icps_inhist[i]; - - stats->stats.icmpInStats.dwErrors = icmp_stat.icps_badcode + icmp_stat.icps_tooshort + icmp_stat.icps_checksum + icmp_stat.icps_badlen; - - stats->stats.icmpInStats.dwDestUnreachs = icmp_stat.icps_inhist[ICMP_UNREACH]; - stats->stats.icmpInStats.dwTimeExcds = icmp_stat.icps_inhist[ICMP_TIMXCEED]; - stats->stats.icmpInStats.dwParmProbs = icmp_stat.icps_inhist[ICMP_PARAMPROB]; - stats->stats.icmpInStats.dwSrcQuenchs = icmp_stat.icps_inhist[ICMP_SOURCEQUENCH]; - stats->stats.icmpInStats.dwRedirects = icmp_stat.icps_inhist[ICMP_REDIRECT]; - stats->stats.icmpInStats.dwEchos = icmp_stat.icps_inhist[ICMP_ECHO]; - stats->stats.icmpInStats.dwEchoReps = icmp_stat.icps_inhist[ICMP_ECHOREPLY]; - stats->stats.icmpInStats.dwTimestamps = icmp_stat.icps_inhist[ICMP_TSTAMP]; - stats->stats.icmpInStats.dwTimestampReps = icmp_stat.icps_inhist[ICMP_TSTAMPREPLY]; - stats->stats.icmpInStats.dwAddrMasks = icmp_stat.icps_inhist[ICMP_MASKREQ]; - stats->stats.icmpInStats.dwAddrMaskReps = icmp_stat.icps_inhist[ICMP_MASKREPLY]; + DWORD ret = ERROR_NOT_SUPPORTED; -#ifdef HAVE_ICPS_OUTHIST - /* out stats */ - stats->stats.icmpOutStats.dwMsgs = icmp_stat.icps_oldshort + icmp_stat.icps_oldicmp; - for(i = 0; i <= ICMP_MAXTYPE; i++) - stats->stats.icmpOutStats.dwMsgs += icmp_stat.icps_outhist[i]; - - stats->stats.icmpOutStats.dwErrors = icmp_stat.icps_oldshort + icmp_stat.icps_oldicmp; - - stats->stats.icmpOutStats.dwDestUnreachs = icmp_stat.icps_outhist[ICMP_UNREACH]; - stats->stats.icmpOutStats.dwTimeExcds = icmp_stat.icps_outhist[ICMP_TIMXCEED]; - stats->stats.icmpOutStats.dwParmProbs = icmp_stat.icps_outhist[ICMP_PARAMPROB]; - stats->stats.icmpOutStats.dwSrcQuenchs = icmp_stat.icps_outhist[ICMP_SOURCEQUENCH]; - stats->stats.icmpOutStats.dwRedirects = icmp_stat.icps_outhist[ICMP_REDIRECT]; - stats->stats.icmpOutStats.dwEchos = icmp_stat.icps_outhist[ICMP_ECHO]; - stats->stats.icmpOutStats.dwEchoReps = icmp_stat.icps_outhist[ICMP_ECHOREPLY]; - stats->stats.icmpOutStats.dwTimestamps = icmp_stat.icps_outhist[ICMP_TSTAMP]; - stats->stats.icmpOutStats.dwTimestampReps = icmp_stat.icps_outhist[ICMP_TSTAMPREPLY]; - stats->stats.icmpOutStats.dwAddrMasks = icmp_stat.icps_outhist[ICMP_MASKREQ]; - stats->stats.icmpOutStats.dwAddrMaskReps = icmp_stat.icps_outhist[ICMP_MASKREPLY]; -#else /* ICPS_OUTHIST */ - memset( &stats->stats.icmpOutStats, 0, sizeof(stats->stats.icmpOutStats) ); -#endif /* ICPS_OUTHIST */ + if (!name || !entry) return ERROR_INVALID_PARAMETER; - return NO_ERROR; +#ifdef __linux__ + { + FILE *fp; -#else /* ICMPCTL_STATS */ - FILE *fp; - - if (!stats) - return ERROR_INVALID_PARAMETER; - - memset(stats, 0, sizeof(MIB_ICMP)); - /* get most of these stats from /proc/net/snmp, no error if can't */ - fp = fopen("/proc/net/snmp", "r"); - if (fp) { - static const char hdr[] = "Icmp:"; - char buf[512] = { 0 }, *ptr; - - do { - ptr = fgets(buf, sizeof(buf), fp); - } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1)); - if (ptr) { - /* last line was a header, get another */ - ptr = fgets(buf, sizeof(buf), fp); - if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) { - char *endPtr; - - ptr += sizeof(hdr); - if (ptr && *ptr) { - stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + if ((fp = fopen("/proc/net/dev", "r"))) + { + DWORD skip; + char buf[512], *ptr; + int nameLen = strlen(name); + + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + while (*ptr && isspace(*ptr)) ptr++; + if (strncasecmp(ptr, name, nameLen) == 0 && *(ptr + nameLen) == ':') + { + ptr += nameLen + 1; + sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u", + &entry->dwInOctets, &entry->dwInUcastPkts, + &entry->dwInErrors, &entry->dwInDiscards, + &skip, &skip, &skip, + &entry->dwInNUcastPkts, &entry->dwOutOctets, + &entry->dwOutUcastPkts, &entry->dwOutErrors, + &entry->dwOutDiscards ); + break; + } + } + fclose(fp); + ret = NO_ERROR; } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + } +#elif defined(HAVE_LIBKSTAT) + { + kstat_ctl_t *kc; + kstat_t *ksp; + + if ((kc = kstat_open()) && + (ksp = kstat_lookup( kc, NULL, -1, (char *)name )) && + kstat_read( kc, ksp, NULL ) != -1 && + ksp->ks_type == KSTAT_TYPE_NAMED) + { + entry->dwMtu = 1500; /* FIXME */ + entry->dwSpeed = min( kstat_get_ui64( ksp, "ifspeed" ), ~0u ); + entry->dwInOctets = kstat_get_ui32( ksp, "rbytes" ); + entry->dwInNUcastPkts = kstat_get_ui32( ksp, "multircv" ); + entry->dwInNUcastPkts += kstat_get_ui32( ksp, "brdcstrcv" ); + entry->dwInUcastPkts = kstat_get_ui32( ksp, "ipackets" ) - entry->dwInNUcastPkts; + entry->dwInDiscards = kstat_get_ui32( ksp, "norcvbuf" ); + entry->dwInErrors = kstat_get_ui32( ksp, "ierrors" ); + entry->dwInUnknownProtos = kstat_get_ui32( ksp, "unknowns" ); + entry->dwOutOctets = kstat_get_ui32( ksp, "obytes" ); + entry->dwOutNUcastPkts = kstat_get_ui32( ksp, "multixmt" ); + entry->dwOutNUcastPkts += kstat_get_ui32( ksp, "brdcstxmt" ); + entry->dwOutUcastPkts = kstat_get_ui32( ksp, "opackets" ) - entry->dwOutNUcastPkts; + entry->dwOutDiscards = 0; /* FIXME */ + entry->dwOutErrors = kstat_get_ui32( ksp, "oerrors" ); + entry->dwOutQLen = kstat_get_ui32( ksp, "noxmtbuf" ); + ret = NO_ERROR; + } + if (kc) kstat_close( kc ); + } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_IFLIST) + { + int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, if_nametoindex(name)}; +#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) + + size_t needed; + char *buf = NULL, *end; + struct if_msghdr *ifm; + struct if_data ifdata; + + if(sysctl(mib, MIB_LEN, NULL, &needed, NULL, 0) == -1) + { + ERR ("failed to get size of iflist\n"); + goto done; } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + buf = HeapAlloc (GetProcessHeap (), 0, needed); + if (!buf) + { + ret = ERROR_OUTOFMEMORY; + goto done; } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + if(sysctl(mib, MIB_LEN, buf, &needed, NULL, 0) == -1) + { + ERR ("failed to get iflist\n"); + goto done; } - if (ptr && *ptr) { - stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + for ( end = buf + needed; buf < end; buf += ifm->ifm_msglen) + { + ifm = (struct if_msghdr *) buf; + if(ifm->ifm_type == RTM_IFINFO && ifm->ifm_data.ifi_type == IFT_ETHER) + { + ifdata = ifm->ifm_data; + entry->dwMtu = ifdata.ifi_mtu; + entry->dwSpeed = ifdata.ifi_baudrate; + entry->dwInOctets = ifdata.ifi_ibytes; + entry->dwInErrors = ifdata.ifi_ierrors; + entry->dwInDiscards = ifdata.ifi_iqdrops; + entry->dwInUcastPkts = ifdata.ifi_ipackets; + entry->dwInNUcastPkts = ifdata.ifi_imcasts; + entry->dwOutOctets = ifdata.ifi_obytes; + entry->dwOutUcastPkts = ifdata.ifi_opackets; + entry->dwOutErrors = ifdata.ifi_oerrors; + ret = NO_ERROR; + break; + } } - } + done: + HeapFree (GetProcessHeap (), 0, buf); } - fclose(fp); - } - else - { - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; - } - - return NO_ERROR; +#else + FIXME( "unimplemented\n" ); #endif + return ret; } -DWORD getIPStats(PMIB_IPSTATS stats) + +/****************************************************************** + * GetIcmpStatistics (IPHLPAPI.@) + * + * Get the ICMP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for ICMP statistics + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetIcmpStatistics(PMIB_ICMP stats) { -#if defined(HAVE_SYS_SYSCTL_H) && defined(IPCTL_STATS) - int mib[] = {CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS}; -#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) - int ip_ttl, ip_forwarding; - struct ipstat ip_stat; - size_t needed; - - if (!stats) - return ERROR_INVALID_PARAMETER; - - needed = sizeof(ip_stat); - if(sysctl(mib, MIB_LEN, &ip_stat, &needed, NULL, 0) == -1) - { - ERR ("failed to get ipstat\n"); - return ERROR_NOT_SUPPORTED; - } - - needed = sizeof(ip_ttl); - if (sysctlbyname ("net.inet.ip.ttl", &ip_ttl, &needed, NULL, 0) == -1) - { - ERR ("failed to get ip Default TTL\n"); - return ERROR_NOT_SUPPORTED; - } - - needed = sizeof(ip_forwarding); - if (sysctlbyname ("net.inet.ip.forwarding", &ip_forwarding, &needed, NULL, 0) == -1) - { - ERR ("failed to get ip forwarding\n"); - return ERROR_NOT_SUPPORTED; - } - - stats->dwForwarding = ip_forwarding; - stats->dwDefaultTTL = ip_ttl; - stats->dwInDelivers = ip_stat.ips_delivered; - stats->dwInHdrErrors = ip_stat.ips_badhlen + ip_stat.ips_badsum + ip_stat.ips_tooshort + ip_stat.ips_badlen; - stats->dwInAddrErrors = ip_stat.ips_cantforward; - stats->dwInReceives = ip_stat.ips_total; - stats->dwForwDatagrams = ip_stat.ips_forward; - stats->dwInUnknownProtos = ip_stat.ips_noproto; - stats->dwInDiscards = ip_stat.ips_fragdropped; - stats->dwOutDiscards = ip_stat.ips_odropped; - stats->dwReasmOks = ip_stat.ips_reassembled; - stats->dwFragOks = ip_stat.ips_fragmented; - stats->dwFragFails = ip_stat.ips_cantfrag; - stats->dwReasmTimeout = ip_stat.ips_fragtimeout; - stats->dwOutNoRoutes = ip_stat.ips_noroute; - stats->dwOutRequests = ip_stat.ips_localout; - stats->dwReasmReqds = ip_stat.ips_fragments; - - return NO_ERROR; -#else - FILE *fp; - MIB_IPFORWARDTABLE *fwd_table; - - if (!stats) - return ERROR_INVALID_PARAMETER; - - memset(stats, 0, sizeof(MIB_IPSTATS)); - stats->dwNumIf = stats->dwNumAddr = getNumInterfaces(); - if (!AllocateAndGetIpForwardTableFromStack( &fwd_table, FALSE, GetProcessHeap(), 0 )) - { - stats->dwNumRoutes = fwd_table->dwNumEntries; - HeapFree( GetProcessHeap(), 0, fwd_table ); - } - - /* get most of these stats from /proc/net/snmp, no error if can't */ - fp = fopen("/proc/net/snmp", "r"); - if (fp) { - static const char hdr[] = "Ip:"; - char buf[512] = { 0 }, *ptr; - - do { - ptr = fgets(buf, sizeof(buf), fp); - } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1)); - if (ptr) { - /* last line was a header, get another */ - ptr = fgets(buf, sizeof(buf), fp); - if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) { - char *endPtr; - - ptr += sizeof(hdr); - if (ptr && *ptr) { - stats->dwForwarding = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwDefaultTTL = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInReceives = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInHdrErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInAddrErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwForwDatagrams = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInUnknownProtos = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInDiscards = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInDelivers = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwOutRequests = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwOutDiscards = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwOutNoRoutes = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwReasmTimeout = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwReasmReqds = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwReasmOks = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + DWORD ret = ERROR_NOT_SUPPORTED; + + if (!stats) return ERROR_INVALID_PARAMETER; + memset( stats, 0, sizeof(MIB_ICMP) ); + +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen("/proc/net/snmp", "r"))) + { + static const char hdr[] = "Icmp:"; + char buf[512], *ptr; + + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + if (strncasecmp(buf, hdr, sizeof(hdr) - 1)) continue; + /* last line was a header, get another */ + if (!(ptr = fgets(buf, sizeof(buf), fp))) break; + if (!strncasecmp(buf, hdr, sizeof(hdr) - 1)) + { + ptr += sizeof(hdr); + sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u", + &stats->stats.icmpInStats.dwMsgs, + &stats->stats.icmpInStats.dwErrors, + &stats->stats.icmpInStats.dwDestUnreachs, + &stats->stats.icmpInStats.dwTimeExcds, + &stats->stats.icmpInStats.dwParmProbs, + &stats->stats.icmpInStats.dwSrcQuenchs, + &stats->stats.icmpInStats.dwRedirects, + &stats->stats.icmpInStats.dwEchoReps, + &stats->stats.icmpInStats.dwTimestamps, + &stats->stats.icmpInStats.dwTimestampReps, + &stats->stats.icmpInStats.dwAddrMasks, + &stats->stats.icmpInStats.dwAddrMaskReps, + &stats->stats.icmpOutStats.dwMsgs, + &stats->stats.icmpOutStats.dwErrors, + &stats->stats.icmpOutStats.dwDestUnreachs, + &stats->stats.icmpOutStats.dwTimeExcds, + &stats->stats.icmpOutStats.dwParmProbs, + &stats->stats.icmpOutStats.dwSrcQuenchs, + &stats->stats.icmpOutStats.dwRedirects, + &stats->stats.icmpOutStats.dwEchoReps, + &stats->stats.icmpOutStats.dwTimestamps, + &stats->stats.icmpOutStats.dwTimestampReps, + &stats->stats.icmpOutStats.dwAddrMasks, + &stats->stats.icmpOutStats.dwAddrMaskReps ); + break; + } + } + fclose(fp); + ret = NO_ERROR; } - if (ptr && *ptr) { - stats->dwReasmFails = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + } +#elif defined(HAVE_LIBKSTAT) + { + static char ip[] = "ip", icmp[] = "icmp"; + kstat_ctl_t *kc; + kstat_t *ksp; + + if ((kc = kstat_open()) && + (ksp = kstat_lookup( kc, ip, 0, icmp )) && + kstat_read( kc, ksp, NULL ) != -1 && + ksp->ks_type == KSTAT_TYPE_NAMED) + { + stats->stats.icmpInStats.dwMsgs = kstat_get_ui32( ksp, "inMsgs" ); + stats->stats.icmpInStats.dwErrors = kstat_get_ui32( ksp, "inErrors" ); + stats->stats.icmpInStats.dwDestUnreachs = kstat_get_ui32( ksp, "inDestUnreachs" ); + stats->stats.icmpInStats.dwTimeExcds = kstat_get_ui32( ksp, "inTimeExcds" ); + stats->stats.icmpInStats.dwParmProbs = kstat_get_ui32( ksp, "inParmProbs" ); + stats->stats.icmpInStats.dwSrcQuenchs = kstat_get_ui32( ksp, "inSrcQuenchs" ); + stats->stats.icmpInStats.dwRedirects = kstat_get_ui32( ksp, "inRedirects" ); + stats->stats.icmpInStats.dwEchos = kstat_get_ui32( ksp, "inEchos" ); + stats->stats.icmpInStats.dwEchoReps = kstat_get_ui32( ksp, "inEchoReps" ); + stats->stats.icmpInStats.dwTimestamps = kstat_get_ui32( ksp, "inTimestamps" ); + stats->stats.icmpInStats.dwTimestampReps = kstat_get_ui32( ksp, "inTimestampReps" ); + stats->stats.icmpInStats.dwAddrMasks = kstat_get_ui32( ksp, "inAddrMasks" ); + stats->stats.icmpInStats.dwAddrMaskReps = kstat_get_ui32( ksp, "inAddrMaskReps" ); + stats->stats.icmpOutStats.dwMsgs = kstat_get_ui32( ksp, "outMsgs" ); + stats->stats.icmpOutStats.dwErrors = kstat_get_ui32( ksp, "outErrors" ); + stats->stats.icmpOutStats.dwDestUnreachs = kstat_get_ui32( ksp, "outDestUnreachs" ); + stats->stats.icmpOutStats.dwTimeExcds = kstat_get_ui32( ksp, "outTimeExcds" ); + stats->stats.icmpOutStats.dwParmProbs = kstat_get_ui32( ksp, "outParmProbs" ); + stats->stats.icmpOutStats.dwSrcQuenchs = kstat_get_ui32( ksp, "outSrcQuenchs" ); + stats->stats.icmpOutStats.dwRedirects = kstat_get_ui32( ksp, "outRedirects" ); + stats->stats.icmpOutStats.dwEchos = kstat_get_ui32( ksp, "outEchos" ); + stats->stats.icmpOutStats.dwEchoReps = kstat_get_ui32( ksp, "outEchoReps" ); + stats->stats.icmpOutStats.dwTimestamps = kstat_get_ui32( ksp, "outTimestamps" ); + stats->stats.icmpOutStats.dwTimestampReps = kstat_get_ui32( ksp, "outTimestampReps" ); + stats->stats.icmpOutStats.dwAddrMasks = kstat_get_ui32( ksp, "outAddrMasks" ); + stats->stats.icmpOutStats.dwAddrMaskReps = kstat_get_ui32( ksp, "outAddrMaskReps" ); + ret = NO_ERROR; + } + if (kc) kstat_close( kc ); + } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(ICMPCTL_STATS) + { + int mib[] = {CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS}; +#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) + struct icmpstat icmp_stat; + size_t needed = sizeof(icmp_stat); + int i; + + if(sysctl(mib, MIB_LEN, &icmp_stat, &needed, NULL, 0) != -1) + { + /*in stats */ + stats->stats.icmpInStats.dwMsgs = icmp_stat.icps_badcode + icmp_stat.icps_checksum + icmp_stat.icps_tooshort + icmp_stat.icps_badlen; + for(i = 0; i <= ICMP_MAXTYPE; i++) + stats->stats.icmpInStats.dwMsgs += icmp_stat.icps_inhist[i]; + + stats->stats.icmpInStats.dwErrors = icmp_stat.icps_badcode + icmp_stat.icps_tooshort + icmp_stat.icps_checksum + icmp_stat.icps_badlen; + + stats->stats.icmpInStats.dwDestUnreachs = icmp_stat.icps_inhist[ICMP_UNREACH]; + stats->stats.icmpInStats.dwTimeExcds = icmp_stat.icps_inhist[ICMP_TIMXCEED]; + stats->stats.icmpInStats.dwParmProbs = icmp_stat.icps_inhist[ICMP_PARAMPROB]; + stats->stats.icmpInStats.dwSrcQuenchs = icmp_stat.icps_inhist[ICMP_SOURCEQUENCH]; + stats->stats.icmpInStats.dwRedirects = icmp_stat.icps_inhist[ICMP_REDIRECT]; + stats->stats.icmpInStats.dwEchos = icmp_stat.icps_inhist[ICMP_ECHO]; + stats->stats.icmpInStats.dwEchoReps = icmp_stat.icps_inhist[ICMP_ECHOREPLY]; + stats->stats.icmpInStats.dwTimestamps = icmp_stat.icps_inhist[ICMP_TSTAMP]; + stats->stats.icmpInStats.dwTimestampReps = icmp_stat.icps_inhist[ICMP_TSTAMPREPLY]; + stats->stats.icmpInStats.dwAddrMasks = icmp_stat.icps_inhist[ICMP_MASKREQ]; + stats->stats.icmpInStats.dwAddrMaskReps = icmp_stat.icps_inhist[ICMP_MASKREPLY]; + +#ifdef HAVE_ICPS_OUTHIST + /* out stats */ + stats->stats.icmpOutStats.dwMsgs = icmp_stat.icps_oldshort + icmp_stat.icps_oldicmp; + for(i = 0; i <= ICMP_MAXTYPE; i++) + stats->stats.icmpOutStats.dwMsgs += icmp_stat.icps_outhist[i]; + + stats->stats.icmpOutStats.dwErrors = icmp_stat.icps_oldshort + icmp_stat.icps_oldicmp; + + stats->stats.icmpOutStats.dwDestUnreachs = icmp_stat.icps_outhist[ICMP_UNREACH]; + stats->stats.icmpOutStats.dwTimeExcds = icmp_stat.icps_outhist[ICMP_TIMXCEED]; + stats->stats.icmpOutStats.dwParmProbs = icmp_stat.icps_outhist[ICMP_PARAMPROB]; + stats->stats.icmpOutStats.dwSrcQuenchs = icmp_stat.icps_outhist[ICMP_SOURCEQUENCH]; + stats->stats.icmpOutStats.dwRedirects = icmp_stat.icps_outhist[ICMP_REDIRECT]; + stats->stats.icmpOutStats.dwEchos = icmp_stat.icps_outhist[ICMP_ECHO]; + stats->stats.icmpOutStats.dwEchoReps = icmp_stat.icps_outhist[ICMP_ECHOREPLY]; + stats->stats.icmpOutStats.dwTimestamps = icmp_stat.icps_outhist[ICMP_TSTAMP]; + stats->stats.icmpOutStats.dwTimestampReps = icmp_stat.icps_outhist[ICMP_TSTAMPREPLY]; + stats->stats.icmpOutStats.dwAddrMasks = icmp_stat.icps_outhist[ICMP_MASKREQ]; + stats->stats.icmpOutStats.dwAddrMaskReps = icmp_stat.icps_outhist[ICMP_MASKREPLY]; +#endif /* ICPS_OUTHIST */ + ret = NO_ERROR; } - if (ptr && *ptr) { - stats->dwFragOks = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + } +#else /* ICMPCTL_STATS */ + FIXME( "unimplemented\n" ); +#endif + return ret; +} + + +/****************************************************************** + * GetIpStatistics (IPHLPAPI.@) + * + * Get the IP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for IP statistics + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats) +{ + DWORD ret = ERROR_NOT_SUPPORTED; + MIB_IPFORWARDTABLE *fwd_table; + + if (!stats) return ERROR_INVALID_PARAMETER; + memset( stats, 0, sizeof(*stats) ); + + stats->dwNumIf = stats->dwNumAddr = getNumInterfaces(); + if (!AllocateAndGetIpForwardTableFromStack( &fwd_table, FALSE, GetProcessHeap(), 0 )) + { + stats->dwNumRoutes = fwd_table->dwNumEntries; + HeapFree( GetProcessHeap(), 0, fwd_table ); + } + +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen("/proc/net/snmp", "r"))) + { + static const char hdr[] = "Ip:"; + char buf[512], *ptr; + + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + if (strncasecmp(buf, hdr, sizeof(hdr) - 1)) continue; + /* last line was a header, get another */ + if (!(ptr = fgets(buf, sizeof(buf), fp))) break; + if (!strncasecmp(buf, hdr, sizeof(hdr) - 1)) + { + ptr += sizeof(hdr); + sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u", + &stats->dwForwarding, + &stats->dwDefaultTTL, + &stats->dwInReceives, + &stats->dwInHdrErrors, + &stats->dwInAddrErrors, + &stats->dwForwDatagrams, + &stats->dwInUnknownProtos, + &stats->dwInDiscards, + &stats->dwInDelivers, + &stats->dwOutRequests, + &stats->dwOutDiscards, + &stats->dwOutNoRoutes, + &stats->dwReasmTimeout, + &stats->dwReasmReqds, + &stats->dwReasmOks, + &stats->dwReasmFails, + &stats->dwFragOks, + &stats->dwFragFails, + &stats->dwFragCreates ); + /* hmm, no routingDiscards */ + break; + } + } + fclose(fp); + ret = NO_ERROR; } - if (ptr && *ptr) { - stats->dwFragFails = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + } +#elif defined(HAVE_LIBKSTAT) + { + static char ip[] = "ip"; + kstat_ctl_t *kc; + kstat_t *ksp; + + if ((kc = kstat_open()) && + (ksp = kstat_lookup( kc, ip, 0, ip )) && + kstat_read( kc, ksp, NULL ) != -1 && + ksp->ks_type == KSTAT_TYPE_NAMED) + { + stats->dwForwarding = kstat_get_ui32( ksp, "forwarding" ); + stats->dwDefaultTTL = kstat_get_ui32( ksp, "defaultTTL" ); + stats->dwInReceives = kstat_get_ui32( ksp, "inReceives" ); + stats->dwInHdrErrors = kstat_get_ui32( ksp, "inHdrErrors" ); + stats->dwInAddrErrors = kstat_get_ui32( ksp, "inAddrErrors" ); + stats->dwForwDatagrams = kstat_get_ui32( ksp, "forwDatagrams" ); + stats->dwInUnknownProtos = kstat_get_ui32( ksp, "inUnknownProtos" ); + stats->dwInDiscards = kstat_get_ui32( ksp, "inDiscards" ); + stats->dwInDelivers = kstat_get_ui32( ksp, "inDelivers" ); + stats->dwOutRequests = kstat_get_ui32( ksp, "outRequests" ); + stats->dwRoutingDiscards = kstat_get_ui32( ksp, "routingDiscards" ); + stats->dwOutDiscards = kstat_get_ui32( ksp, "outDiscards" ); + stats->dwOutNoRoutes = kstat_get_ui32( ksp, "outNoRoutes" ); + stats->dwReasmTimeout = kstat_get_ui32( ksp, "reasmTimeout" ); + stats->dwReasmReqds = kstat_get_ui32( ksp, "reasmReqds" ); + stats->dwReasmOks = kstat_get_ui32( ksp, "reasmOKs" ); + stats->dwReasmFails = kstat_get_ui32( ksp, "reasmFails" ); + stats->dwFragOks = kstat_get_ui32( ksp, "fragOKs" ); + stats->dwFragFails = kstat_get_ui32( ksp, "fragFails" ); + stats->dwFragCreates = kstat_get_ui32( ksp, "fragCreates" ); + ret = NO_ERROR; + } + if (kc) kstat_close( kc ); + } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(IPCTL_STATS) + { + int mib[] = {CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS}; +#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) + int ip_ttl, ip_forwarding; + struct ipstat ip_stat; + size_t needed; + + needed = sizeof(ip_stat); + if(sysctl(mib, MIB_LEN, &ip_stat, &needed, NULL, 0) == -1) + { + ERR ("failed to get ipstat\n"); + return ERROR_NOT_SUPPORTED; } - if (ptr && *ptr) { - stats->dwFragCreates = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + + needed = sizeof(ip_ttl); + if (sysctlbyname ("net.inet.ip.ttl", &ip_ttl, &needed, NULL, 0) == -1) + { + ERR ("failed to get ip Default TTL\n"); + return ERROR_NOT_SUPPORTED; } - /* hmm, no routingDiscards */ - } + + needed = sizeof(ip_forwarding); + if (sysctlbyname ("net.inet.ip.forwarding", &ip_forwarding, &needed, NULL, 0) == -1) + { + ERR ("failed to get ip forwarding\n"); + return ERROR_NOT_SUPPORTED; + } + + stats->dwForwarding = ip_forwarding; + stats->dwDefaultTTL = ip_ttl; + stats->dwInDelivers = ip_stat.ips_delivered; + stats->dwInHdrErrors = ip_stat.ips_badhlen + ip_stat.ips_badsum + ip_stat.ips_tooshort + ip_stat.ips_badlen; + stats->dwInAddrErrors = ip_stat.ips_cantforward; + stats->dwInReceives = ip_stat.ips_total; + stats->dwForwDatagrams = ip_stat.ips_forward; + stats->dwInUnknownProtos = ip_stat.ips_noproto; + stats->dwInDiscards = ip_stat.ips_fragdropped; + stats->dwOutDiscards = ip_stat.ips_odropped; + stats->dwReasmOks = ip_stat.ips_reassembled; + stats->dwFragOks = ip_stat.ips_fragmented; + stats->dwFragFails = ip_stat.ips_cantfrag; + stats->dwReasmTimeout = ip_stat.ips_fragtimeout; + stats->dwOutNoRoutes = ip_stat.ips_noroute; + stats->dwOutRequests = ip_stat.ips_localout; + stats->dwReasmReqds = ip_stat.ips_fragments; + ret = NO_ERROR; } - fclose(fp); - } - else - { - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; - } - - return NO_ERROR; +#else + FIXME( "unimplemented\n" ); #endif + return ret; } -DWORD getTCPStats(MIB_TCPSTATS *stats) + +/****************************************************************** + * GetTcpStatistics (IPHLPAPI.@) + * + * Get the TCP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for TCP statistics + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS stats) { -#if defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS) + DWORD ret = ERROR_NOT_SUPPORTED; + + if (!stats) return ERROR_INVALID_PARAMETER; + memset( stats, 0, sizeof(*stats) ); + +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen("/proc/net/snmp", "r"))) + { + static const char hdr[] = "Tcp:"; + MIB_TCPTABLE *tcp_table; + char buf[512], *ptr; + + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + if (strncasecmp(buf, hdr, sizeof(hdr) - 1)) continue; + /* last line was a header, get another */ + if (!(ptr = fgets(buf, sizeof(buf), fp))) break; + if (!strncasecmp(buf, hdr, sizeof(hdr) - 1)) + { + ptr += sizeof(hdr); + sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u", + &stats->dwRtoAlgorithm, + &stats->dwRtoMin, + &stats->dwRtoMax, + &stats->dwMaxConn, + &stats->dwActiveOpens, + &stats->dwPassiveOpens, + &stats->dwAttemptFails, + &stats->dwEstabResets, + &stats->dwCurrEstab, + &stats->dwInSegs, + &stats->dwOutSegs, + &stats->dwRetransSegs, + &stats->dwInErrs, + &stats->dwOutRsts ); + break; + } + } + if (!AllocateAndGetTcpTableFromStack( &tcp_table, FALSE, GetProcessHeap(), 0 )) + { + stats->dwNumConns = tcp_table->dwNumEntries; + HeapFree( GetProcessHeap(), 0, tcp_table ); + } + fclose(fp); + ret = NO_ERROR; + } + } +#elif defined(HAVE_LIBKSTAT) + { + static char tcp[] = "tcp"; + kstat_ctl_t *kc; + kstat_t *ksp; + + if ((kc = kstat_open()) && + (ksp = kstat_lookup( kc, tcp, 0, tcp )) && + kstat_read( kc, ksp, NULL ) != -1 && + ksp->ks_type == KSTAT_TYPE_NAMED) + { + stats->dwRtoAlgorithm = kstat_get_ui32( ksp, "rtoAlgorithm" ); + stats->dwRtoMin = kstat_get_ui32( ksp, "rtoMin" ); + stats->dwRtoMax = kstat_get_ui32( ksp, "rtoMax" ); + stats->dwMaxConn = kstat_get_ui32( ksp, "maxConn" ); + stats->dwActiveOpens = kstat_get_ui32( ksp, "activeOpens" ); + stats->dwPassiveOpens = kstat_get_ui32( ksp, "passiveOpens" ); + stats->dwAttemptFails = kstat_get_ui32( ksp, "attemptFails" ); + stats->dwEstabResets = kstat_get_ui32( ksp, "estabResets" ); + stats->dwCurrEstab = kstat_get_ui32( ksp, "currEstab" ); + stats->dwInSegs = kstat_get_ui32( ksp, "inSegs" ); + stats->dwOutSegs = kstat_get_ui32( ksp, "outSegs" ); + stats->dwRetransSegs = kstat_get_ui32( ksp, "retransSegs" ); + stats->dwInErrs = kstat_get_ui32( ksp, "inErrs" ); + stats->dwOutRsts = kstat_get_ui32( ksp, "outRsts" ); + stats->dwNumConns = kstat_get_ui32( ksp, "connTableSize" ); + ret = NO_ERROR; + } + if (kc) kstat_close( kc ); + } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS) + { #ifndef TCPTV_MIN /* got removed in Mac OS X for some reason */ #define TCPTV_MIN 2 #define TCPTV_REXMTMAX 128 #endif - int mib[] = {CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS}; + int mib[] = {CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS}; #define MIB_LEN (sizeof(mib) / sizeof(mib[0])) #define hz 1000 - struct tcpstat tcp_stat; - size_t needed; - - if (!stats) - return ERROR_INVALID_PARAMETER; - needed = sizeof(tcp_stat); - - if(sysctl(mib, MIB_LEN, &tcp_stat, &needed, NULL, 0) == -1) - { - ERR ("failed to get tcpstat\n"); - return ERROR_NOT_SUPPORTED; - } - - stats->dwRtoAlgorithm = MIB_TCP_RTO_VANJ; - stats->dwRtoMin = TCPTV_MIN; - stats->dwRtoMax = TCPTV_REXMTMAX; - stats->dwMaxConn = -1; - stats->dwActiveOpens = tcp_stat.tcps_connattempt; - stats->dwPassiveOpens = tcp_stat.tcps_accepts; - stats->dwAttemptFails = tcp_stat.tcps_conndrops; - stats->dwEstabResets = tcp_stat.tcps_drops; - stats->dwCurrEstab = 0; - stats->dwInSegs = tcp_stat.tcps_rcvtotal; - stats->dwOutSegs = tcp_stat.tcps_sndtotal - tcp_stat.tcps_sndrexmitpack; - stats->dwRetransSegs = tcp_stat.tcps_sndrexmitpack; - stats->dwInErrs = tcp_stat.tcps_rcvbadsum + tcp_stat.tcps_rcvbadoff + tcp_stat.tcps_rcvmemdrop + tcp_stat.tcps_rcvshort; - stats->dwOutRsts = tcp_stat.tcps_sndctrl - tcp_stat.tcps_closed; - stats->dwNumConns = tcp_stat.tcps_connects; - - return NO_ERROR; + struct tcpstat tcp_stat; + size_t needed = sizeof(tcp_stat); -#else - FILE *fp; - MIB_TCPTABLE *tcp_table; - - if (!stats) - return ERROR_INVALID_PARAMETER; - - memset(stats, 0, sizeof(MIB_TCPSTATS)); - - /* get from /proc/net/snmp, no error if can't */ - fp = fopen("/proc/net/snmp", "r"); - if (fp) { - static const char hdr[] = "Tcp:"; - char buf[512] = { 0 }, *ptr; - - - do { - ptr = fgets(buf, sizeof(buf), fp); - } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1)); - if (ptr) { - /* last line was a header, get another */ - ptr = fgets(buf, sizeof(buf), fp); - if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) { - char *endPtr; - - ptr += sizeof(hdr); - if (ptr && *ptr) { - stats->dwRtoAlgorithm = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwRtoMin = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwRtoMax = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwMaxConn = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwActiveOpens = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwPassiveOpens = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwAttemptFails = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwEstabResets = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwCurrEstab = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInSegs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwOutSegs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwRetransSegs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInErrs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwOutRsts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (!AllocateAndGetTcpTableFromStack( &tcp_table, FALSE, GetProcessHeap(), 0 )) + if(sysctl(mib, MIB_LEN, &tcp_stat, &needed, NULL, 0) != -1) { - stats->dwNumConns = tcp_table->dwNumEntries; - HeapFree( GetProcessHeap(), 0, tcp_table ); - } - } + stats->dwRtoAlgorithm = MIB_TCP_RTO_VANJ; + stats->dwRtoMin = TCPTV_MIN; + stats->dwRtoMax = TCPTV_REXMTMAX; + stats->dwMaxConn = -1; + stats->dwActiveOpens = tcp_stat.tcps_connattempt; + stats->dwPassiveOpens = tcp_stat.tcps_accepts; + stats->dwAttemptFails = tcp_stat.tcps_conndrops; + stats->dwEstabResets = tcp_stat.tcps_drops; + stats->dwCurrEstab = 0; + stats->dwInSegs = tcp_stat.tcps_rcvtotal; + stats->dwOutSegs = tcp_stat.tcps_sndtotal - tcp_stat.tcps_sndrexmitpack; + stats->dwRetransSegs = tcp_stat.tcps_sndrexmitpack; + stats->dwInErrs = tcp_stat.tcps_rcvbadsum + tcp_stat.tcps_rcvbadoff + tcp_stat.tcps_rcvmemdrop + tcp_stat.tcps_rcvshort; + stats->dwOutRsts = tcp_stat.tcps_sndctrl - tcp_stat.tcps_closed; + stats->dwNumConns = tcp_stat.tcps_connects; + ret = NO_ERROR; + } + else ERR ("failed to get tcpstat\n"); } - fclose(fp); - } - else - { - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; - } - - return NO_ERROR; +#else + FIXME( "unimplemented\n" ); #endif + return ret; } -DWORD getUDPStats(MIB_UDPSTATS *stats) -{ -#if defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS) - int mib[] = {CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS}; -#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) - struct udpstat udp_stat; - MIB_UDPTABLE *udp_table; - size_t needed; - if (!stats) - return ERROR_INVALID_PARAMETER; - - needed = sizeof(udp_stat); - - if(sysctl(mib, MIB_LEN, &udp_stat, &needed, NULL, 0) == -1) - { - ERR ("failed to get udpstat\n"); - return ERROR_NOT_SUPPORTED; - } - - stats->dwInDatagrams = udp_stat.udps_ipackets; - stats->dwOutDatagrams = udp_stat.udps_opackets; - stats->dwNoPorts = udp_stat.udps_noport; - stats->dwInErrors = udp_stat.udps_hdrops + udp_stat.udps_badsum + udp_stat.udps_fullsock + udp_stat.udps_badlen; - if (!AllocateAndGetUdpTableFromStack( &udp_table, FALSE, GetProcessHeap(), 0 )) - { - stats->dwNumAddrs = udp_table->dwNumEntries; - HeapFree( GetProcessHeap(), 0, udp_table ); - } - else stats->dwNumAddrs = 0; - - return NO_ERROR; -#else - FILE *fp; - - if (!stats) - return ERROR_INVALID_PARAMETER; - memset(stats, 0, sizeof(MIB_UDPSTATS)); +/****************************************************************** + * GetUdpStatistics (IPHLPAPI.@) + * + * Get the UDP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for UDP statistics + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS stats) +{ + DWORD ret = ERROR_NOT_SUPPORTED; - /* get from /proc/net/snmp, no error if can't */ - fp = fopen("/proc/net/snmp", "r"); - if (fp) { - static const char hdr[] = "Udp:"; - char buf[512] = { 0 }, *ptr; + if (!stats) return ERROR_INVALID_PARAMETER; + memset( stats, 0, sizeof(*stats) ); +#ifdef __linux__ + { + FILE *fp; - do { - ptr = fgets(buf, sizeof(buf), fp); - } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1)); - if (ptr) { - /* last line was a header, get another */ - ptr = fgets(buf, sizeof(buf), fp); - if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) { - char *endPtr; + if ((fp = fopen("/proc/net/snmp", "r"))) + { + static const char hdr[] = "Udp:"; + char buf[512], *ptr; - ptr += sizeof(hdr); - if (ptr && *ptr) { - stats->dwInDatagrams = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwNoPorts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - stats->dwInErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + if (strncasecmp(buf, hdr, sizeof(hdr) - 1)) continue; + /* last line was a header, get another */ + if (!(ptr = fgets(buf, sizeof(buf), fp))) break; + if (!strncasecmp(buf, hdr, sizeof(hdr) - 1)) + { + ptr += sizeof(hdr); + sscanf( ptr, "%u %u %u %u %u", + &stats->dwInDatagrams, &stats->dwNoPorts, + &stats->dwInErrors, &stats->dwOutDatagrams, &stats->dwNumAddrs ); + break; + } + } + fclose(fp); + ret = NO_ERROR; } - if (ptr && *ptr) { - stats->dwOutDatagrams = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + } +#elif defined(HAVE_LIBKSTAT) + { + static char udp[] = "udp"; + kstat_ctl_t *kc; + kstat_t *ksp; + MIB_UDPTABLE *udp_table; + + if ((kc = kstat_open()) && + (ksp = kstat_lookup( kc, udp, 0, udp )) && + kstat_read( kc, ksp, NULL ) != -1 && + ksp->ks_type == KSTAT_TYPE_NAMED) + { + stats->dwInDatagrams = kstat_get_ui32( ksp, "inDatagrams" ); + stats->dwNoPorts = 0; /* FIXME */ + stats->dwInErrors = kstat_get_ui32( ksp, "inErrors" ); + stats->dwOutDatagrams = kstat_get_ui32( ksp, "outDatagrams" ); + if (!AllocateAndGetUdpTableFromStack( &udp_table, FALSE, GetProcessHeap(), 0 )) + { + stats->dwNumAddrs = udp_table->dwNumEntries; + HeapFree( GetProcessHeap(), 0, udp_table ); + } + ret = NO_ERROR; } - if (ptr && *ptr) { - stats->dwNumAddrs = strtoul(ptr, &endPtr, 10); - ptr = endPtr; + if (kc) kstat_close( kc ); + } +#elif defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS) + { + int mib[] = {CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS}; +#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) + struct udpstat udp_stat; + MIB_UDPTABLE *udp_table; + size_t needed = sizeof(udp_stat); + + if(sysctl(mib, MIB_LEN, &udp_stat, &needed, NULL, 0) != -1) + { + stats->dwInDatagrams = udp_stat.udps_ipackets; + stats->dwOutDatagrams = udp_stat.udps_opackets; + stats->dwNoPorts = udp_stat.udps_noport; + stats->dwInErrors = udp_stat.udps_hdrops + udp_stat.udps_badsum + udp_stat.udps_fullsock + udp_stat.udps_badlen; + if (!AllocateAndGetUdpTableFromStack( &udp_table, FALSE, GetProcessHeap(), 0 )) + { + stats->dwNumAddrs = udp_table->dwNumEntries; + HeapFree( GetProcessHeap(), 0, udp_table ); + } + ret = NO_ERROR; } - } + else ERR ("failed to get udpstat\n"); } - fclose(fp); - } - else - { - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; - } - - return NO_ERROR; +#else + FIXME( "unimplemented\n" ); #endif + return ret; } diff --git a/dlls/iphlpapi/ipstats.h b/dlls/iphlpapi/ipstats.h index aad931c4ba5..d7aeb658cfa 100644 --- a/dlls/iphlpapi/ipstats.h +++ b/dlls/iphlpapi/ipstats.h @@ -32,26 +32,6 @@ */ DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry); -/* Gets ICMP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is - * NULL, NO_ERROR otherwise. - */ -DWORD getICMPStats(MIB_ICMP *stats); - -/* Gets IP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is - * NULL, NO_ERROR otherwise. - */ -DWORD getIPStats(PMIB_IPSTATS stats); - -/* Gets TCP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is - * NULL, NO_ERROR otherwise. - */ -DWORD getTCPStats(MIB_TCPSTATS *stats); - -/* Gets UDP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is - * NULL, NO_ERROR otherwise. - */ -DWORD getUDPStats(MIB_UDPSTATS *stats); - DWORD WINAPI AllocateAndGetUdpTableFromStack(PMIB_UDPTABLE *ppUdpTable, BOOL bOrder, HANDLE heap, DWORD flags); DWORD WINAPI AllocateAndGetTcpTableFromStack(PMIB_TCPTABLE *ppTcpTable, BOOL bOrder, HANDLE heap, DWORD flags); DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable, BOOL bOrder, HANDLE heap, DWORD flags); diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 23f85ece3f0..8e36858bc38 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -424,15 +424,11 @@ static void testGetTcpTable(void) DWORD apiReturn; ULONG dwSize = 0; - apiReturn = gGetTcpTable(NULL, NULL, FALSE); + apiReturn = gGetTcpTable(NULL, &dwSize, FALSE); if (apiReturn == ERROR_NOT_SUPPORTED) { skip("GetTcpTable is not supported\n"); return; } - ok(apiReturn == ERROR_INVALID_PARAMETER, - "GetTcpTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n", - apiReturn); - apiReturn = gGetTcpTable(NULL, &dwSize, FALSE); ok(apiReturn == ERROR_INSUFFICIENT_BUFFER || broken(apiReturn == ERROR_NO_DATA), /* win95 */ "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n", @@ -455,15 +451,11 @@ static void testGetUdpTable(void) DWORD apiReturn; ULONG dwSize = 0; - apiReturn = gGetUdpTable(NULL, NULL, FALSE); + apiReturn = gGetUdpTable(NULL, &dwSize, FALSE); if (apiReturn == ERROR_NOT_SUPPORTED) { skip("GetUdpTable is not supported\n"); return; } - ok(apiReturn == ERROR_INVALID_PARAMETER, - "GetUdpTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n", - apiReturn); - apiReturn = gGetUdpTable(NULL, &dwSize, FALSE); ok(apiReturn == ERROR_INSUFFICIENT_BUFFER, "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n", apiReturn); diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in index 49e6caf8966..d7b91d3a03f 100644 --- a/dlls/kernel32/Makefile.in +++ b/dlls/kernel32/Makefile.in @@ -10,13 +10,9 @@ EXTRALIBS = @COREFOUNDATIONLIB@ @LIBPOLL@ EXTRADLLFLAGS = -Wb,-F,KERNEL32.dll -Wl,--image-base,0x7b800000 SPEC_SRCS16 = \ - comm.drv.spec \ krnl386.exe.spec \ - stress.spec \ system.drv.spec \ - toolhelp.spec \ - win87em.spec \ - windebug.spec + toolhelp.spec C_SRCS = \ actctx.c \ @@ -56,7 +52,6 @@ C_SRCS = \ resource16.c \ selector.c \ snoop16.c \ - stress.c \ string.c \ sync.c \ syslevel.c \ @@ -72,7 +67,6 @@ C_SRCS = \ virtual.c \ volume.c \ vxd.c \ - windebug.c \ wowthunk.c C_SRCS16 = \ @@ -80,8 +74,7 @@ C_SRCS16 = \ error16.c \ kernel16.c \ registry16.c \ - toolhelp16.c \ - win87em.c + toolhelp16.c RC_SRCS = kernel.rc diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index be96633af4d..38002d7c584 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -2230,7 +2230,8 @@ BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOf return TRUE; } - SetLastError( RtlNtStatusToDosError(status) ); + if (status == STATUS_TIMEOUT) SetLastError( WAIT_TIMEOUT ); + else SetLastError( RtlNtStatusToDosError(status) ); return FALSE; } diff --git a/dlls/kernel32/tests/atom.c b/dlls/kernel32/tests/atom.c index cae36011984..c7398500ab9 100644 --- a/dlls/kernel32/tests/atom.c +++ b/dlls/kernel32/tests/atom.c @@ -201,6 +201,7 @@ static void test_get_atom_name(void) sprintf( res, "#%d", i ); memset( res + strlen(res) + 1, 'a', 10 ); ok( !memcmp( res, buf, 10 ), "bad buffer contents %s\n", buf ); + if (len <= 1 || len >= 7) break; /* don't bother testing all of them */ } else ok( !len, "bad length %d\n", len ); @@ -283,6 +284,7 @@ static void test_get_atom_name(void) print_integral( res, i ); memset( res + lstrlenW(res) + 1, 'a', 10 * sizeof(WCHAR)); ok( !memcmp( res, outW, 10 * sizeof(WCHAR) ), "bad buffer contents for %d\n", i ); + if (len <= 1 || len >= 7) break; /* don't bother testing all of them */ } else ok( !len, "bad length %d\n", len ); diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index fa94679724c..a54ff5cdda4 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -942,7 +942,8 @@ START_TEST(console) ok(hConIn != INVALID_HANDLE_VALUE, "Opening ConIn\n"); ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n"); - ok(ret = GetConsoleScreenBufferInfo(hConOut, &sbi), "Getting sb info\n"); + ret = GetConsoleScreenBufferInfo(hConOut, &sbi); + ok(ret, "Getting sb info\n"); if (!ret) return; /* Non interactive tests */ diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 48d9e14279e..51197ecdd55 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -629,6 +629,113 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) return 0; } +/** Trivial byte echo server - uses i/o completion ports */ +static DWORD CALLBACK serverThreadMain4(LPVOID arg) +{ + int i; + HANDLE hcompletion; + + trace("serverThreadMain4\n"); + /* Set up a simple echo server */ + hnp = CreateNamedPipe(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_WAIT, + /* nMaxInstances */ 1, + /* nOutBufSize */ 1024, + /* nInBufSize */ 1024, + /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, + /* lpSecurityAttrib */ NULL); + ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); + + hcompletion = CreateIoCompletionPort(hnp, NULL, 12345, 1); + ok(hcompletion != NULL, "CreateIoCompletionPort failed, error=%i\n", GetLastError()); + + for (i = 0; i < NB_SERVER_LOOPS; i++) { + char buf[512]; + DWORD written; + DWORD readden; + DWORD dummy; + DWORD success; + OVERLAPPED oConnect; + OVERLAPPED oRead; + OVERLAPPED oWrite; + OVERLAPPED *oResult; + DWORD err; + ULONG_PTR compkey; + + memset(&oConnect, 0, sizeof(oConnect)); + memset(&oRead, 0, sizeof(oRead)); + memset(&oWrite, 0, sizeof(oWrite)); + + /* Wait for client to connect */ + trace("Server calling overlapped ConnectNamedPipe...\n"); + success = ConnectNamedPipe(hnp, &oConnect); + err = GetLastError(); + ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), + "overlapped ConnectNamedPipe got %u err %u\n", success, err ); + if (!success && err == ERROR_IO_PENDING) { + trace("ConnectNamedPipe GetQueuedCompletionStatus\n"); + success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0); + if (!success) + { + ok( GetLastError() == WAIT_TIMEOUT, + "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError()); + success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 10000); + } + ok(success, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError()); + if (success) + { + ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); + ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect); + } + } + trace("overlapped ConnectNamedPipe operation complete.\n"); + + /* Echo bytes once */ + memset(buf, 0, sizeof(buf)); + + trace("Server reading...\n"); + success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); + trace("Server ReadFile returned...\n"); + err = GetLastError(); + ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%i\n", err); + success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, + &oResult, 10000); + ok(success, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError()); + if (success) + { + ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); + ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead); + } + trace("Server done reading.\n"); + + trace("Server writing...\n"); + success = WriteFile(hnp, buf, readden, &written, &oWrite); + trace("Server WriteFile returned...\n"); + err = GetLastError(); + ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%u\n", err); + success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, + &oResult, 10000); + ok(success, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError()); + if (success) + { + ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); + ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite); + ok(written == readden, "write file len\n"); + } + trace("Server done writing.\n"); + + /* finish this connection, wait for next one */ + ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); + success = DisconnectNamedPipe(hnp); + ok(success, "DisconnectNamedPipe failed, err %u\n", GetLastError()); + } + + ok(CloseHandle(hnp), "CloseHandle named pipe failed, err=%i\n", GetLastError()); + ok(CloseHandle(hcompletion), "CloseHandle completion failed, err=%i\n", GetLastError()); + + return 0; +} + static void exercizeServer(const char *pipename, HANDLE serverThread) { int i; @@ -711,6 +818,11 @@ static void test_NamedPipe_2(void) ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n"); exercizeServer(PIPENAME "serverThreadMain3", serverThread); + /* Try server #4 */ + serverThread = CreateThread(NULL, 0, serverThreadMain4, 0, 0, &serverThreadId); + ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n"); + exercizeServer(PIPENAME "serverThreadMain4", serverThread); + ok(SetEvent( alarm_event ), "SetEvent\n"); CloseHandle( alarm_event ); trace("test_NamedPipe_2 returning\n"); diff --git a/dlls/kernel32/win87em.spec b/dlls/kernel32/win87em.spec deleted file mode 100644 index 968063e6624..00000000000 --- a/dlls/kernel32/win87em.spec +++ /dev/null @@ -1,4 +0,0 @@ -1 pascal -register _fpMath() WIN87_fpmath -3 pascal -ret16 __WinEm87Info(ptr word) WIN87_WinEm87Info -4 pascal -ret16 __WinEm87Restore(ptr word) WIN87_WinEm87Restore -5 pascal -ret16 __WinEm87Save(ptr word) WIN87_WinEm87Save diff --git a/dlls/keyboard.drv16/Makefile.in b/dlls/keyboard.drv16/Makefile.in new file mode 100644 index 00000000000..ef8c36c4ecd --- /dev/null +++ b/dlls/keyboard.drv16/Makefile.in @@ -0,0 +1,15 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = keyboard.drv16 +IMPORTS = user32 kernel32 +EXTRADLLFLAGS = -Wb,--subsystem,win16 + +SPEC_SRCS = keyboard.drv16.spec + +C_SRCS = keyboard.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/user32/kbd16.c b/dlls/keyboard.drv16/keyboard.c similarity index 84% rename from dlls/user32/kbd16.c rename to dlls/keyboard.drv16/keyboard.c index ffc53ef3d12..f42ee4bb411 100644 --- a/dlls/user32/kbd16.c +++ b/dlls/keyboard.drv16/keyboard.c @@ -54,7 +54,7 @@ static LPBYTE pKeyStateTable; /*********************************************************************** * Inquire (KEYBOARD.1) */ -WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo) +WORD WINAPI Inquire16(LPKBINFO kbInfo) { kbInfo->Begin_First_Range = 0; kbInfo->End_First_Range = 0; @@ -68,7 +68,7 @@ WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo) /*********************************************************************** * Enable (KEYBOARD.2) */ -VOID WINAPI KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState ) +VOID WINAPI Enable16( FARPROC16 proc, LPBYTE lpKeyState ) { DefKeybEventProc = proc; pKeyStateTable = lpKeyState; @@ -79,12 +79,21 @@ VOID WINAPI KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState ) /*********************************************************************** * Disable (KEYBOARD.3) */ -VOID WINAPI KEYBOARD_Disable(VOID) +VOID WINAPI Disable16(VOID) { DefKeybEventProc = NULL; pKeyStateTable = NULL; } +/**************************************************************************** + * ToAscii (KEYBOARD.4) + */ +INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, + LPVOID lpChar, UINT16 flags) +{ + return ToAscii( virtKey, scanCode, lpKeyState, lpChar, flags ); +} + /*********************************************************************** * AnsiToOem (KEYBOARD.5) */ @@ -185,27 +194,3 @@ void WINAPI OemToAnsiBuff16( LPCSTR s, LPSTR d, UINT16 len ) { if (len != 0) OemToCharBuffA( s, d, len ); } - -/**************************************************************************** - * ToAscii (KEYBOARD.4) - * - * The ToAscii function translates the specified virtual-key code and keyboard - * state to the corresponding Windows character or characters. - * - * If the specified key is a dead key, the return value is negative. Otherwise, - * it is one of the following values: - * Value Meaning - * 0 The specified virtual key has no translation for the current state of the keyboard. - * 1 One Windows character was copied to the buffer. - * 2 Two characters were copied to the buffer. This usually happens when a - * dead-key character (accent or diacritic) stored in the keyboard layout cannot - * be composed with the specified virtual key to form a single character. - * - * FIXME : should do the above (return 2 for non matching deadchar+char combinations) - * - */ -INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, - LPVOID lpChar, UINT16 flags) -{ - return ToAscii( virtKey, scanCode, lpKeyState, lpChar, flags ); -} diff --git a/dlls/user32/keyboard.drv.spec b/dlls/keyboard.drv16/keyboard.drv16.spec similarity index 86% rename from dlls/user32/keyboard.drv.spec rename to dlls/keyboard.drv16/keyboard.drv16.spec index 230b18eb2e2..88dc7a74b66 100644 --- a/dlls/user32/keyboard.drv.spec +++ b/dlls/keyboard.drv16/keyboard.drv16.spec @@ -1,6 +1,6 @@ -1 pascal -ret16 Inquire(ptr) KEYBOARD_Inquire -2 pascal -ret16 Enable(segptr ptr) KEYBOARD_Enable -3 pascal -ret16 Disable() KEYBOARD_Disable +1 pascal -ret16 Inquire(ptr) Inquire16 +2 pascal -ret16 Enable(segptr ptr) Enable16 +3 pascal -ret16 Disable() Disable16 4 pascal -ret16 ToAscii(word word ptr ptr word) ToAscii16 5 pascal -ret16 AnsiToOem(str ptr) AnsiToOem16 6 pascal -ret16 OemToAnsi(str ptr) OemToAnsi16 diff --git a/dlls/mlang/mlang.c b/dlls/mlang/mlang.c index f9c3f8e9baa..4fc8e1b817e 100644 --- a/dlls/mlang/mlang.c +++ b/dlls/mlang/mlang.c @@ -1495,7 +1495,7 @@ typedef struct tagEnumCodePage_impl static inline EnumCodePage_impl *impl_from_IEnumCodePage( IEnumCodePage *iface ) { - return (EnumCodePage_impl *)CONTAINING_RECORD( iface, EnumCodePage_impl, vtbl_IEnumCodePage ); + return CONTAINING_RECORD( iface, EnumCodePage_impl, vtbl_IEnumCodePage ); } static HRESULT WINAPI fnIEnumCodePage_QueryInterface( @@ -1688,7 +1688,7 @@ typedef struct tagEnumScript_impl static inline EnumScript_impl *impl_from_IEnumScript( IEnumScript *iface ) { - return (EnumScript_impl *)CONTAINING_RECORD( iface, EnumScript_impl, vtbl_IEnumScript ); + return CONTAINING_RECORD( iface, EnumScript_impl, vtbl_IEnumScript ); } static HRESULT WINAPI fnIEnumScript_QueryInterface( @@ -1850,7 +1850,7 @@ static HRESULT EnumScript_create( MLang_impl* mlang, DWORD dwFlags, static inline MLang_impl *impl_from_IMLangFontLink( IMLangFontLink *iface ) { - return (MLang_impl *)CONTAINING_RECORD( iface, MLang_impl, vtbl_IMLangFontLink ); + return CONTAINING_RECORD( iface, MLang_impl, vtbl_IMLangFontLink ); } static HRESULT WINAPI fnIMLangFontLink_QueryInterface( @@ -1954,7 +1954,7 @@ static HRESULT WINAPI fnIMLangFontLink_CodePageToCodePages( TRACE("(%p) Seeking %u\n",This, uCodePage); - rc = TranslateCharsetInfo((DWORD*)uCodePage, &cs, TCI_SRCCODEPAGE); + rc = TranslateCharsetInfo((DWORD*)(DWORD_PTR)uCodePage, &cs, TCI_SRCCODEPAGE); if (rc) { @@ -1985,8 +1985,9 @@ static HRESULT WINAPI fnIMLangFontLink_CodePagesToCodePage( *puCodePage = 0x00000000; - rc = TranslateCharsetInfo((DWORD*)uDefaultCodePage, &cs, TCI_SRCCODEPAGE); - + rc = TranslateCharsetInfo((DWORD*)(DWORD_PTR)uDefaultCodePage, &cs, + TCI_SRCCODEPAGE); + if (rc && (dwCodePages & cs.fs.fsCsb[0])) { TRACE("Found Default Codepage\n"); @@ -2087,7 +2088,7 @@ static const IMLangFontLinkVtbl IMLangFontLink_vtbl = static inline MLang_impl *impl_from_IMultiLanguage( IMultiLanguage *iface ) { - return (MLang_impl *)CONTAINING_RECORD( iface, MLang_impl, vtbl_IMultiLanguage ); + return CONTAINING_RECORD( iface, MLang_impl, vtbl_IMultiLanguage ); } static HRESULT WINAPI fnIMultiLanguage_QueryInterface( @@ -2280,7 +2281,7 @@ typedef struct tagEnumRfc1766_impl static inline EnumRfc1766_impl *impl_from_IEnumRfc1766( IEnumRfc1766 *iface ) { - return (EnumRfc1766_impl *)CONTAINING_RECORD( iface, EnumRfc1766_impl, vtbl_IEnumRfc1766 ); + return CONTAINING_RECORD( iface, EnumRfc1766_impl, vtbl_IEnumRfc1766 ); } static HRESULT WINAPI fnIEnumRfc1766_QueryInterface( @@ -2550,7 +2551,7 @@ static const IMultiLanguageVtbl IMultiLanguage_vtbl = static inline MLang_impl *impl_from_IMultiLanguage3( IMultiLanguage3 *iface ) { - return (MLang_impl *)CONTAINING_RECORD( iface, MLang_impl, vtbl_IMultiLanguage3 ); + return CONTAINING_RECORD( iface, MLang_impl, vtbl_IMultiLanguage3 ); } static HRESULT WINAPI fnIMultiLanguage2_QueryInterface( @@ -2592,7 +2593,8 @@ static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINF { CHARSETINFO csi; - if (TranslateCharsetInfo((DWORD *)ml_data->family_codepage, &csi, TCI_SRCCODEPAGE)) + if (TranslateCharsetInfo((DWORD*)(DWORD_PTR)ml_data->family_codepage, &csi, + TCI_SRCCODEPAGE)) mime_cp_info->bGDICharset = csi.ciCharset; else mime_cp_info->bGDICharset = DEFAULT_CHARSET; @@ -3169,7 +3171,7 @@ static const IMultiLanguage3Vtbl IMultiLanguage3_vtbl = static inline MLang_impl *impl_from_IMLangFontLink2( IMLangFontLink2 *iface ) { - return (MLang_impl *)CONTAINING_RECORD( iface, MLang_impl, vtbl_IMLangFontLink2 ); + return CONTAINING_RECORD( iface, MLang_impl, vtbl_IMLangFontLink2 ); } static HRESULT WINAPI fnIMLangFontLink2_QueryInterface( @@ -3323,7 +3325,7 @@ static const IMLangFontLink2Vtbl IMLangFontLink2_vtbl = static inline MLang_impl *impl_from_IMLangLineBreakConsole( IMLangLineBreakConsole *iface ) { - return (MLang_impl *)CONTAINING_RECORD( iface, MLang_impl, vtbl_IMLangLineBreakConsole ); + return CONTAINING_RECORD( iface, MLang_impl, vtbl_IMLangLineBreakConsole ); } static HRESULT WINAPI fnIMLangLineBreakConsole_QueryInterface( diff --git a/dlls/mouse.drv16/Makefile.in b/dlls/mouse.drv16/Makefile.in new file mode 100644 index 00000000000..982e9b7ddcf --- /dev/null +++ b/dlls/mouse.drv16/Makefile.in @@ -0,0 +1,19 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = mouse.drv16 +IMPORTS = user32 kernel32 + +EXTRADLLFLAGS = -Wb,--subsystem,win16 +EXTRARCFLAGS = -O res16 + +SPEC_SRCS = mouse.drv16.spec + +C_SRCS = mouse.c + +RC_SRCS = mouse.rc + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/user32/mouse16.c b/dlls/mouse.drv16/mouse.c similarity index 94% rename from dlls/user32/mouse16.c rename to dlls/mouse.drv16/mouse.c index 7cb653de012..b2e074e2ad7 100644 --- a/dlls/user32/mouse16.c +++ b/dlls/mouse.drv16/mouse.c @@ -47,7 +47,7 @@ static FARPROC16 DefMouseEventProc; /*********************************************************************** * Inquire (MOUSE.1) */ -WORD WINAPI MOUSE_Inquire(LPMOUSEINFO mouseInfo) +WORD WINAPI Inquire16(LPMOUSEINFO mouseInfo) { mouseInfo->msExist = TRUE; mouseInfo->msRelative = FALSE; @@ -65,7 +65,7 @@ WORD WINAPI MOUSE_Inquire(LPMOUSEINFO mouseInfo) /*********************************************************************** * Enable (MOUSE.2) */ -VOID WINAPI MOUSE_Enable( FARPROC16 proc ) +VOID WINAPI Enable16( FARPROC16 proc ) { DefMouseEventProc = proc; } @@ -73,7 +73,7 @@ VOID WINAPI MOUSE_Enable( FARPROC16 proc ) /*********************************************************************** * Disable (MOUSE.3) */ -VOID WINAPI MOUSE_Disable(VOID) +VOID WINAPI Disable16(void) { DefMouseEventProc = 0; } diff --git a/dlls/user32/mouse.drv.spec b/dlls/mouse.drv16/mouse.drv16.spec similarity index 53% rename from dlls/user32/mouse.drv.spec rename to dlls/mouse.drv16/mouse.drv16.spec index 71d406c5d32..c45cc6affe0 100644 --- a/dlls/user32/mouse.drv.spec +++ b/dlls/mouse.drv16/mouse.drv16.spec @@ -1,6 +1,6 @@ -1 pascal -ret16 Inquire(ptr) MOUSE_Inquire -2 pascal -ret16 Enable(segptr) MOUSE_Enable -3 pascal -ret16 Disable() MOUSE_Disable +1 pascal -ret16 Inquire(ptr) Inquire16 +2 pascal -ret16 Enable(segptr) Enable16 +3 pascal -ret16 Disable() Disable16 4 stub MOUSEGETINTVECT 5 stub GETSETMOUSEDATA #Control Panel thinks this is implemented if it is available diff --git a/dlls/user32/resources/mouse.rc b/dlls/mouse.drv16/mouse.rc similarity index 100% rename from dlls/user32/resources/mouse.rc rename to dlls/mouse.drv16/mouse.rc diff --git a/dlls/msacm32/internal.c b/dlls/msacm32/internal.c index 4100aae1918..feb6e9cb6cc 100644 --- a/dlls/msacm32/internal.c +++ b/dlls/msacm32/internal.c @@ -72,7 +72,7 @@ PWINE_ACMDRIVERID MSACM_RegisterDriverFromRegistry(LPCWSTR pszRegEntry) /* The requested registry entry must have the format msacm.XXXXX in order to be recognized in any future sessions of msacm */ - if (0 == strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(WCHAR))) { + if (0 == strncmpiW(pszRegEntry, msacmW, sizeof(msacmW)/sizeof(WCHAR))) { lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey); if (lRet != ERROR_SUCCESS) { WARN("unable to open registry key - 0x%08x\n", lRet); diff --git a/dlls/mscms/mscms_main.c b/dlls/mscms/mscms_main.c index 00e2a753e87..3199c0b80ac 100644 --- a/dlls/mscms/mscms_main.c +++ b/dlls/mscms/mscms_main.c @@ -36,6 +36,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(mscms); +#ifdef HAVE_LCMS +static int lcms_error_handler( int error, const char *text ) +{ + switch (error) + { + case LCMS_ERRC_WARNING: + case LCMS_ERRC_RECOVERABLE: + case LCMS_ERRC_ABORTED: + WARN("%d %s\n", error, debugstr_a(text)); + return 1; + default: + ERR("unknown error %d %s\n", error, debugstr_a(text)); + return 0; + } +} +#endif + BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { TRACE( "(%p, %d, %p)\n", hinst, reason, reserved ); @@ -44,6 +61,9 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinst ); +#ifdef HAVE_LCMS + cmsSetErrorHandler( lcms_error_handler ); +#endif break; case DLL_PROCESS_DETACH: #ifdef HAVE_LCMS diff --git a/dlls/mscms/tests/profile.c b/dlls/mscms/tests/profile.c index e33280ab857..100c15c4f1f 100644 --- a/dlls/mscms/tests/profile.c +++ b/dlls/mscms/tests/profile.c @@ -581,9 +581,14 @@ static void check_registry(BOOL *has_space_rgb) trace("RegEnumValueA() failed (%d), cannot enumerate profiles\n", res); break; } - ok( dwType == REG_SZ, "RegEnumValueA() returned unexpected value type (%d)\n", dwType ); - if (dwType != REG_SZ) break; - trace(" found '%s' value containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData)); + ok( dwType == REG_SZ || dwType == REG_DWORD, "RegEnumValueA() returned unexpected value type (%d)\n", dwType ); + + if (dwType == REG_SZ) + trace(" found string value '%s' containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData)); + else if (dwType == REG_DWORD) + trace(" found DWORD value '%s' containing '%x'\n", szName, *(DWORD *)szData); + else + break; } RegCloseKey( hkIcmKey ); diff --git a/dlls/msctf/msctf.c b/dlls/msctf/msctf.c index 1f5e35bc824..e77c749ab1f 100644 --- a/dlls/msctf/msctf.c +++ b/dlls/msctf/msctf.c @@ -148,7 +148,7 @@ static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut) This->vtbl = &ClassFactoryVtbl; This->ref = 1; This->ctor = ctor; - *ppvOut = (LPVOID)This; + *ppvOut = This; TRACE("Created class factory %p\n", This); MSCTF_refCount++; return S_OK; @@ -217,7 +217,7 @@ HRESULT WINAPI TF_CreateThreadMgr(ITfThreadMgr **pptim) HRESULT WINAPI TF_GetThreadMgr(ITfThreadMgr **pptim) { TRACE("\n"); - *pptim = (ITfThreadMgr*)TlsGetValue(tlsIndex); + *pptim = TlsGetValue(tlsIndex); if (*pptim) ITfThreadMgr_AddRef(*pptim); diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index a3a9595cdad..0d0422c873a 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -88,6 +88,9 @@ static REFIID tid_ids[] = { &IID_IHTMLBodyElement2, &IID_IHTMLCommentElement, &IID_IHTMLCurrentStyle, + &IID_IHTMLCurrentStyle2, + &IID_IHTMLCurrentStyle3, + &IID_IHTMLCurrentStyle4, &IID_IHTMLDocument2, &IID_IHTMLDocument3, &IID_IHTMLDocument4, @@ -111,6 +114,8 @@ static REFIID tid_ids[] = { &IID_IHTMLSelectElement, &IID_IHTMLStyle, &IID_IHTMLStyle2, + &IID_IHTMLStyle3, + &IID_IHTMLStyle4, &IID_IHTMLTable, &IID_IHTMLTableRow, &IID_IHTMLTextContainer, diff --git a/dlls/mshtml/htmlcurstyle.c b/dlls/mshtml/htmlcurstyle.c index 9bb139d960f..5aaaece85c2 100644 --- a/dlls/mshtml/htmlcurstyle.c +++ b/dlls/mshtml/htmlcurstyle.c @@ -709,15 +709,15 @@ static HRESULT WINAPI HTMLCurrentStyle_get_layoutGridType(IHTMLCurrentStyle *ifa static HRESULT WINAPI HTMLCurrentStyle_get_borderStyle(IHTMLCurrentStyle *iface, BSTR *p) { HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr(This->nsstyle, STYLEID_BORDER_STYLE, p); } static HRESULT WINAPI HTMLCurrentStyle_get_borderColor(IHTMLCurrentStyle *iface, BSTR *p) { HTMLCurrentStyle *This = HTMLCURSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr(This->nsstyle, STYLEID_BORDER_COLOR, p); } static HRESULT WINAPI HTMLCurrentStyle_get_borderWidth(IHTMLCurrentStyle *iface, BSTR *p) @@ -874,6 +874,9 @@ static const IHTMLCurrentStyleVtbl HTMLCurrentStyleVtbl = { static const tid_t HTMLCurrentStyle_iface_tids[] = { IHTMLCurrentStyle_tid, + IHTMLCurrentStyle2_tid, + IHTMLCurrentStyle3_tid, + IHTMLCurrentStyle4_tid, 0 }; static dispex_static_data_t HTMLCurrentStyle_dispex = { diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index a7eff56b9e2..3727c8e8ed6 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -41,20 +41,34 @@ static const WCHAR attrBackgroundColor[] = {'b','a','c','k','g','r','o','u','n','d','-','c','o','l','o','r',0}; static const WCHAR attrBackgroundImage[] = {'b','a','c','k','g','r','o','u','n','d','-','i','m','a','g','e',0}; +static const WCHAR attrBackgroundPositionX[] = + {'b','a','c','k','g','r','o','u','n','d','-','p','o','s','i','t','i','o','n','-','x',0}; +static const WCHAR attrBackgroundPositionY[] = + {'b','a','c','k','g','r','o','u','n','d','-','p','o','s','i','t','i','o','n','-','y',0}; static const WCHAR attrBackgroundRepeat[] = {'b','a','c','k','g','r','o','u','n','d','-','r','e','p','e','a','t',0}; static const WCHAR attrBorder[] = {'b','o','r','d','e','r',0}; static const WCHAR attrBorderBottomStyle[] = {'b','o','r','d','e','r','-','b','o','t','t','o','m','-','s','t','y','l','e',0}; +static const WCHAR attrBorderBottomWidth[] = + {'b','o','r','d','e','r','-','b','o','t','t','o','m','-','w','i','d','t','h',0}; +static const WCHAR attrBorderColor[] = + {'b','o','r','d','e','r','-','c','o','l','o','r',0}; static const WCHAR attrBorderLeft[] = {'b','o','r','d','e','r','-','l','e','f','t',0}; static const WCHAR attrBorderLeftStyle[] = {'b','o','r','d','e','r','-','l','e','f','t','-','s','t','y','l','e',0}; static const WCHAR attrBorderRightStyle[] = {'b','o','r','d','e','r','-','r','i','g','h','t','-','s','t','y','l','e',0}; +static const WCHAR attrBorderRightWidth[] = + {'b','o','r','d','e','r','-','r','i','g','h','t','-','w','i','d','t','h',0}; +static const WCHAR attrBorderStyle[] = + {'b','o','r','d','e','r','-','s','t','y','l','e',0}; static const WCHAR attrBorderTopStyle[] = {'b','o','r','d','e','r','-','t','o','p','-','s','t','y','l','e',0}; +static const WCHAR attrBorderTopWidth[] = + {'b','o','r','d','e','r','-','t','o','p','-','w','i','d','t','h',0}; static const WCHAR attrBorderWidth[] = {'b','o','r','d','e','r','-','w','i','d','t','h',0}; static const WCHAR attrColor[] = @@ -115,13 +129,20 @@ static const struct{ {attrBackground, DISPID_IHTMLSTYLE_BACKGROUND}, {attrBackgroundColor, DISPID_IHTMLSTYLE_BACKGROUNDCOLOR}, {attrBackgroundImage, DISPID_IHTMLSTYLE_BACKGROUNDIMAGE}, + {attrBackgroundPositionX, DISPID_IHTMLSTYLE_BACKGROUNDPOSITIONX}, + {attrBackgroundPositionY, DISPID_IHTMLSTYLE_BACKGROUNDPOSITIONY}, {attrBackgroundRepeat, DISPID_IHTMLSTYLE_BACKGROUNDREPEAT}, {attrBorder, DISPID_IHTMLSTYLE_BORDER}, {attrBorderBottomStyle, DISPID_IHTMLSTYLE_BORDERBOTTOMSTYLE}, + {attrBorderBottomWidth, DISPID_IHTMLSTYLE_BORDERBOTTOMWIDTH}, + {attrBorderColor, DISPID_IHTMLSTYLE_BORDERCOLOR}, {attrBorderLeft, DISPID_IHTMLSTYLE_BORDERLEFT}, {attrBorderLeftStyle, DISPID_IHTMLSTYLE_BORDERLEFTSTYLE}, {attrBorderRightStyle, DISPID_IHTMLSTYLE_BORDERRIGHTSTYLE}, + {attrBorderRightWidth, DISPID_IHTMLSTYLE_BORDERRIGHTWIDTH}, + {attrBorderStyle, DISPID_IHTMLSTYLE_BORDERSTYLE}, {attrBorderTopStyle, DISPID_IHTMLSTYLE_BORDERTOPSTYLE}, + {attrBorderTopWidth, DISPID_IHTMLSTYLE_BORDERTOPWIDTH}, {attrBorderWidth, DISPID_IHTMLSTYLE_BORDERWIDTH}, {attrColor, DISPID_IHTMLSTYLE_COLOR}, {attrCursor, DISPID_IHTMLSTYLE_CURSOR}, @@ -868,29 +889,29 @@ static HRESULT WINAPI HTMLStyle_get_backgroundPosition(IHTMLStyle *iface, BSTR * static HRESULT WINAPI HTMLStyle_put_backgroundPositionX(IHTMLStyle *iface, VARIANT v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(v%d)\n", This, V_VT(&v)); - return E_NOTIMPL; + TRACE("(%p)->(v%d)\n", This, V_VT(&v)); + return set_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_POSITION_X, &v, 0); } static HRESULT WINAPI HTMLStyle_get_backgroundPositionX(IHTMLStyle *iface, VARIANT *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_POSITION_X, p, 0); } static HRESULT WINAPI HTMLStyle_put_backgroundPositionY(IHTMLStyle *iface, VARIANT v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(v%d)\n", This, V_VT(&v)); - return E_NOTIMPL; + TRACE("(%p)->(v%d)\n", This, V_VT(&v)); + return set_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_POSITION_Y, &v, 0); } static HRESULT WINAPI HTMLStyle_get_backgroundPositionY(IHTMLStyle *iface, VARIANT *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_POSITION_Y, p, 0); } static HRESULT WINAPI HTMLStyle_put_wordSpacing(IHTMLStyle *iface, VARIANT v) @@ -924,8 +945,18 @@ static HRESULT WINAPI HTMLStyle_get_letterSpacing(IHTMLStyle *iface, VARIANT *p) static HRESULT WINAPI HTMLStyle_put_textDecoration(IHTMLStyle *iface, BSTR v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + /* textDecoration can only be one of the following */ + if(!v || strcmpiW(styleNone, v) == 0 || strcmpiW(valUnderline, v) == 0 || + strcmpiW(valOverline, v) == 0 || strcmpiW(valLineThrough, v) == 0 || + strcmpiW(valBlink, v) == 0) + { + return set_style_attr(This, STYLEID_TEXT_DECORATION , v, 0); + } + + return E_INVALIDARG; } static HRESULT WINAPI HTMLStyle_get_textDecoration(IHTMLStyle *iface, BSTR *p) @@ -1398,22 +1429,28 @@ static HRESULT WINAPI HTMLStyle_put_borderLeft(IHTMLStyle *iface, BSTR v) static HRESULT WINAPI HTMLStyle_get_borderLeft(IHTMLStyle *iface, BSTR *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_style_attr(This, STYLEID_BORDER_LEFT, p); } static HRESULT WINAPI HTMLStyle_put_borderColor(IHTMLStyle *iface, BSTR v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_style_attr(This, STYLEID_BORDER_COLOR, v, 0); } static HRESULT WINAPI HTMLStyle_get_borderColor(IHTMLStyle *iface, BSTR *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_style_attr(This, STYLEID_BORDER_COLOR, p); } static HRESULT WINAPI HTMLStyle_put_borderTopColor(IHTMLStyle *iface, VARIANT v) @@ -1489,43 +1526,46 @@ static HRESULT WINAPI HTMLStyle_get_borderWidth(IHTMLStyle *iface, BSTR *p) static HRESULT WINAPI HTMLStyle_put_borderTopWidth(IHTMLStyle *iface, VARIANT v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(v%d)\n", This, V_VT(&v)); - return E_NOTIMPL; + TRACE("(%p)->(v%d)\n", This, V_VT(&v)); + return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, &v, 0); } static HRESULT WINAPI HTMLStyle_get_borderTopWidth(IHTMLStyle *iface, VARIANT *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, p, 0); } static HRESULT WINAPI HTMLStyle_put_borderRightWidth(IHTMLStyle *iface, VARIANT v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(v%d)\n", This, V_VT(&v)); - return E_NOTIMPL; + TRACE("(%p)->(v%d)\n", This, V_VT(&v)); + return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, &v, 0); } static HRESULT WINAPI HTMLStyle_get_borderRightWidth(IHTMLStyle *iface, VARIANT *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, p, 0); } static HRESULT WINAPI HTMLStyle_put_borderBottomWidth(IHTMLStyle *iface, VARIANT v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(v%d)\n", This, V_VT(&v)); - return E_NOTIMPL; + + TRACE("(%p)->(v%d)\n", This, V_VT(&v)); + return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, &v, 0); } static HRESULT WINAPI HTMLStyle_get_borderBottomWidth(IHTMLStyle *iface, VARIANT *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, p, 0); } static HRESULT WINAPI HTMLStyle_put_borderLeftWidth(IHTMLStyle *iface, VARIANT v) @@ -1545,15 +1585,52 @@ static HRESULT WINAPI HTMLStyle_get_borderLeftWidth(IHTMLStyle *iface, VARIANT * static HRESULT WINAPI HTMLStyle_put_borderStyle(IHTMLStyle *iface, BSTR v) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + static const WCHAR styleWindowInset[] = {'w','i','n','d','o','w','-','i','n','s','e','t',0}; + HRESULT hres = S_OK; + BSTR pstyle; + int i=0; + int last = 0; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + while(v[i] && hres == S_OK) + { + if(v[i] == (WCHAR)' ') + { + pstyle = SysAllocStringLen(&v[last], (i-last)); + if( !(is_valid_border_style(pstyle) || strcmpiW(styleWindowInset, pstyle) == 0)) + { + TRACE("1. Invalid style (%s)\n", debugstr_w(pstyle)); + hres = E_INVALIDARG; + } + SysFreeString(pstyle); + last = i+1; + } + i++; + } + + if(hres == S_OK) + { + pstyle = SysAllocStringLen(&v[last], i-last); + if( !(is_valid_border_style(pstyle) || strcmpiW(styleWindowInset, pstyle) == 0)) + { + TRACE("2. Invalid style (%s)\n", debugstr_w(pstyle)); + hres = E_INVALIDARG; + } + SysFreeString(pstyle); + } + + if(hres == S_OK) + hres = set_nsstyle_attr(This->nsstyle, STYLEID_BORDER_STYLE, v, 0); + + return hres; } static HRESULT WINAPI HTMLStyle_get_borderStyle(IHTMLStyle *iface, BSTR *p) { HTMLStyle *This = HTMLSTYLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_style_attr(This, STYLEID_BORDER_STYLE, p); } static HRESULT WINAPI HTMLStyle_put_borderTopStyle(IHTMLStyle *iface, BSTR v) @@ -2498,6 +2575,8 @@ static const dispex_static_data_vtbl_t HTMLStyle_dispex_vtbl = { static const tid_t HTMLStyle_iface_tids[] = { IHTMLStyle_tid, IHTMLStyle2_tid, + IHTMLStyle3_tid, + IHTMLStyle4_tid, 0 }; static dispex_static_data_t HTMLStyle_dispex = { diff --git a/dlls/mshtml/htmlstyle.h b/dlls/mshtml/htmlstyle.h index 73c7c7dccba..596f5793f31 100644 --- a/dlls/mshtml/htmlstyle.h +++ b/dlls/mshtml/htmlstyle.h @@ -38,13 +38,20 @@ typedef enum { STYLEID_BACKGROUND, STYLEID_BACKGROUND_COLOR, STYLEID_BACKGROUND_IMAGE, + STYLEID_BACKGROUND_POSITION_X, + STYLEID_BACKGROUND_POSITION_Y, STYLEID_BACKGROUND_REPEAT, STYLEID_BORDER, STYLEID_BORDER_BOTTOM_STYLE, + STYLEID_BORDER_BOTTOM_WIDTH, + STYLEID_BORDER_COLOR, STYLEID_BORDER_LEFT, STYLEID_BORDER_LEFT_STYLE, STYLEID_BORDER_RIGHT_STYLE, + STYLEID_BORDER_RIGHT_WIDTH, + STYLEID_BORDER_STYLE, STYLEID_BORDER_TOP_STYLE, + STYLEID_BORDER_TOP_WIDTH, STYLEID_BORDER_WIDTH, STYLEID_COLOR, STYLEID_CURSOR, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index b67c4856a93..3ecfdea1c3b 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -84,6 +84,9 @@ typedef enum { IHTMLBodyElement2_tid, IHTMLCommentElement_tid, IHTMLCurrentStyle_tid, + IHTMLCurrentStyle2_tid, + IHTMLCurrentStyle3_tid, + IHTMLCurrentStyle4_tid, IHTMLDocument2_tid, IHTMLDocument3_tid, IHTMLDocument4_tid, @@ -107,6 +110,8 @@ typedef enum { IHTMLSelectElement_tid, IHTMLStyle_tid, IHTMLStyle2_tid, + IHTMLStyle3_tid, + IHTMLStyle4_tid, IHTMLTable_tid, IHTMLTableRow_tid, IHTMLTextContainer_tid, diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index c0fb0091ab6..69ed3c0fd3f 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -486,7 +486,7 @@ static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk) HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem); - ok_(__FILE__,line) (hres == S_OK, "Coule not get IHTMLElement: %08x\n", hres); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement: %08x\n", hres); return elem; } @@ -497,7 +497,7 @@ static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk) HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem); - ok_(__FILE__,line) (hres == S_OK, "Coule not get IHTMLElement2: %08x\n", hres); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2: %08x\n", hres); return elem; } @@ -508,7 +508,7 @@ static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk) HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem); - ok_(__FILE__,line) (hres == S_OK, "Coule not get IHTMLElement3: %08x\n", hres); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3: %08x\n", hres); return elem; } @@ -519,7 +519,7 @@ static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk) HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&node); - ok_(__FILE__,line) (hres == S_OK, "Coule not get IHTMLDOMNode: %08x\n", hres); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode: %08x\n", hres); return node; } @@ -2445,6 +2445,14 @@ static void test_current_style(IHTMLCurrentStyle *current_style) ok(!strcmp_wa(str, "repeat"), "get_backgroundRepeat returned %s\n", dbgstr_w(str)); SysFreeString(str); + hres = IHTMLCurrentStyle_get_borderColor(current_style, &str); + ok(hres == S_OK, "get_borderColor failed: %08x\n", hres); + SysFreeString(str); + + hres = IHTMLCurrentStyle_get_borderStyle(current_style, &str); + ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres); + SysFreeString(str); + hres = IHTMLCurrentStyle_get_fontWeight(current_style, &v); ok(hres == S_OK, "get_fontWeight failed: %08x\n", hres); ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); @@ -2798,6 +2806,48 @@ static void test_default_style(IHTMLStyle *style) hres = IHTMLStyle_put_textDecorationBlink(style, VARIANT_FALSE); ok(hres == S_OK, "textDecorationBlink failed: %08x\n", hres); + hres = IHTMLStyle_get_textDecoration(style, &sDefault); + ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres); + + str = a2bstr("invalid"); + hres = IHTMLStyle_put_textDecoration(style, str); + ok(hres == E_INVALIDARG, "put_textDecoration failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("none"); + hres = IHTMLStyle_put_textDecoration(style, str); + ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("underline"); + hres = IHTMLStyle_put_textDecoration(style, str); + ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("overline"); + hres = IHTMLStyle_put_textDecoration(style, str); + ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("line-through"); + hres = IHTMLStyle_put_textDecoration(style, str); + ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("blink"); + hres = IHTMLStyle_put_textDecoration(style, str); + ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres); + SysFreeString(str); + + hres = IHTMLStyle_get_textDecoration(style, &str); + ok(hres == S_OK, "get_textDecoration failed: %08x\n", hres); + ok(!strcmp_wa(str, "blink"), "str != blink\n"); + SysFreeString(str); + + hres = IHTMLStyle_put_textDecoration(style, sDefault); + ok(hres == S_OK, "put_textDecoration failed: %08x\n", hres); + SysFreeString(sDefault); + hres = IHTMLStyle_get_posWidth(style, NULL); ok(hres == E_POINTER, "get_posWidth failed: %08x\n", hres); @@ -3216,6 +3266,56 @@ static void test_default_style(IHTMLStyle *style) test_border_styles(style, str); SysFreeString(str); + hres = IHTMLStyle_get_borderStyle(style, &sDefault); + ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres); + + str = a2bstr("none dotted dashed solid"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("none dotted dashed solid"); + hres = IHTMLStyle_get_borderStyle(style, &str); + ok(hres == S_OK, "get_borderStyle failed: %08x\n", hres); + ok(!strcmp_wa(str, "none dotted dashed solid"), + "expected (none dotted dashed solid) = (%s)\n", dbgstr_w(V_BSTR(&v))); + SysFreeString(str); + + str = a2bstr("double groove ridge inset"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("window-inset outset ridge inset"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("window-inset"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("none none none none none"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("invalid none none none"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("none invalid none none"); + hres = IHTMLStyle_put_borderStyle(style, str); + ok(hres == E_INVALIDARG, "put_borderStyle failed: %08x\n", hres); + SysFreeString(str); + + hres = IHTMLStyle_put_borderStyle(style, sDefault); + ok(hres == S_OK, "put_borderStyle failed: %08x\n", hres); + SysFreeString(sDefault); + + /* backgoundColor */ hres = IHTMLStyle_get_backgroundColor(style, &v); ok(hres == S_OK, "get_backgroundColor: %08x\n", hres); ok(V_VT(&v) == VT_BSTR, "type failed: %d\n", V_VT(&v)); @@ -3277,6 +3377,153 @@ static void test_default_style(IHTMLStyle *style) ok(hres == S_OK, "put_backgroundRepeat failed: %08x\n", hres); SysFreeString(sDefault); + /* BorderColor */ + hres = IHTMLStyle_get_borderColor(style, &sDefault); + ok(hres == S_OK, "get_borderColor failed: %08x\n", hres); + + str = a2bstr("red green red blue"); + hres = IHTMLStyle_put_borderColor(style, str); + ok(hres == S_OK, "put_borderColor failed: %08x\n", hres); + SysFreeString(str); + + hres = IHTMLStyle_get_borderColor(style, &str); + ok(hres == S_OK, "get_borderColor failed: %08x\n", hres); + ok(!strcmp_wa(str, "red green red blue"), "str=%s\n", dbgstr_w(str)); + SysFreeString(str); + + hres = IHTMLStyle_put_borderColor(style, sDefault); + ok(hres == S_OK, "put_borderColor failed: %08x\n", hres); + SysFreeString(sDefault); + + /* BorderLeft */ + hres = IHTMLStyle_get_borderLeft(style, &sDefault); + ok(hres == S_OK, "get_borderLeft failed: %08x\n", hres); + + str = a2bstr("thick dotted red"); + hres = IHTMLStyle_put_borderLeft(style, str); + ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres); + SysFreeString(str); + + /* IHTMLStyle_get_borderLeft appears to have a bug where + it returns the first letter of the color. So we check + each style individually. + */ + V_BSTR(&v) = NULL; + hres = IHTMLStyle_get_borderLeftColor(style, &v); + todo_wine ok(hres == S_OK, "get_borderLeftColor failed: %08x\n", hres); + todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_BSTR(&v) = NULL; + hres = IHTMLStyle_get_borderLeftWidth(style, &v); + todo_wine ok(hres == S_OK, "get_borderLeftWidth failed: %08x\n", hres); + todo_wine ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + hres = IHTMLStyle_get_borderLeftStyle(style, &str); + ok(hres == S_OK, "get_borderLeftStyle failed: %08x\n", hres); + ok(!strcmp_wa(str, "dotted"), "str=%s\n", dbgstr_w(str)); + SysFreeString(str); + + hres = IHTMLStyle_put_borderLeft(style, sDefault); + ok(hres == S_OK, "put_borderLeft failed: %08x\n", hres); + SysFreeString(sDefault); + + /* backgroundPositionX */ + hres = IHTMLStyle_get_backgroundPositionX(style, &vDefault); + ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("10px"); + hres = IHTMLStyle_put_backgroundPositionX(style, v); + ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres); + VariantClear(&v); + + hres = IHTMLStyle_get_backgroundPositionX(style, &v); + ok(hres == S_OK, "get_backgroundPositionX failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v)); + VariantClear(&v); + + hres = IHTMLStyle_put_backgroundPositionX(style, vDefault); + ok(hres == S_OK, "put_backgroundPositionX failed: %08x\n", hres); + VariantClear(&vDefault); + + /* backgroundPositionY */ + hres = IHTMLStyle_get_backgroundPositionY(style, &vDefault); + ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("10px"); + hres = IHTMLStyle_put_backgroundPositionY(style, v); + ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres); + VariantClear(&v); + + hres = IHTMLStyle_get_backgroundPositionY(style, &v); + ok(hres == S_OK, "get_backgroundPositionY failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v)); + VariantClear(&v); + + hres = IHTMLStyle_put_backgroundPositionY(style, vDefault); + ok(hres == S_OK, "put_backgroundPositionY failed: %08x\n", hres); + VariantClear(&vDefault); + + /* borderTopWidth */ + hres = IHTMLStyle_get_borderTopWidth(style, &vDefault); + ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("10px"); + hres = IHTMLStyle_put_borderTopWidth(style, v); + ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres); + VariantClear(&v); + + hres = IHTMLStyle_get_borderTopWidth(style, &v); + ok(hres == S_OK, "get_borderTopWidth: %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + hres = IHTMLStyle_put_borderTopWidth(style, vDefault); + ok(hres == S_OK, "put_borderTopWidth: %08x\n", hres); + VariantClear(&vDefault); + + /* borderRightWidth */ + hres = IHTMLStyle_get_borderRightWidth(style, &vDefault); + ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("10"); + hres = IHTMLStyle_put_borderRightWidth(style, v); + ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres); + VariantClear(&v); + + hres = IHTMLStyle_get_borderRightWidth(style, &v); + ok(hres == S_OK, "get_borderRightWidth: %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + hres = IHTMLStyle_put_borderRightWidth(style, vDefault); + ok(hres == S_OK, "put_borderRightWidth: %08x\n", hres); + VariantClear(&vDefault); + + /* borderBottomWidth */ + hres = IHTMLStyle_get_borderBottomWidth(style, &vDefault); + ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("10"); + hres = IHTMLStyle_put_borderBottomWidth(style, v); + ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres); + VariantClear(&v); + + hres = IHTMLStyle_get_borderBottomWidth(style, &v); + ok(hres == S_OK, "get_borderBottomWidth: %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "10px"), "expected 10px = %s\n", dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + hres = IHTMLStyle_put_borderBottomWidth(style, vDefault); + ok(hres == S_OK, "put_borderBottomWidth: %08x\n", hres); + VariantClear(&vDefault); + hres = IHTMLStyle_QueryInterface(style, &IID_IHTMLStyle2, (void**)&style2); ok(hres == S_OK, "Could not get IHTMLStyle2 iface: %08x\n", hres); if(SUCCEEDED(hres)) { diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 46fde5a1d95..ee8af399594 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -7775,6 +7775,12 @@ static void test_appsearch_reglocator(void) ok(!lstrcmpA(prop, "#-42"), "Expected \"#-42\", got \"%s\"\n", prop); size = ExpandEnvironmentStringsA("%PATH%", NULL, 0); + if (size == 0 && GetLastError() == ERROR_INVALID_PARAMETER) + { + /* Workaround for Win95 */ + CHAR tempbuf[1]; + size = ExpandEnvironmentStringsA("%PATH%", tempbuf, 0); + } pathvar = HeapAlloc(GetProcessHeap(), 0, size); ExpandEnvironmentStringsA("%PATH%", pathvar, size); diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h index fd1ad3b347d..6ea9ab1ca81 100644 --- a/dlls/msvcrt/scanf.h +++ b/dlls/msvcrt/scanf.h @@ -79,7 +79,7 @@ _FUNCTION_ { if (!*format) return 0; #ifndef WIDE_SCANF #ifdef CONSOLE - TRACE("(%s): \n", debugstr_a(format)); + TRACE("(%s):\n", debugstr_a(format)); #else /* CONSOLE */ #ifdef STRING TRACE("%s (%s)\n", file, debugstr_a(format)); diff --git a/dlls/netapi32/access.c b/dlls/netapi32/access.c index 84d280b048a..db22655b0a9 100644 --- a/dlls/netapi32/access.c +++ b/dlls/netapi32/access.c @@ -658,7 +658,7 @@ NetQueryDisplayInformation( admin_size - sizeof(NET_DISPLAY_USER) + guest_size - sizeof(NET_DISPLAY_USER), SortedBuffer); - inf = (PNET_DISPLAY_USER) *SortedBuffer; + inf = *SortedBuffer; str = (LPWSTR) ((PBYTE) inf + sizeof(NET_DISPLAY_USER) * records); inf->usri1_name = str; str = (LPWSTR) ( @@ -826,8 +826,7 @@ NET_API_STATUS WINAPI NetUserModalsGet( } umi = (USER_MODALS_INFO_2 *) *pbuffer; - umi->usrmod2_domain_id = (PSID)(*pbuffer + - sizeof(USER_MODALS_INFO_2)); + umi->usrmod2_domain_id = *pbuffer + sizeof(USER_MODALS_INFO_2); umi->usrmod2_domain_name = (LPWSTR)(*pbuffer + sizeof(USER_MODALS_INFO_2) + GetLengthSid(domainIdentifier)); diff --git a/dlls/netapi32/nbt.c b/dlls/netapi32/nbt.c index b840a412fdb..0bddd946c66 100644 --- a/dlls/netapi32/nbt.c +++ b/dlls/netapi32/nbt.c @@ -400,7 +400,7 @@ typedef struct _NetBTNameQueryData { static BOOL NetBTFindNameAnswerCallback(void *pVoid, WORD answerCount, WORD answerIndex, PUCHAR rData, WORD rLen) { - NetBTNameQueryData *queryData = (NetBTNameQueryData *)pVoid; + NetBTNameQueryData *queryData = pVoid; BOOL ret; if (queryData) @@ -696,7 +696,7 @@ typedef struct _NetBTNodeQueryData static BOOL NetBTNodeStatusAnswerCallback(void *pVoid, WORD answerCount, WORD answerIndex, PUCHAR rData, WORD rLen) { - NetBTNodeQueryData *data = (NetBTNodeQueryData *)pVoid; + NetBTNodeQueryData *data = pVoid; if (data && !data->gotResponse && rData && rLen >= 1) { @@ -811,7 +811,7 @@ static UCHAR NetBTAstatRemote(NetBTAdapter *adapter, PNCB ncb) static UCHAR NetBTAstat(void *adapt, PNCB ncb) { - NetBTAdapter *adapter = (NetBTAdapter *)adapt; + NetBTAdapter *adapter = adapt; UCHAR ret; TRACE("adapt %p, NCB %p\n", adapt, ncb); @@ -856,7 +856,7 @@ static UCHAR NetBTAstat(void *adapt, PNCB ncb) static UCHAR NetBTFindName(void *adapt, PNCB ncb) { - NetBTAdapter *adapter = (NetBTAdapter *)adapt; + NetBTAdapter *adapter = adapt; UCHAR ret; const NBNameCacheEntry *cacheEntry = NULL; PFIND_NAME_HEADER foundName; @@ -973,7 +973,7 @@ static UCHAR NetBTSessionReq(SOCKET fd, const UCHAR *calledName, static UCHAR NetBTCall(void *adapt, PNCB ncb, void **sess) { - NetBTAdapter *adapter = (NetBTAdapter *)adapt; + NetBTAdapter *adapter = adapt; UCHAR ret; const NBNameCacheEntry *cacheEntry = NULL; @@ -1074,8 +1074,8 @@ static UCHAR NetBTCall(void *adapt, PNCB ncb, void **sess) */ static UCHAR NetBTSend(void *adapt, void *sess, PNCB ncb) { - NetBTAdapter *adapter = (NetBTAdapter *)adapt; - NetBTSession *session = (NetBTSession *)sess; + NetBTAdapter *adapter = adapt; + NetBTSession *session = sess; UCHAR buffer[NBSS_HDRSIZE], ret; int r; WSABUF wsaBufs[2]; @@ -1123,8 +1123,8 @@ static UCHAR NetBTSend(void *adapt, void *sess, PNCB ncb) static UCHAR NetBTRecv(void *adapt, void *sess, PNCB ncb) { - NetBTAdapter *adapter = (NetBTAdapter *)adapt; - NetBTSession *session = (NetBTSession *)sess; + NetBTAdapter *adapter = adapt; + NetBTSession *session = sess; UCHAR buffer[NBSS_HDRSIZE], ret; int r; WSABUF wsaBufs[2]; @@ -1231,7 +1231,7 @@ error: static UCHAR NetBTHangup(void *adapt, void *sess) { - NetBTSession *session = (NetBTSession *)sess; + NetBTSession *session = sess; TRACE("adapt %p, session %p\n", adapt, session); @@ -1255,7 +1255,7 @@ static void NetBTCleanupAdapter(void *adapt) TRACE("adapt %p\n", adapt); if (adapt) { - NetBTAdapter *adapter = (NetBTAdapter *)adapt; + NetBTAdapter *adapter = adapt; if (adapter->nameCache) NBNameCacheDestroy(adapter->nameCache); @@ -1310,7 +1310,7 @@ static BOOL NetBTEnumCallback(UCHAR totalLANAs, UCHAR lanaIndex, ULONG transport, const NetBIOSAdapterImpl *data, void *closure) { BOOL ret; - PMIB_IPADDRTABLE table = (PMIB_IPADDRTABLE)closure; + PMIB_IPADDRTABLE table = closure; if (table && data) { @@ -1319,7 +1319,7 @@ static BOOL NetBTEnumCallback(UCHAR totalLANAs, UCHAR lanaIndex, ret = FALSE; for (ndx = 0; !ret && ndx < table->dwNumEntries; ndx++) { - const NetBTAdapter *adapter = (const NetBTAdapter *)data->data; + const NetBTAdapter *adapter = data->data; if (table->table[ndx].dwIndex == adapter->ipr.dwIndex) { diff --git a/dlls/netapi32/netbios.c b/dlls/netapi32/netbios.c index 8d0de1f039e..89b2c2aa316 100644 --- a/dlls/netapi32/netbios.c +++ b/dlls/netapi32/netbios.c @@ -762,7 +762,7 @@ static UCHAR nbDispatch(NetBIOSAdapter *adapter, PNCB ncb) static DWORD WINAPI nbCmdThread(LPVOID lpVoid) { - PNCB ncb = (PNCB)lpVoid; + PNCB ncb = lpVoid; if (ncb) { diff --git a/dlls/netapi32/tests/apibuf.c b/dlls/netapi32/tests/apibuf.c index 2438ecd7e44..0972e76569a 100644 --- a/dlls/netapi32/tests/apibuf.c +++ b/dlls/netapi32/tests/apibuf.c @@ -42,12 +42,12 @@ static void run_apibuf_tests(void) NET_API_STATUS res; /* test normal logic */ - ok(pNetApiBufferAllocate(1024, (LPVOID *)&p) == NERR_Success, + ok(pNetApiBufferAllocate(1024, &p) == NERR_Success, "Reserved memory\n"); ok(pNetApiBufferSize(p, &dwSize) == NERR_Success, "Got size\n"); ok(dwSize >= 1024, "The size is correct\n"); - ok(pNetApiBufferReallocate(p, 1500, (LPVOID *) &p) == NERR_Success, + ok(pNetApiBufferReallocate(p, 1500, &p) == NERR_Success, "Reallocated\n"); ok(pNetApiBufferSize(p, &dwSize) == NERR_Success, "Got size\n"); ok(dwSize >= 1500, "The size is correct\n"); @@ -58,14 +58,14 @@ static void run_apibuf_tests(void) ok(pNetApiBufferSize(NULL, &dwSize) == ERROR_INVALID_PARAMETER, "Error for NULL pointer\n"); /* border reallocate cases */ - ok(pNetApiBufferReallocate(0, 1500, (LPVOID *) &p) == NERR_Success, "Reallocate with OldBuffer = NULL failed\n"); + ok(pNetApiBufferReallocate(0, 1500, &p) == NERR_Success, "Reallocate with OldBuffer = NULL failed\n"); ok(p != NULL, "No memory got allocated\n"); - ok(pNetApiBufferAllocate(1024, (LPVOID *)&p) == NERR_Success, "Memory not reserved\n"); - ok(pNetApiBufferReallocate(p, 0, (LPVOID *) &p) == NERR_Success, "Not freed\n"); + ok(pNetApiBufferAllocate(1024, &p) == NERR_Success, "Memory not reserved\n"); + ok(pNetApiBufferReallocate(p, 0, &p) == NERR_Success, "Not freed\n"); ok(p == NULL, "Pointer not cleared\n"); - + /* 0-length buffer */ - ok(pNetApiBufferAllocate(0, (LPVOID *)&p) == NERR_Success, + ok(pNetApiBufferAllocate(0, &p) == NERR_Success, "Reserved memory\n"); ok(pNetApiBufferSize(p, &dwSize) == NERR_Success, "Got size\n"); ok(dwSize < 0xFFFFFFFF, "The size of the 0-length buffer\n"); diff --git a/dlls/netapi32/wksta.c b/dlls/netapi32/wksta.c index 7b39fd98fab..67690b8670e 100644 --- a/dlls/netapi32/wksta.c +++ b/dlls/netapi32/wksta.c @@ -157,8 +157,7 @@ static BOOL WkstaEnumAdaptersCallback(UCHAR totalLANAs, UCHAR lanaIndex, ULONG transport, const NetBIOSAdapterImpl *data, void *closure) { BOOL ret; - struct WkstaTransportEnumData *enumData = (struct WkstaTransportEnumData *) - closure; + struct WkstaTransportEnumData *enumData = closure; if (enumData && enumData->pbuf) { diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c index c8d3b29a891..48457c84c4f 100644 --- a/dlls/ntdll/serial.c +++ b/dlls/ntdll/serial.c @@ -486,7 +486,7 @@ static NTSTATUS set_baud_rate(int fd, const SERIAL_BAUD_RATE* sbr) "a non-standard baud rate %d. Wine will set the rate to %d,\n" "which is as close as we can get by our present understanding of your\n" "hardware. I hope you know what you are doing. Any disruption Wine\n" - "has caused to your linux system can be undone with setserial \n" + "has caused to your linux system can be undone with setserial\n" "(see man setserial). If you have incapacitated a Hayes type modem,\n" "reset it and it will probably recover.\n", sbr->BaudRate, arby); ioctl(fd, TIOCSSERIAL, &nuts); diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 32db8101bb9..0b7c25b6c81 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -636,7 +636,7 @@ static void wine_sigacthandler( int signal, siginfo_t *siginfo, void *sigcontext __asm__ __volatile__("mov %ss,%ax; mov %ax,%ds; mov %ax,%es"); - thread_data = get_current_teb()->SystemReserved2; + thread_data = (struct ntdll_thread_data *)get_current_teb()->SystemReserved2; wine_set_fs( thread_data->fs ); wine_set_gs( thread_data->gs ); @@ -672,7 +672,6 @@ typedef void (WINAPI *raise_func)( EXCEPTION_RECORD *rec, CONTEXT *context ); static inline void *init_handler( const SIGCONTEXT *sigcontext, WORD *fs, WORD *gs ) { TEB *teb = get_current_teb(); - struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; /* get %fs and %gs at time of the fault */ #ifdef FS_sig @@ -687,8 +686,11 @@ static inline void *init_handler( const SIGCONTEXT *sigcontext, WORD *fs, WORD * #endif #ifndef __sun /* see above for Solaris handling */ - wine_set_fs( thread_data->fs ); - wine_set_gs( thread_data->gs ); + { + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + wine_set_fs( thread_data->fs ); + wine_set_gs( thread_data->gs ); + } #endif if (!wine_ldt_is_system(CS_sig(sigcontext)) || diff --git a/dlls/ntdll/tests/port.c b/dlls/ntdll/tests/port.c index c63820a37fd..51707e3c3aa 100644 --- a/dlls/ntdll/tests/port.c +++ b/dlls/ntdll/tests/port.c @@ -90,10 +90,7 @@ static const WCHAR PORTNAME[] = {'\\','M','y','P','o','r','t',0}; #define MAX_MESSAGE_LEN 30 -UNICODE_STRING port; -static char selfname[MAX_PATH]; -static int myARGC; -static char** myARGV; +static UNICODE_STRING port; /* Function pointers for ntdll calls */ static HMODULE hntdll = 0; @@ -155,10 +152,10 @@ static void ProcessConnectionRequest(PLPC_MESSAGE LpcMessage, PHANDLE pAcceptPor ok(!*LpcMessage->Data, "Expected empty string!\n"); status = pNtAcceptConnectPort(pAcceptPortHandle, 0, LpcMessage, 1, 0, NULL); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); status = pNtCompleteConnectPort(*pAcceptPortHandle); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); } static void ProcessLpcRequest(HANDLE PortHandle, PLPC_MESSAGE LpcMessage) @@ -173,7 +170,7 @@ static void ProcessLpcRequest(HANDLE PortHandle, PLPC_MESSAGE LpcMessage) lstrcpy((LPSTR)LpcMessage->Data, REPLY); status = pNtReplyPort(PortHandle, LpcMessage); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); ok(LpcMessage->MessageType == LPC_REQUEST, "Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType); ok(!lstrcmp((LPSTR)LpcMessage->Data, REPLY), @@ -194,11 +191,11 @@ static DWORD WINAPI test_ports_client(LPVOID arg) sqos.EffectiveOnly = TRUE; status = pNtConnectPort(&PortHandle, &port, &sqos, 0, 0, &len, NULL, NULL); - todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); if (status != STATUS_SUCCESS) return 1; status = pNtRegisterThreadTerminatePort(PortHandle); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN; LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); @@ -209,7 +206,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg) lstrcpy((LPSTR)LpcMessage->Data, REQUEST1); status = pNtRequestPort(PortHandle, LpcMessage); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); ok(LpcMessage->MessageType == 0, "Expected 0, got %d\n", LpcMessage->MessageType); ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1), "Expected %s, got %s\n", REQUEST1, LpcMessage->Data); @@ -222,7 +219,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg) /* Send the message and wait for the reply */ status = pNtRequestWaitReplyPort(PortHandle, LpcMessage, out); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status); ok(!lstrcmp((LPSTR)out->Data, REPLY), "Expected %s, got %s\n", REPLY, out->Data); ok(out->MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->MessageType); @@ -232,34 +229,14 @@ static DWORD WINAPI test_ports_client(LPVOID arg) return 0; } -static void test_ports_server(void) +static void test_ports_server( HANDLE PortHandle ) { - OBJECT_ATTRIBUTES obj; - HANDLE PortHandle; HANDLE AcceptPortHandle; PLPC_MESSAGE LpcMessage; ULONG size; NTSTATUS status; BOOL done = FALSE; - pRtlInitUnicodeString(&port, PORTNAME); - - memset(&obj, 0, sizeof(OBJECT_ATTRIBUTES)); - obj.Length = sizeof(OBJECT_ATTRIBUTES); - obj.ObjectName = &port; - - status = pNtCreatePort(&PortHandle, &obj, 100, 100, 0); - if (status == STATUS_ACCESS_DENIED) - { - skip("Not enough rights\n"); - return; - } - todo_wine - { - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); - } - if (status != STATUS_SUCCESS) return; - size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN; LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); @@ -308,20 +285,32 @@ static void test_ports_server(void) START_TEST(port) { - HANDLE thread; - DWORD id; + OBJECT_ATTRIBUTES obj; + HANDLE port_handle; + NTSTATUS status; if (!init_function_ptrs()) return; - myARGC = winetest_get_mainargs(&myARGV); - strcpy(selfname, myARGV[0]); + pRtlInitUnicodeString(&port, PORTNAME); - thread = CreateThread(NULL, 0, test_ports_client, NULL, 0, &id); - ok(thread != NULL, "Expected non-NULL thread handle!\n"); + memset(&obj, 0, sizeof(OBJECT_ATTRIBUTES)); + obj.Length = sizeof(OBJECT_ATTRIBUTES); + obj.ObjectName = &port; - test_ports_server(); - CloseHandle(thread); + status = pNtCreatePort(&port_handle, &obj, 100, 100, 0); + if (status == STATUS_ACCESS_DENIED) skip("Not enough rights\n"); + else todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status); + if (status == STATUS_SUCCESS) + { + DWORD id; + HANDLE thread = CreateThread(NULL, 0, test_ports_client, NULL, 0, &id); + ok(thread != NULL, "Expected non-NULL thread handle!\n"); + + test_ports_server( port_handle ); + ok( WaitForSingleObject( thread, 10000 ) == 0, "thread didn't exit\n" ); + CloseHandle(thread); + } FreeLibrary(hntdll); } diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index b8ddba8af72..711f341e278 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -934,6 +934,7 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret) } else { + HeapFree(GetProcessHeap(), 0, entry); hr = E_OUTOFMEMORY; FreeLibrary(hLibrary); } diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c index 0e8cab3ba44..ae225dc1b4c 100644 --- a/dlls/ole32/ole2.c +++ b/dlls/ole32/ole2.c @@ -2642,6 +2642,7 @@ static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt) case VT_BSTR: case VT_ERROR: case VT_BOOL: + case VT_DECIMAL: case VT_UI1: case VT_UI2: case VT_UI4: @@ -2712,6 +2713,7 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */ case VT_DATE: case VT_ERROR: case VT_BOOL: + case VT_DECIMAL: case VT_UI1: case VT_UI2: case VT_UI4: @@ -2799,7 +2801,7 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ ULONG len; HRESULT hr; - TRACE("(%p, %p)\n", pvarDest, pvarSrc); + TRACE("(%p, %p vt %04x)\n", pvarDest, pvarSrc, pvarSrc->vt); hr = PROPVARIANT_ValidateType(pvarSrc->vt); if (FAILED(hr)) @@ -2817,6 +2819,7 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ case VT_I2: case VT_UI2: case VT_BOOL: + case VT_DECIMAL: case VT_I4: case VT_UI4: case VT_R4: diff --git a/dlls/ole32/tests/dragdrop.c b/dlls/ole32/tests/dragdrop.c index b7599814ba8..b28a8313e1a 100644 --- a/dlls/ole32/tests/dragdrop.c +++ b/dlls/ole32/tests/dragdrop.c @@ -31,9 +31,6 @@ #include "wine/test.h" -/* functions that are not present on all versions of Windows */ -HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); - static int droptarget_addref_called; static int droptarget_release_called; diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c index f1cbc76ecdc..380dc141652 100644 --- a/dlls/ole32/tests/propvariant.c +++ b/dlls/ole32/tests/propvariant.c @@ -23,13 +23,14 @@ #include "wine/test.h" /* invalid in all versions */ -#define PROP_INV 255 +#define PROP_INV 0x7f /* valid in v0 and above (NT4+) */ #define PROP_V0 0 /* valid in v1 and above (Win2k+) */ #define PROP_V1 1 /* valid in v1a and above (WinXP+) */ #define PROP_V1A 2 +#define PROP_TODO 0x80 struct valid_mapping { @@ -41,28 +42,28 @@ struct valid_mapping { { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_EMPTY */ { PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_NULL */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_I2 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_I4 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_R4 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_R8 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_CY */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_DATE */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_BSTR */ - { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 }, /* VT_DISPATCH */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_ERROR */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_BOOL */ - { PROP_V1 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_VARIANT */ - { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 }, /* VT_UNKNOWN */ - { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 }, /* VT_DECIMAL */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I2 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I4 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R4 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R8 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_CY */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_DATE */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BSTR */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DISPATCH */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_ERROR */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BOOL */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_VARIANT */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UNKNOWN */ + { PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DECIMAL */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 15 */ - { PROP_V1 , PROP_V1 , PROP_V1 , PROP_V1 }, /* VT_I1 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_UI1 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_UI2 */ - { PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 }, /* VT_UI4 */ - { PROP_V0 , PROP_V1A, PROP_V0 , PROP_V1A }, /* VT_I8 */ - { PROP_V0 , PROP_V1A, PROP_V0 , PROP_V1A }, /* VT_UI8 */ - { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 }, /* VT_INT */ - { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 }, /* VT_UINT */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO }, /* VT_I1 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI1 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI2 */ + { PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI4 */ + { PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_I8 */ + { PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_UI8 */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_INT */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UINT */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_VOID */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_HRESULT */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_PTR */ @@ -75,7 +76,7 @@ struct valid_mapping { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 33 */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 34 */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 35 */ - { PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 }, /* VT_RECORD */ + { PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_RECORD */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_INT_PTR */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_UINT_PTR */ { PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 39 */ @@ -126,74 +127,83 @@ static const char* wine_vtypes[VT_CLSID+1] = "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID" }; -static void test_validtypes(void) + +static void expect(HRESULT hr, VARTYPE vt) { - PROPVARIANT propvar; - HRESULT hr; - unsigned int i; - BYTE version; + int idx = vt & VT_TYPEMASK; + BYTE flags; + const char *modifier; - memset(&propvar, 0, sizeof(propvar)); + if(vt & VT_BYREF) + { + flags = valid_types[idx].byref; + modifier = "byref"; + } + else if(vt & VT_ARRAY) + { + flags = valid_types[idx].with_array; + modifier = "array"; + } + else if(vt & VT_VECTOR) + { + flags = valid_types[idx].with_vector; + modifier = "vector"; + } + else + { + flags = valid_types[idx].simple; + modifier = "simple"; + } - /* detect version */ - propvar.vt = VT_I2 | VT_ARRAY; - hr = PropVariantClear(&propvar); - if (hr == S_OK) + if(flags == PROP_INV) + ok(hr == STG_E_INVALIDPARAMETER, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); + else if(flags == PROP_V0) + ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); + else if(flags & PROP_TODO) { - propvar.vt = VT_I8 | VT_ARRAY; - hr = PropVariantClear(&propvar); - if (hr == S_OK) - { - version = PROP_V1A; - trace("detected prop variant v1a\n"); - } - else + todo_wine { - version = PROP_V1; - trace("detected prop variant v1\n"); + if(hr != S_OK) + win_skip("%s (%s): unsupported\n", wine_vtypes[idx], modifier); + else ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); } } else { - version = PROP_V0; - trace("detected prop variant v0\n"); + if(hr != S_OK) + win_skip("%s (%s): unsupported\n", wine_vtypes[idx], modifier); + else ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); } +} + +static void test_validtypes(void) +{ + PROPVARIANT propvar; + HRESULT hr; + unsigned int i; + + memset(&propvar, 0, sizeof(propvar)); for (i = 0; i < sizeof(valid_types)/sizeof(valid_types[0]); i++) { - BOOL expected_result; + VARTYPE vt; - propvar.vt = i; + vt = propvar.vt = i; hr = PropVariantClear(&propvar); - expected_result = (valid_types[i].simple <= version ? TRUE : FALSE); - ok(expected_result == !(hr == STG_E_INVALIDPARAMETER), - "PropVariantClear(%s) should have returned 0x%08x, but returned 0x%08x\n", - wine_vtypes[i], - expected_result ? S_OK : STG_E_INVALIDPARAMETER, hr); + expect(hr, vt); - propvar.vt = i | VT_ARRAY; + vt = propvar.vt = i | VT_ARRAY; hr = PropVariantClear(&propvar); - expected_result = (valid_types[i].with_array <= version ? TRUE : FALSE); - ok(expected_result == !(hr == STG_E_INVALIDPARAMETER), - "PropVariantClear(%s|VT_ARRAY) should have returned 0x%08x, but returned 0x%08x\n", - wine_vtypes[i], - expected_result ? S_OK : STG_E_INVALIDPARAMETER, hr); + expect(hr, vt); - propvar.vt = i | VT_VECTOR; + vt = propvar.vt = i | VT_VECTOR; hr = PropVariantClear(&propvar); - expected_result = (valid_types[i].with_vector <= version ? TRUE : FALSE); - ok(expected_result == !(hr == STG_E_INVALIDPARAMETER), - "PropVariantClear(%s|VT_VECTOR) should have returned 0x%08x, but returned 0x%08x\n", - wine_vtypes[i], - expected_result ? S_OK : STG_E_INVALIDPARAMETER, hr); + expect(hr, vt); - propvar.vt = i | VT_BYREF; + vt = propvar.vt = i | VT_BYREF; hr = PropVariantClear(&propvar); - expected_result = (valid_types[i].byref <= version ? TRUE : FALSE); - ok(expected_result == !(hr == STG_E_INVALIDPARAMETER), - "PropVariantClear(%s|VT_BYREF) should have returned 0x%08x, but returned 0x%08x\n", - wine_vtypes[i], - expected_result ? S_OK : STG_E_INVALIDPARAMETER, hr); + expect(hr, vt); + } } diff --git a/dlls/qmgr/qmgr.c b/dlls/qmgr/qmgr.c index 5fdd1219d6d..1ff6050301e 100644 --- a/dlls/qmgr/qmgr.c +++ b/dlls/qmgr/qmgr.c @@ -157,7 +157,14 @@ DWORD WINAPI fileTransfer(void *param) /* Check if it's the stop_event */ if (WaitForMultipleObjects(2, events, FALSE, INFINITE) == WAIT_OBJECT_0) + { + LIST_FOR_EACH_ENTRY_SAFE(job, jobCur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr) + { + list_remove(&job->entryFromQmgr); + IBackgroundCopyJob_Release((IBackgroundCopyJob *) job); + } return 0; + } /* Note that other threads may add files to the job list, but only this thread ever deletes them so we don't need to worry about jobs diff --git a/dlls/qmgr/service.c b/dlls/qmgr/service.c index 1e0a5450270..b7dc7c39566 100644 --- a/dlls/qmgr/service.c +++ b/dlls/qmgr/service.c @@ -153,4 +153,6 @@ ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv) UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0); CloseHandle(stop_event); TRACE("service stoped\n"); + + CoUninitialize(); } diff --git a/dlls/qmgr/tests/job.c b/dlls/qmgr/tests/job.c index 36201f8194f..d0e2306bfc0 100644 --- a/dlls/qmgr/tests/job.c +++ b/dlls/qmgr/tests/job.c @@ -24,6 +24,7 @@ #include "wine/test.h" #include "bits.h" +#include "initguid.h" /* Globals used by many tests */ static const WCHAR test_displayName[] = {'T', 'e', 's', 't', 0}; @@ -123,6 +124,49 @@ static void teardown(void) IBackgroundCopyManager_Release(test_manager); } +/* FIXME: Remove when Wine has implemented this */ +DEFINE_GUID(CLSID_BackgroundCopyManager2_0, 0x6d18ad12, 0xbde3, 0x4393, 0xb3,0x11, 0x09,0x9c,0x34,0x6e,0x6d,0xf9); + +static BOOL check_bits20(void) +{ + HRESULT hres; + IBackgroundCopyManager *manager; + BOOL ret = TRUE; + + hres = CoCreateInstance(&CLSID_BackgroundCopyManager2_0, NULL, + CLSCTX_LOCAL_SERVER, + &IID_IBackgroundCopyManager, + (void **) &manager); + + if (hres == REGDB_E_CLASSNOTREG) + { + ret = FALSE; + + /* FIXME: Wine implements 2.0 functionality but doesn't advertise 2.0 + * + * Remove when Wine is fixed + */ + if (setup()) + { + HRESULT hres2; + + hres2 = IBackgroundCopyJob_AddFile(test_job, test_remotePathA, + test_localPathA); + if (hres2 == S_OK) + { + trace("Running on Wine, claim 2.0 is present\n"); + ret = TRUE; + } + teardown(); + } + } + + if (manager) + IBackgroundCopyManager_Release(manager); + + return ret; +} + /* Test that the jobId is properly set */ static void test_GetId(void) { @@ -486,12 +530,15 @@ START_TEST(job) test_GetId, test_GetType, test_GetName, - test_AddFile, - test_AddFileSet, - test_EnumFiles, test_GetProgress_preTransfer, test_GetState, test_ResumeEmpty, + 0 + }; + static const test_t tests_bits20[] = { + test_AddFile, + test_AddFileSet, + test_EnumFiles, test_CompleteLocal, test_CompleteLocalURL, 0 @@ -502,6 +549,7 @@ START_TEST(job) return; CoInitialize(NULL); + for (test = tests; *test; ++test) { /* Keep state separate between tests. */ @@ -513,5 +561,25 @@ START_TEST(job) (*test)(); teardown(); } + + if (check_bits20()) + { + for (test = tests_bits20; *test; ++test) + { + /* Keep state separate between tests. */ + if (!setup()) + { + skip("Unable to setup test\n"); + break; + } + (*test)(); + teardown(); + } + } + else + { + win_skip("Tests need BITS 2.0 or higher\n"); + } + CoUninitialize(); } diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 09feb960da4..c9cb244a4d9 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2018,11 +2018,14 @@ ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam) { MSGFILTER msgf; + if (!editor->hWnd) return FALSE; + msgf.nmhdr.hwndFrom = editor->hWnd; + msgf.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID); msgf.nmhdr.code = EN_MSGFILTER; msgf.msg = msg; msgf.wParam = *wParam; msgf.lParam = *lParam; - if (ITextHost_TxNotify(editor->texthost, msgf.nmhdr.code, &msgf) == S_OK) + if (SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf)) return FALSE; *wParam = msgf.wParam; *lParam = msgf.lParam; @@ -2037,6 +2040,8 @@ static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor) ME_DisplayItem *prev_para; int from, to; + if (!editor->AutoURLDetect_bEnable) return; + ME_GetSelection(editor, &from, &to); /* Find paragraph previous to the one that contains start cursor */ @@ -2232,9 +2237,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) ME_CommitCoalescingUndo(editor); SetCursor(NULL); - if (editor->AutoURLDetect_bEnable) - ME_UpdateSelectionLinkAttribute(editor); - + ME_UpdateSelectionLinkAttribute(editor); ME_UpdateRepaint(editor); } return TRUE; @@ -2393,8 +2396,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, ITextHost_TxSetCursor(editor->texthost, NULL, FALSE); } - if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); - + ME_UpdateSelectionLinkAttribute(editor); ME_UpdateRepaint(editor); } return 0; @@ -2515,22 +2517,20 @@ static BOOL ME_SetCursor(ME_TextEditor *editor) offset = ME_CharFromPos(editor, pt.x, pt.y, &isExact); if (isExact) { - if (editor->AutoURLDetect_bEnable) + ME_Cursor cursor; + ME_Run *run; + + ME_CursorFromCharOfs(editor, offset, &cursor); + run = &cursor.pRun->member.run; + if (run->style->fmt.dwMask & CFM_LINK && + run->style->fmt.dwEffects & CFE_LINK) { - ME_Cursor cursor; - ME_Run *run; - ME_CursorFromCharOfs(editor, offset, &cursor); - run = &cursor.pRun->member.run; - if (editor->AutoURLDetect_bEnable && - run->style->fmt.dwMask & CFM_LINK && - run->style->fmt.dwEffects & CFE_LINK) - { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_HAND), - FALSE); - return TRUE; - } + ITextHost_TxSetCursor(editor->texthost, + LoadCursorW(NULL, (WCHAR*)IDC_HAND), + FALSE); + return TRUE; } + if (ME_IsSelection(editor)) { int selStart, selEnd; @@ -3231,12 +3231,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, if (bSelection) { ME_ReleaseStyle(style); - if (editor->AutoURLDetect_bEnable) - ME_UpdateSelectionLinkAttribute(editor); + ME_UpdateSelectionLinkAttribute(editor); } else { len = 1; - if (editor->AutoURLDetect_bEnable) - ME_UpdateLinkAttribute(editor, 0, -1); + ME_UpdateLinkAttribute(editor, 0, -1); } ME_CommitUndo(editor); if (!(pStruct->flags & ST_KEEPUNDO)) @@ -3430,7 +3428,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_ClearTempStyle(editor); ME_EndToUnicode(unicode, wszText); ME_CommitUndo(editor); - if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor); + ME_UpdateSelectionLinkAttribute(editor); if (!wParam) ME_EmptyUndoStack(editor); ME_UpdateRepaint(editor); @@ -3498,10 +3496,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } else TRACE("WM_SETTEXT - NULL\n"); - if (editor->AutoURLDetect_bEnable) - { - ME_UpdateLinkAttribute(editor, 0, -1); - } + ME_UpdateLinkAttribute(editor, 0, -1); ME_SetSelection(editor, 0, 0); editor->nModifyStep = 0; ME_CommitUndo(editor); @@ -4847,6 +4842,8 @@ static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, int sel_min, int sel_m BOOL modified = FALSE; int cMin, cMax; + if (!editor->AutoURLDetect_bEnable) return FALSE; + if (sel_max == -1) sel_max = ME_GetTextLength(editor); do { diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index f8da3faf109..331fd692def 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -3282,7 +3282,7 @@ static void test_WM_SETTEXT(void) memset(buf, 0, sizeof(buf)); SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_RTF), (LPARAM)&es); - trace("EM_STREAMOUT produced: \n%s\n", buf); + trace("EM_STREAMOUT produced:\n%s\n", buf); TEST_SETTEXT(buf, TestItem1) #undef TEST_SETTEXT @@ -3618,7 +3618,7 @@ static void test_EM_SETTEXTEX(void) memset(buf, 0, sizeof(buf)); SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_RTF), (LPARAM)&es); - trace("EM_STREAMOUT produced: \n%s\n", (char *)buf); + trace("EM_STREAMOUT produced:\n%s\n", (char *)buf); /* !ST_SELECTION && !Unicode && \rtf */ setText.codepage = CP_ACP;/* EM_STREAMOUT saved as ANSI string */ @@ -3659,7 +3659,7 @@ static void test_EM_SETTEXTEX(void) memset(buf, 0, sizeof(buf)); SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_RTF), (LPARAM)&es); - trace("EM_STREAMOUT produced: \n%s\n", (char *)buf); + trace("EM_STREAMOUT produced:\n%s\n", (char *)buf); /* select some text */ cr.cpMax = 1; diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c index 5032e8729f6..8fabd8388d1 100644 --- a/dlls/riched20/txthost.c +++ b/dlls/riched20/txthost.c @@ -452,8 +452,6 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface, HWND parent = GetParent(hwnd); UINT id = GetWindowLongW(hwnd, GWLP_ID); - /* Note: EN_MSGFILTER is documented as not being sent to TxNotify */ - switch (iNotify) { case EN_DROPFILES: @@ -492,6 +490,9 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface, SendMessageW(parent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd); break; + case EN_MSGFILTER: + FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n"); + /* fall through */ default: return E_FAIL; } diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c index 8e12b2a7d3e..8afa931b8e4 100644 --- a/dlls/rsaenh/tests/rsaenh.c +++ b/dlls/rsaenh/tests/rsaenh.c @@ -106,7 +106,7 @@ static void trace_hex(BYTE *pbData, DWORD dwLen) { trace(szTemp); } for (j=0; i +#include +#include #include "windef.h" #include "winbase.h" #include "twain.h" #include "sane_i.h" +#include "winnls.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(twain); +#ifndef SANE_VALUE_SCAN_MODE_COLOR +#define SANE_VALUE_SCAN_MODE_COLOR SANE_I18N("Color") +#endif +#ifndef SANE_VALUE_SCAN_MODE_GRAY +#define SANE_VALUE_SCAN_MODE_GRAY SANE_I18N("Gray") +#endif +#ifndef SANE_VALUE_SCAN_MODE_LINEART +#define SANE_VALUE_SCAN_MODE_LINEART SANE_I18N("Lineart") +#endif + static TW_UINT16 get_onevalue(pTW_CAPABILITY pCapability, TW_UINT16 *type, TW_UINT32 *value) { if (pCapability->hContainer) @@ -154,8 +167,9 @@ static TW_UINT16 TWAIN_GetSupportedCaps(pTW_CAPABILITY pCapability) { TW_ARRAY *a; static const UINT16 supported_caps[] = { CAP_SUPPORTEDCAPS, CAP_XFERCOUNT, CAP_UICONTROLLABLE, + CAP_AUTOFEED, CAP_FEEDERENABLED, ICAP_XFERMECH, ICAP_PIXELTYPE, ICAP_UNITS, ICAP_BITDEPTH, ICAP_COMPRESSION, ICAP_PIXELFLAVOR, - ICAP_XRESOLUTION, ICAP_YRESOLUTION }; + ICAP_XRESOLUTION, ICAP_YRESOLUTION, ICAP_PHYSICALHEIGHT, ICAP_PHYSICALWIDTH, ICAP_SUPPORTEDSIZES }; pCapability->hContainer = GlobalAlloc (0, FIELD_OFFSET( TW_ARRAY, ItemList[sizeof(supported_caps)] )); pCapability->ConType = TWON_ARRAY; @@ -386,6 +400,7 @@ static TW_UINT16 SANE_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 actio twCC = msg_set(pCapability, &val); if (twCC == TWCC_SUCCESS) { + TRACE("Setting pixeltype to %d\n", val); if (! pixeltype_to_sane_mode(val, mode, sizeof(mode))) return TWCC_BADVALUE; @@ -430,6 +445,7 @@ static TW_UINT16 SANE_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 actio case MSG_GETCURRENT: twCC = set_onevalue(pCapability, TWTY_UINT16, current_pixeltype); + TRACE("Returning current pixeltype of %d\n", current_pixeltype); break; } @@ -507,6 +523,7 @@ static TW_UINT16 SANE_ICAPBitDepth(pTW_CAPABILITY pCapability, TW_UINT16 action) /* .. Fall through intentional .. */ case MSG_GETCURRENT: + TRACE("Returning current bitdepth of %d\n", activeDS.sane_param.depth); twCC = set_onevalue(pCapability, TWTY_UINT16, activeDS.sane_param.depth); break; } @@ -679,12 +696,88 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti return twCC; } +#ifdef SONAME_LIBSANE +static void convert_double_fix32(double d, TW_FIX32 *fix32) +{ + TW_INT32 value = (TW_INT32) (d * 65536.0 + 0.5); + fix32->Whole = value >> 16; + fix32->Frac = value & 0x0000ffffL; +} + +static BOOL convert_sane_res_to_twain(double sane_res, SANE_Unit unit, TW_FIX32 *twain_res, TW_UINT16 twtype) +{ + double d; + + if (unit != SANE_UNIT_MM) + return FALSE; + + if (twtype != TWUN_INCHES) + return FALSE; + + d = (sane_res / 10.0) / 2.54; + convert_double_fix32((sane_res / 10.0) / 2.54, twain_res); + + return TRUE; +} +#endif + +/* ICAP_PHYSICALHEIGHT, ICAP_PHYSICALWIDTH */ +static TW_UINT16 SANE_ICAPPhysical (pTW_CAPABILITY pCapability, TW_UINT16 action, TW_UINT16 cap) +{ + TW_UINT16 twCC = TWCC_BADCAP; +#ifdef SONAME_LIBSANE + TW_FIX32 res; + char option_name[64]; + SANE_Fixed lower, upper; + SANE_Unit lowerunit, upperunit; + SANE_Status status; + + TRACE("ICAP_PHYSICAL%s\n", cap == ICAP_PHYSICALHEIGHT? "HEIGHT" : "WIDTH"); + + sprintf(option_name, "tl-%c", cap == ICAP_PHYSICALHEIGHT ? 'y' : 'x'); + status = sane_option_probe_scan_area(activeDS.deviceHandle, option_name, NULL, &lowerunit, &lower, NULL, NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + + sprintf(option_name, "br-%c", cap == ICAP_PHYSICALHEIGHT ? 'y' : 'x'); + status = sane_option_probe_scan_area(activeDS.deviceHandle, option_name, NULL, &upperunit, NULL, &upper, NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + + if (upperunit != lowerunit) + return TWCC_BADCAP; + + if (! convert_sane_res_to_twain(SANE_UNFIX(upper) - SANE_UNFIX(lower), upperunit, &res, TWUN_INCHES)) + return TWCC_BADCAP; + + switch (action) + { + case MSG_QUERYSUPPORT: + twCC = set_onevalue(pCapability, TWTY_INT32, + TWQC_GET | TWQC_GETDEFAULT | TWQC_GETCURRENT ); + break; + + case MSG_GET: + case MSG_GETDEFAULT: + + /* .. fall through intentional .. */ + + case MSG_GETCURRENT: + twCC = set_onevalue(pCapability, TWTY_FIX32, res.Whole | (res.Frac << 16)); + break; + } +#endif + return twCC; +} + /* ICAP_PIXELFLAVOR */ static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 action) { + TW_UINT16 twCC = TWCC_BADCAP; +#ifdef SONAME_LIBSANE static const TW_UINT32 possible_values[] = { TWPF_CHOCOLATE, TWPF_VANILLA }; TW_UINT32 val; - TW_UINT16 twCC = TWCC_BADCAP; + TW_UINT32 flavor = activeDS.sane_param.depth == 1 ? TWPF_VANILLA : TWPF_CHOCOLATE; TRACE("ICAP_PIXELFLAVOR\n"); @@ -697,7 +790,7 @@ static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 act case MSG_GET: twCC = msg_get_enum(pCapability, possible_values, sizeof(possible_values) / sizeof(possible_values[0]), - TWTY_UINT16, TWPF_CHOCOLATE, TWPF_CHOCOLATE); + TWTY_UINT16, flavor, flavor); break; case MSG_SET: @@ -709,19 +802,383 @@ static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 act break; case MSG_GETDEFAULT: - twCC = set_onevalue(pCapability, TWTY_UINT16, TWPF_CHOCOLATE); + twCC = set_onevalue(pCapability, TWTY_UINT16, flavor); break; case MSG_RESET: /* .. fall through intentional .. */ case MSG_GETCURRENT: - twCC = set_onevalue(pCapability, TWTY_UINT16, TWPF_CHOCOLATE); + twCC = set_onevalue(pCapability, TWTY_UINT16, flavor); break; } +#endif return twCC; } +#ifdef SONAME_LIBSANE +static TW_UINT16 get_width_height(double *width, double *height, BOOL max) +{ + SANE_Status status; + + SANE_Fixed tlx_current, tlx_min, tlx_max; + SANE_Fixed tly_current, tly_min, tly_max; + SANE_Fixed brx_current, brx_min, brx_max; + SANE_Fixed bry_current, bry_min, bry_max; + + status = sane_option_probe_scan_area(activeDS.deviceHandle, "tl-x", &tlx_current, NULL, &tlx_min, &tlx_max, NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + + status = sane_option_probe_scan_area(activeDS.deviceHandle, "tl-y", &tly_current, NULL, &tly_min, &tly_max, NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + + status = sane_option_probe_scan_area(activeDS.deviceHandle, "br-x", &brx_current, NULL, &brx_min, &brx_max, NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + + status = sane_option_probe_scan_area(activeDS.deviceHandle, "br-y", &bry_current, NULL, &bry_min, &bry_max, NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + + if (max) + *width = SANE_UNFIX(brx_max) - SANE_UNFIX(tlx_min); + else + *width = SANE_UNFIX(brx_current) - SANE_UNFIX(tlx_current); + + if (max) + *height = SANE_UNFIX(bry_max) - SANE_UNFIX(tly_min); + else + *height = SANE_UNFIX(bry_current) - SANE_UNFIX(tly_current); + + return(TWCC_SUCCESS); +} + +static TW_UINT16 set_one_coord(const char *name, double coord) +{ + SANE_Status status; + status = sane_option_set_fixed(activeDS.deviceHandle, name, SANE_FIX(coord), NULL); + if (status != SANE_STATUS_GOOD) + return sane_status_to_twcc(status); + return TWCC_SUCCESS; +} + +static TW_UINT16 set_width_height(double width, double height) +{ + TW_UINT16 rc = TWCC_SUCCESS; + rc = set_one_coord("tl-x", 0); + if (rc != TWCC_SUCCESS) + return rc; + rc = set_one_coord("br-x", width); + if (rc != TWCC_SUCCESS) + return rc; + rc = set_one_coord("tl-y", 0); + if (rc != TWCC_SUCCESS) + return rc; + rc = set_one_coord("br-y", height); + + return rc; +} + +typedef struct +{ + TW_UINT32 size; + double x; + double y; +} supported_size_t; + +static const supported_size_t supported_sizes[] = +{ + { TWSS_NONE, 0, 0 }, + { TWSS_A4, 210, 297 }, + { TWSS_JISB5, 182, 257 }, + { TWSS_USLETTER, 215.9, 279.4 }, + { TWSS_USLEGAL, 215.9, 355.6 }, + { TWSS_A5, 148, 210 }, + { TWSS_B4, 250, 353 }, + { TWSS_B6, 125, 176 }, + { TWSS_USLEDGER, 215.9, 431.8 }, + { TWSS_USEXECUTIVE, 184.15, 266.7 }, + { TWSS_A3, 297, 420 }, +}; +#define SUPPORTED_SIZE_COUNT (sizeof(supported_sizes) / sizeof(supported_sizes[0])) + +static TW_UINT16 get_default_paper_size(const supported_size_t *s, int n) +{ + DWORD paper; + int rc; + int defsize = -1; + double width, height; + int i; + rc = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE | LOCALE_RETURN_NUMBER, (void *) &paper, sizeof(paper)); + if (rc > 0) + switch (paper) + { + case 1: + defsize = TWSS_USLETTER; + break; + case 5: + defsize = TWSS_USLEGAL; + break; + case 8: + defsize = TWSS_A3; + break; + case 9: + defsize = TWSS_A4; + break; + } + + if (defsize == -1) + return TWSS_NONE; + + if (get_width_height(&width, &height, TRUE) != TWCC_SUCCESS) + return TWSS_NONE; + + for (i = 0; i < n; i++) + if (s[i].size == defsize) + { + /* Sane's use of integers to store floats is a hair lossy; deal with it */ + if (s[i].x > (width + .01) || s[i].y > (height + 0.01)) + return TWSS_NONE; + else + return s[i].size; + } + + return TWSS_NONE; +} + +static TW_UINT16 get_current_paper_size(const supported_size_t *s, int n) +{ + int i; + double width, height; + double xdelta, ydelta; + + if (get_width_height(&width, &height, FALSE) != TWCC_SUCCESS) + return TWSS_NONE; + + for (i = 0; i < n; i++) + { + /* Sane's use of integers to store floats results + * in a very small error; cope with that */ + xdelta = s[i].x - width; + ydelta = s[i].y - height; + if (xdelta < 0.01 && xdelta > -0.01 && + ydelta < 0.01 && ydelta > -0.01) + return s[i].size; + } + + return TWSS_NONE; +} +#endif + +/* ICAP_SUPPORTEDSIZES */ +static TW_UINT16 SANE_ICAPSupportedSizes (pTW_CAPABILITY pCapability, TW_UINT16 action) +{ + TW_UINT16 twCC = TWCC_BADCAP; +#ifdef SONAME_LIBSANE + + static TW_UINT32 possible_values[SUPPORTED_SIZE_COUNT]; + int i; + TW_UINT32 val; + TW_UINT16 default_size = get_default_paper_size(supported_sizes, SUPPORTED_SIZE_COUNT); + TW_UINT16 current_size = get_current_paper_size(supported_sizes, SUPPORTED_SIZE_COUNT); + + TRACE("ICAP_SUPPORTEDSIZES\n"); + + switch (action) + { + case MSG_QUERYSUPPORT: + twCC = set_onevalue(pCapability, TWTY_INT32, + TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET ); + break; + + case MSG_GET: + for (i = 0; i < sizeof(supported_sizes) / sizeof(supported_sizes[0]); i++) + possible_values[i] = supported_sizes[i].size; + twCC = msg_get_enum(pCapability, possible_values, sizeof(possible_values) / sizeof(possible_values[0]), + TWTY_UINT16, current_size, default_size); + WARN("Partial Stub: our supported size selection is a bit thin.\n"); + break; + + case MSG_SET: + twCC = msg_set(pCapability, &val); + if (twCC == TWCC_SUCCESS) + for (i = 1; i < SUPPORTED_SIZE_COUNT; i++) + if (supported_sizes[i].size == val) + return set_width_height(supported_sizes[i].x, supported_sizes[i].y); + + ERR("Unsupported size %d\n", val); + twCC = TWCC_BADCAP; + break; + + case MSG_GETDEFAULT: + twCC = set_onevalue(pCapability, TWTY_UINT16, default_size); + break; + + case MSG_RESET: + twCC = TWCC_BADCAP; + for (i = 1; i < SUPPORTED_SIZE_COUNT; i++) + if (supported_sizes[i].size == default_size) + { + twCC = set_width_height(supported_sizes[i].x, supported_sizes[i].y); + break; + } + if (twCC != TWCC_SUCCESS) + return twCC; + + /* .. fall through intentional .. */ + + case MSG_GETCURRENT: + twCC = set_onevalue(pCapability, TWTY_UINT16, current_size); + break; + } + +#undef SUPPORTED_SIZE_COUNT +#endif + return twCC; +} + +/* CAP_AUTOFEED */ +static TW_UINT16 SANE_CAPAutofeed (pTW_CAPABILITY pCapability, TW_UINT16 action) +{ + TW_UINT16 twCC = TWCC_BADCAP; +#ifdef SONAME_LIBSANE + TW_UINT32 val; + SANE_Bool autofeed; + SANE_Status status; + + TRACE("CAP_AUTOFEED\n"); + + if (sane_option_get_bool(activeDS.deviceHandle, "batch-scan", &autofeed, NULL) != SANE_STATUS_GOOD) + return TWCC_BADCAP; + + switch (action) + { + case MSG_QUERYSUPPORT: + twCC = set_onevalue(pCapability, TWTY_INT32, + TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET ); + break; + + case MSG_GET: + twCC = set_onevalue(pCapability, TWTY_BOOL, autofeed); + break; + + case MSG_SET: + twCC = msg_set(pCapability, &val); + if (twCC == TWCC_SUCCESS) + { + if (val) + autofeed = SANE_TRUE; + else + autofeed = SANE_FALSE; + + status = sane_option_set_bool(activeDS.deviceHandle, "batch-scan", autofeed, NULL); + if (status != SANE_STATUS_GOOD) + { + ERR("Error %s: Could not set batch-scan to %d\n", psane_strstatus(status), autofeed); + return sane_status_to_twcc(status); + } + } + break; + + case MSG_GETDEFAULT: + twCC = set_onevalue(pCapability, TWTY_BOOL, SANE_TRUE); + break; + + case MSG_RESET: + autofeed = SANE_TRUE; + status = sane_option_set_bool(activeDS.deviceHandle, "batch-scan", autofeed, NULL); + if (status != SANE_STATUS_GOOD) + { + ERR("Error %s: Could not reset batch-scan to SANE_TRUE\n", psane_strstatus(status)); + return sane_status_to_twcc(status); + } + /* .. fall through intentional .. */ + + case MSG_GETCURRENT: + twCC = set_onevalue(pCapability, TWTY_BOOL, autofeed); + break; + } +#endif + return twCC; +} + +/* CAP_FEEDERENABLED */ +static TW_UINT16 SANE_CAPFeederEnabled (pTW_CAPABILITY pCapability, TW_UINT16 action) +{ + TW_UINT16 twCC = TWCC_BADCAP; +#ifdef SONAME_LIBSANE + TW_UINT32 val; + TW_BOOL enabled; + SANE_Status status; + SANE_Char source[64]; + + TRACE("CAP_FEEDERENABLED\n"); + + if (sane_option_get_str(activeDS.deviceHandle, SANE_NAME_SCAN_SOURCE, source, sizeof(source), NULL) != SANE_STATUS_GOOD) + return TWCC_BADCAP; + + if (strcmp(source, "Auto") == 0 || strcmp(source, "ADF") == 0) + enabled = TRUE; + else + enabled = FALSE; + + switch (action) + { + case MSG_QUERYSUPPORT: + twCC = set_onevalue(pCapability, TWTY_INT32, + TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET ); + break; + + case MSG_GET: + twCC = set_onevalue(pCapability, TWTY_BOOL, enabled); + break; + + case MSG_SET: + twCC = msg_set(pCapability, &val); + if (twCC == TWCC_SUCCESS) + { + if (val) + enabled = TRUE; + else + enabled = FALSE; + + strcpy(source, "ADF"); + status = sane_option_set_str(activeDS.deviceHandle, SANE_NAME_SCAN_SOURCE, source, NULL); + if (status != SANE_STATUS_GOOD) + { + strcpy(source, "Auto"); + status = sane_option_set_str(activeDS.deviceHandle, SANE_NAME_SCAN_SOURCE, source, NULL); + } + if (status != SANE_STATUS_GOOD) + { + ERR("Error %s: Could not set source to either ADF or Auto\n", psane_strstatus(status)); + return sane_status_to_twcc(status); + } + } + break; + + case MSG_GETDEFAULT: + twCC = set_onevalue(pCapability, TWTY_BOOL, TRUE); + break; + + case MSG_RESET: + strcpy(source, "Auto"); + if (sane_option_set_str(activeDS.deviceHandle, SANE_NAME_SCAN_SOURCE, source, NULL) == SANE_STATUS_GOOD) + enabled = TRUE; + twCC = TWCC_SUCCESS; + /* .. fall through intentional .. */ + + case MSG_GETCURRENT: + twCC = set_onevalue(pCapability, TWTY_BOOL, enabled); + break; + } +#endif + return twCC; +} + + TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) { @@ -746,6 +1203,14 @@ TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) twCC = SANE_CAPUiControllable (pCapability, action); break; + case CAP_AUTOFEED: + twCC = SANE_CAPAutofeed (pCapability, action); + break; + + case CAP_FEEDERENABLED: + twCC = SANE_CAPFeederEnabled (pCapability, action); + break; + case ICAP_PIXELTYPE: twCC = SANE_ICAPPixelType (pCapability, action); break; @@ -777,6 +1242,27 @@ TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) case ICAP_YRESOLUTION: twCC = SANE_ICAPResolution(pCapability, action, pCapability->Cap); break; + + case ICAP_PHYSICALHEIGHT: + twCC = SANE_ICAPPhysical(pCapability, action, pCapability->Cap); + break; + + case ICAP_PHYSICALWIDTH: + twCC = SANE_ICAPPhysical(pCapability, action, pCapability->Cap); + break; + + case ICAP_SUPPORTEDSIZES: + twCC = SANE_ICAPSupportedSizes (pCapability, action); + break; + + case ICAP_PLANARCHUNKY: + FIXME("ICAP_PLANARCHUNKY not implemented\n"); + break; + + case ICAP_BITORDER: + FIXME("ICAP_BITORDER not implemented\n"); + break; + } /* Twain specifies that you should return a 0 in response to QUERYSUPPORT, @@ -789,3 +1275,31 @@ TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) return twCC; } + +TW_UINT16 SANE_SaneSetDefaults (void) +{ + TW_CAPABILITY cap; + + memset(&cap, 0, sizeof(cap)); + cap.Cap = CAP_AUTOFEED; + cap.ConType = TWON_DONTCARE16; + + if (SANE_SaneCapability(&cap, MSG_RESET) == TWCC_SUCCESS) + GlobalFree(cap.hContainer); + + memset(&cap, 0, sizeof(cap)); + cap.Cap = CAP_FEEDERENABLED; + cap.ConType = TWON_DONTCARE16; + + if (SANE_SaneCapability(&cap, MSG_RESET) == TWCC_SUCCESS) + GlobalFree(cap.hContainer); + + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_DONTCARE16; + + if (SANE_SaneCapability(&cap, MSG_RESET) == TWCC_SUCCESS) + GlobalFree(cap.hContainer); + + return TWCC_SUCCESS; +} diff --git a/dlls/sane.ds/ds_ctrl.c b/dlls/sane.ds/ds_ctrl.c index f204a71d22d..9901fffe4e8 100644 --- a/dlls/sane.ds/ds_ctrl.c +++ b/dlls/sane.ds/ds_ctrl.c @@ -174,126 +174,6 @@ TW_UINT16 SANE_CapabilitySet (pTW_IDENTITY pOrigin, return twRC; } -/* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_GET */ -TW_UINT16 SANE_CustomDSDataGet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_SET */ -TW_UINT16 SANE_CustomDSDataSet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_AUTOMATICCAPTUREDIRECTORY */ -TW_UINT16 SANE_AutomaticCaptureDirectory (pTW_IDENTITY pOrigin, - - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_CHANGEDIRECTORY */ -TW_UINT16 SANE_ChangeDirectory (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_COPY */ -TW_UINT16 SANE_FileSystemCopy (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_CREATEDIRECTORY */ -TW_UINT16 SANE_CreateDirectory (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_DELETE */ -TW_UINT16 SANE_FileSystemDelete (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_FORMATMEDIA */ -TW_UINT16 SANE_FormatMedia (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_GETCLOSE */ -TW_UINT16 SANE_FileSystemGetClose (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_GETFIRSTFILE */ -TW_UINT16 SANE_FileSystemGetFirstFile (pTW_IDENTITY pOrigin, - - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_GETINFO */ -TW_UINT16 SANE_FileSystemGetInfo (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_GETNEXTFILE */ -TW_UINT16 SANE_FileSystemGetNextFile (pTW_IDENTITY pOrigin, - - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_FILESYSTEM/MSG_RENAME */ -TW_UINT16 SANE_FileSystemRename (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - /* DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT */ TW_UINT16 SANE_ProcessEvent (pTW_IDENTITY pOrigin, TW_MEMREF pData) @@ -322,21 +202,16 @@ TW_UINT16 SANE_ProcessEvent (pTW_IDENTITY pOrigin, return twRC; } -/* DG_CONTROL/DAT_PASSTHRU/MSG_PASSTHRU */ -TW_UINT16 SANE_PassThrough (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - /* DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER */ TW_UINT16 SANE_PendingXfersEndXfer (pTW_IDENTITY pOrigin, TW_MEMREF pData) { +#ifndef SONAME_LIBSANE + return TWRC_FAILURE; +#else TW_UINT16 twRC = TWRC_SUCCESS; pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData; + SANE_Status status; TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER\n"); @@ -347,31 +222,41 @@ TW_UINT16 SANE_PendingXfersEndXfer (pTW_IDENTITY pOrigin, } else { - if (pPendingXfers->Count != 0) + pPendingXfers->Count = -1; + activeDS.currentState = 6; + if (! activeDS.sane_started) { - pPendingXfers->Count --; - activeDS.currentState = 6; - } - else - { - activeDS.currentState = 5; - /* Notify the application that it can close the data source */ - if (activeDS.windowMessage) - PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0); + status = psane_start (activeDS.deviceHandle); + if (status != SANE_STATUS_GOOD) + { + TRACE("PENDINGXFERS/MSG_ENDXFER sane_start returns %s\n", psane_strstatus(status)); + pPendingXfers->Count = 0; + activeDS.currentState = 5; + /* Notify the application that it can close the data source */ + if (activeDS.windowMessage) + PostMessageA(activeDS.hwndOwner, activeDS.windowMessage, MSG_CLOSEDSREQ, 0); + } + else + activeDS.sane_started = TRUE; } twRC = TWRC_SUCCESS; activeDS.twCC = TWCC_SUCCESS; } return twRC; +#endif } /* DG_CONTROL/DAT_PENDINGXFERS/MSG_GET */ TW_UINT16 SANE_PendingXfersGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) { +#ifndef SONAME_LIBSANE + return TWRC_FAILURE; +#else TW_UINT16 twRC = TWRC_SUCCESS; pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData; + SANE_Status status; TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_GET\n"); @@ -382,19 +267,33 @@ TW_UINT16 SANE_PendingXfersGet (pTW_IDENTITY pOrigin, } else { - /* FIXME: we shouldn't return 1 here */ - pPendingXfers->Count = 1; + pPendingXfers->Count = -1; + if (! activeDS.sane_started) + { + status = psane_start (activeDS.deviceHandle); + if (status != SANE_STATUS_GOOD) + { + TRACE("PENDINGXFERS/MSG_GET sane_start returns %s\n", psane_strstatus(status)); + pPendingXfers->Count = 0; + } + else + activeDS.sane_started = TRUE; + } twRC = TWRC_SUCCESS; activeDS.twCC = TWCC_SUCCESS; } return twRC; +#endif } /* DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET */ TW_UINT16 SANE_PendingXfersReset (pTW_IDENTITY pOrigin, TW_MEMREF pData) { +#ifndef SONAME_LIBSANE + return TWRC_FAILURE; +#else TW_UINT16 twRC = TWRC_SUCCESS; pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData; @@ -411,91 +310,16 @@ TW_UINT16 SANE_PendingXfersReset (pTW_IDENTITY pOrigin, activeDS.currentState = 5; twRC = TWRC_SUCCESS; activeDS.twCC = TWCC_SUCCESS; + + if (activeDS.sane_started) + { + psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; + } } return twRC; -} - -/* DG_CONTROL/DAT_PENDINGXFERS/MSG_STOPFEEDER */ -TW_UINT16 SANE_PendingXfersStopFeeder (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPFILEXFER/MSG_GET */ -TW_UINT16 SANE_SetupFileXferGet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPXFER/MSG_GETDEFAULT */ -TW_UINT16 SANE_SetupFileXferGetDefault (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - - -/* DG_CONTROL/DAT_SETUPFILEXFER/MSG_RESET */ -TW_UINT16 SANE_SetupFileXferReset (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET */ -TW_UINT16 SANE_SetupFileXferSet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GET */ -TW_UINT16 SANE_SetupFileXfer2Get (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GETDEFAULT */ -TW_UINT16 SANE_SetupFileXfer2GetDefault (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_RESET */ -TW_UINT16 SANE_SetupFileXfer2Reset (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_SET */ -TW_UINT16 SANE_SetupFileXfer2Set (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; +#endif } /* DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET */ @@ -575,7 +399,7 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin, { twRC = TWRC_FAILURE; activeDS.twCC = TWCC_SEQERROR; - FIXME("sequence error %d\n", activeDS.currentState); + WARN("sequence error %d\n", activeDS.currentState); } else { @@ -586,7 +410,6 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin, { BOOL rc; activeDS.currentState = 5; /* Transitions to state 5 */ - FIXME("showing UI\n"); rc = DoScannerUI(); pUserInterface->ModalUI = TRUE; if (!rc) diff --git a/dlls/sane.ds/ds_image.c b/dlls/sane.ds/ds_image.c index 38689da13f8..63e0179d35b 100644 --- a/dlls/sane.ds/ds_image.c +++ b/dlls/sane.ds/ds_image.c @@ -31,51 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(twain); -/* DG_IMAGE/DAT_CIECOLOR/MSG_GET */ -TW_UINT16 SANE_CIEColorGet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */ -TW_UINT16 SANE_ExtImageInfoGet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */ -TW_UINT16 SANE_GrayResponseReset (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */ -TW_UINT16 SANE_GrayResponseSet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */ -TW_UINT16 SANE_ImageFileXferGet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - /* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) @@ -106,6 +61,7 @@ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, { WARN("psane_get_parameters: %s\n", psane_strstatus (status)); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } @@ -142,7 +98,10 @@ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, pImageInfo->Planar = TRUE; pImageInfo->SamplesPerPixel = 1; pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth; - pImageInfo->PixelType = TWPT_GRAY; + if (activeDS.sane_param.depth == 1) + pImageInfo->PixelType = TWPT_BW; + else + pImageInfo->PixelType = TWPT_GRAY; } else { @@ -227,13 +186,17 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, ScanningDialogBox(activeDS.progressWnd,0); - status = psane_start (activeDS.deviceHandle); - if (status != SANE_STATUS_GOOD) + if (! activeDS.sane_started) { - WARN("psane_start: %s\n", psane_strstatus (status)); - psane_cancel (activeDS.deviceHandle); - activeDS.twCC = TWCC_OPERATIONERROR; - return TWRC_FAILURE; + status = psane_start (activeDS.deviceHandle); + if (status != SANE_STATUS_GOOD) + { + WARN("psane_start: %s\n", psane_strstatus (status)); + psane_cancel (activeDS.deviceHandle); + activeDS.twCC = TWCC_OPERATIONERROR; + return TWRC_FAILURE; + } + activeDS.sane_started = TRUE; } status = psane_get_parameters (activeDS.deviceHandle, @@ -244,6 +207,7 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, { WARN("psane_get_parameters: %s\n", psane_strstatus (status)); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } @@ -260,6 +224,7 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line) { psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_BADVALUE; return TWRC_FAILURE; } @@ -306,6 +271,7 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, ScanningDialogBox(activeDS.progressWnd, -1); TRACE("psane_read: %s\n", psane_strstatus (status)); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; twRC = TWRC_XFERDONE; } activeDS.twCC = TWRC_SUCCESS; @@ -315,6 +281,7 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, ScanningDialogBox(activeDS.progressWnd, -1); WARN("psane_read: %s\n", psane_strstatus (status)); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_OPERATIONERROR; twRC = TWRC_FAILURE; } @@ -366,7 +333,10 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, int dib_bytes; int dib_bytes_per_line; BYTE *line; + RGBQUAD *colors; + int color_size = 0; int i; + BYTE *p; TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n"); @@ -378,13 +348,17 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, else { /* Transfer an image from the source to the application */ - status = psane_start (activeDS.deviceHandle); - if (status != SANE_STATUS_GOOD) + if (! activeDS.sane_started) { - WARN("psane_start: %s\n", psane_strstatus (status)); - psane_cancel (activeDS.deviceHandle); - activeDS.twCC = TWCC_OPERATIONERROR; - return TWRC_FAILURE; + status = psane_start (activeDS.deviceHandle); + if (status != SANE_STATUS_GOOD) + { + WARN("psane_start: %s\n", psane_strstatus (status)); + psane_cancel (activeDS.deviceHandle); + activeDS.twCC = TWCC_OPERATIONERROR; + return TWRC_FAILURE; + } + activeDS.sane_started = TRUE; } status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param); @@ -393,14 +367,31 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, { WARN("psane_get_parameters: %s\n", psane_strstatus (status)); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } - if (activeDS.sane_param.format != SANE_FRAME_RGB) + if (activeDS.sane_param.format == SANE_FRAME_GRAY) + { + if (activeDS.sane_param.depth == 8) + color_size = (1 << 8) * sizeof(*colors); + else if (activeDS.sane_param.depth == 1) + ; + else + { + FIXME("For NATIVE, we support only 1 bit monochrome and 8 bit Grayscale, not %d\n", activeDS.sane_param.depth); + psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; + activeDS.twCC = TWCC_OPERATIONERROR; + return TWRC_FAILURE; + } + } + else if (activeDS.sane_param.format != SANE_FRAME_RGB) { - FIXME("For NATIVE, we support only RGB, not %d\n", activeDS.sane_param.format); + FIXME("For NATIVE, we support only GRAY and RGB, not %d\n", activeDS.sane_param.format); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } @@ -413,13 +404,14 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, dib_bytes_per_line = ((activeDS.sane_param.bytes_per_line + 3) / 4) * 4; dib_bytes = activeDS.sane_param.lines * dib_bytes_per_line; - hDIB = GlobalAlloc(GMEM_ZEROINIT, dib_bytes + sizeof(*header)); + hDIB = GlobalAlloc(GMEM_ZEROINIT, dib_bytes + sizeof(*header) + color_size); if (hDIB) header = GlobalLock(hDIB); if (!header) { psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_LOWMEMORY; if (hDIB) GlobalFree(hDIB); @@ -430,18 +422,31 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, header->biWidth = activeDS.sane_param.pixels_per_line; header->biHeight = activeDS.sane_param.lines; header->biPlanes = 1; - header->biBitCount = activeDS.sane_param.depth * 3; header->biCompression = BI_RGB; + if (activeDS.sane_param.format == SANE_FRAME_RGB) + header->biBitCount = activeDS.sane_param.depth * 3; + if (activeDS.sane_param.format == SANE_FRAME_GRAY) + header->biBitCount = activeDS.sane_param.depth; header->biSizeImage = dib_bytes; header->biXPelsPerMeter = 0; header->biYPelsPerMeter = 0; header->biClrUsed = 0; header->biClrImportant = 0; + p = (BYTE *)(header + 1); + + if (color_size > 0) + { + colors = (RGBQUAD *) p; + p += color_size; + for (i = 0; i < (color_size / sizeof(*colors)); i++) + colors[i].rgbBlue = colors[i].rgbRed = colors[i].rgbGreen = i; + } + + /* Sane returns data in top down order. Acrobat does best with a bottom up DIB being returned. */ - line = (BYTE *)(header + 1) + - (activeDS.sane_param.lines - 1) * dib_bytes_per_line; + line = p + (activeDS.sane_param.lines - 1) * dib_bytes_per_line; for (i = activeDS.sane_param.lines - 1; i >= 0; i--) { activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd, @@ -464,12 +469,14 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, { WARN("psane_read: %s, reading line %d\n", psane_strstatus(status), i); psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; activeDS.twCC = TWCC_OPERATIONERROR; GlobalFree(hDIB); return TWRC_FAILURE; } psane_cancel (activeDS.deviceHandle); + activeDS.sane_started = FALSE; *pHandle = (TW_UINT32)hDIB; twRC = TWRC_XFERDONE; activeDS.twCC = TWCC_SUCCESS; @@ -478,94 +485,3 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, return twRC; #endif } - -/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */ -TW_UINT16 SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */ -TW_UINT16 SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin, - - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */ -TW_UINT16 SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */ -TW_UINT16 SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_PALETTE8/MSG_GET */ -TW_UINT16 SANE_Palette8Get (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */ -TW_UINT16 SANE_Palette8GetDefault (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_PALETTE8/MSG_RESET */ -TW_UINT16 SANE_Palette8Reset (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_PALETTE8/MSG_SET */ -TW_UINT16 SANE_Palette8Set (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */ -TW_UINT16 SANE_RGBResponseReset (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} - -/* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */ -TW_UINT16 SANE_RGBResponseSet (pTW_IDENTITY pOrigin, - TW_MEMREF pData) -{ - FIXME ("stub!\n"); - - return TWRC_FAILURE; -} diff --git a/dlls/sane.ds/options.c b/dlls/sane.ds/options.c index 98d83dcf489..44cd34efb76 100644 --- a/dlls/sane.ds/options.c +++ b/dlls/sane.ds/options.c @@ -85,6 +85,61 @@ SANE_Status sane_option_set_int(SANE_Handle h, const char *option_name, SANE_Int return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status); } +SANE_Status sane_option_get_bool(SANE_Handle h, const char *option_name, SANE_Bool *val, SANE_Int *status) +{ + SANE_Status rc; + int optno; + const SANE_Option_Descriptor *opt; + + rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL); + if (rc != SANE_STATUS_GOOD) + return rc; + + return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status); +} + +SANE_Status sane_option_set_bool(SANE_Handle h, const char *option_name, SANE_Bool val, SANE_Int *status) +{ + SANE_Status rc; + int optno; + const SANE_Option_Descriptor *opt; + + rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL); + if (rc != SANE_STATUS_GOOD) + return rc; + + return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status); +} + +SANE_Status sane_option_set_fixed(SANE_Handle h, const char *option_name, SANE_Fixed val, SANE_Int *status) +{ + SANE_Status rc; + int optno; + const SANE_Option_Descriptor *opt; + + rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED); + if (rc != SANE_STATUS_GOOD) + return rc; + + return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status); +} + +SANE_Status sane_option_get_str(SANE_Handle h, const char *option_name, SANE_String val, size_t len, SANE_Int *status) +{ + SANE_Status rc; + int optno; + const SANE_Option_Descriptor *opt; + + rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_STRING); + if (rc != SANE_STATUS_GOOD) + return rc; + + if (opt->size < len) + return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status); + else + return SANE_STATUS_NO_MEM; +} + /* Important: SANE has the side effect of of overwriting val with the returned value */ SANE_Status sane_option_set_str(SANE_Handle h, const char *option_name, SANE_String val, SANE_Int *status) { @@ -137,4 +192,30 @@ SANE_Status sane_option_probe_mode(SANE_Handle h, SANE_String_Const **choices, c return SANE_STATUS_NO_MEM; } + +SANE_Status sane_option_probe_scan_area(SANE_Handle h, const char *option_name, SANE_Fixed *val, + SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant) +{ + SANE_Status rc; + int optno; + const SANE_Option_Descriptor *opt; + + rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED); + if (rc != SANE_STATUS_GOOD) + return rc; + + if (unit) + *unit = opt->unit; + if (min) + *min = opt->constraint.range->min; + if (max) + *max = opt->constraint.range->max; + if (quant) + *quant = opt->constraint.range->quant; + + if (val) + rc = psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL); + + return rc; +} #endif diff --git a/dlls/sane.ds/sane_i.h b/dlls/sane.ds/sane_i.h index 9d0d1233828..72b4b790480 100644 --- a/dlls/sane.ds/sane_i.h +++ b/dlls/sane.ds/sane_i.h @@ -71,6 +71,7 @@ struct tagActiveDS SANE_Parameters sane_param; /* parameters about the image transferred */ BOOL sane_param_valid; /* true if valid sane_param*/ + BOOL sane_started; /* If sane_start has been called */ INT deviceIndex; /* index of the current device */ #endif /* Capabilities */ @@ -85,6 +86,7 @@ struct tagActiveDS /* Helper functions */ extern TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action); +extern TW_UINT16 SANE_SaneSetDefaults (void); /* Implementation of operation triplets * From Application to Source (Control Information) */ @@ -223,9 +225,15 @@ HWND ScanningDialogBox(HWND dialog, LONG progress); #ifdef SONAME_LIBSANE SANE_Status sane_option_get_int(SANE_Handle h, const char *option_name, SANE_Int *val); SANE_Status sane_option_set_int(SANE_Handle h, const char *option_name, SANE_Int val, SANE_Int *status); +SANE_Status sane_option_get_str(SANE_Handle h, const char *option_name, SANE_String val, size_t len, SANE_Int *status); SANE_Status sane_option_set_str(SANE_Handle h, const char *option_name, SANE_String val, SANE_Int *status); SANE_Status sane_option_probe_resolution(SANE_Handle h, const char *option_name, SANE_Int *minval, SANE_Int *maxval, SANE_Int *quant); SANE_Status sane_option_probe_mode(SANE_Handle h, SANE_String_Const **choices, char *current, int current_size); +SANE_Status sane_option_probe_scan_area(SANE_Handle h, const char *option_name, SANE_Fixed *val, + SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant); +SANE_Status sane_option_get_bool(SANE_Handle h, const char *option_name, SANE_Bool *val, SANE_Int *status); +SANE_Status sane_option_set_bool(SANE_Handle h, const char *option_name, SANE_Bool val, SANE_Int *status); +SANE_Status sane_option_set_fixed(SANE_Handle h, const char *option_name, SANE_Fixed val, SANE_Int *status); #endif diff --git a/dlls/sane.ds/sane_main.c b/dlls/sane.ds/sane_main.c index 3bd231e3123..a873d6c1256 100644 --- a/dlls/sane.ds/sane_main.c +++ b/dlls/sane.ds/sane_main.c @@ -141,6 +141,9 @@ static TW_UINT16 SANE_SourceControlHandler ( case MSG_CLOSEDS: #ifdef SONAME_LIBSANE psane_close (activeDS.deviceHandle); +#else + twRC = TWRC_FAILURE; + activeDS.twCC = TWCC_CAPUNSUPPORTED; #endif break; case MSG_OPENDS: @@ -148,6 +151,7 @@ static TW_UINT16 SANE_SourceControlHandler ( twRC = SANE_OpenDS( pOrigin, (pTW_IDENTITY)pData); #else twRC = TWRC_FAILURE; + activeDS.twCC = TWCC_CAPUNSUPPORTED; #endif break; case MSG_GET: @@ -155,6 +159,7 @@ static TW_UINT16 SANE_SourceControlHandler ( twRC = SANE_GetIdentity( pOrigin, (pTW_IDENTITY)pData); #else twRC = TWRC_FAILURE; + activeDS.twCC = TWCC_CAPUNSUPPORTED; #endif break; } @@ -182,63 +187,8 @@ static TW_UINT16 SANE_SourceControlHandler ( break; default: twRC = TWRC_FAILURE; + activeDS.twCC = TWCC_CAPBADOPERATION; FIXME("unrecognized opertion triplet\n"); - } - break; - - case DAT_CUSTOMDSDATA: - switch (MSG) - { - case MSG_GET: - twRC = SANE_CustomDSDataGet (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_CustomDSDataSet (pOrigin, pData); - break; - default: - break; - } - break; - - case DAT_FILESYSTEM: - switch (MSG) - { - /*case MSG_AUTOMATICCAPTUREDIRECTORY: - twRC = SANE_AutomaticCaptureDirectory - (pOrigin, pData); - break;*/ - case MSG_CHANGEDIRECTORY: - twRC = SANE_ChangeDirectory (pOrigin, pData); - break; - /*case MSG_COPY: - twRC = SANE_FileSystemCopy (pOrigin, pData); - break;*/ - case MSG_CREATEDIRECTORY: - twRC = SANE_CreateDirectory (pOrigin, pData); - break; - case MSG_DELETE: - twRC = SANE_FileSystemDelete (pOrigin, pData); - break; - case MSG_FORMATMEDIA: - twRC = SANE_FormatMedia (pOrigin, pData); - break; - case MSG_GETCLOSE: - twRC = SANE_FileSystemGetClose (pOrigin, pData); - break; - case MSG_GETFIRSTFILE: - twRC = SANE_FileSystemGetFirstFile (pOrigin, pData); - break; - case MSG_GETINFO: - twRC = SANE_FileSystemGetInfo (pOrigin, pData); - break; - case MSG_GETNEXTFILE: - twRC = SANE_FileSystemGetNextFile (pOrigin, pData); - break; - case MSG_RENAME: - twRC = SANE_FileSystemRename (pOrigin, pData); - break; - default: - twRC = TWRC_FAILURE; break; } break; @@ -247,14 +197,10 @@ static TW_UINT16 SANE_SourceControlHandler ( if (MSG == MSG_PROCESSEVENT) twRC = SANE_ProcessEvent (pOrigin, pData); else + { + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; - break; - - case DAT_PASSTHRU: - if (MSG == MSG_PASSTHRU) - twRC = SANE_PassThrough (pOrigin, pData); - else - twRC = TWRC_FAILURE; + } break; case DAT_PENDINGXFERS: @@ -269,64 +215,30 @@ static TW_UINT16 SANE_SourceControlHandler ( case MSG_RESET: twRC = SANE_PendingXfersReset (pOrigin, pData); break; - /*case MSG_STOPFEEDER: - twRC = SANE_PendingXfersStopFeeder (pOrigin, pData); - break;*/ - default: - twRC = TWRC_FAILURE; - } - break; - - case DAT_SETUPFILEXFER: - switch (MSG) - { - case MSG_GET: - twRC = SANE_SetupFileXferGet (pOrigin, pData); - break; - case MSG_GETDEFAULT: - twRC = SANE_SetupFileXferGetDefault (pOrigin, pData); - break; - case MSG_RESET: - twRC = SANE_SetupFileXferReset (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_SetupFileXferSet (pOrigin, pData); - break; default: + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; - break; } break; - /*case DAT_SETUPFILEXFER2: - switch (MSG) - { - case MSG_GET: - twRC = SANE_SetupFileXfer2Get (pOrigin, pData); - break; - case MSG_GETDEFAULT: - twRC = SANE_SetupFileXfer2GetDefault (pOrigin, pData); - break; - case MSG_RESET: - twRC = SANE_SetupFileXfer2Reset (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_SetupFileXfer2Set (pOrigin, pData); - break; - } - break;*/ case DAT_SETUPMEMXFER: if (MSG == MSG_GET) twRC = SANE_SetupMemXferGet (pOrigin, pData); else + { + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; + } break; case DAT_STATUS: if (MSG == MSG_GET) twRC = SANE_GetDSStatus (pOrigin, pData); else + { + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; + } break; case DAT_USERINTERFACE: @@ -342,6 +254,7 @@ static TW_UINT16 SANE_SourceControlHandler ( twRC = SANE_EnableDSUIOnly (pOrigin, pData); break; default: + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; break; } @@ -357,13 +270,15 @@ static TW_UINT16 SANE_SourceControlHandler ( twRC = SANE_XferGroupSet (pOrigin, pData); break; default: + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; break; } break; default: - FIXME("code unknown: %d\n", DAT); + WARN("code unsupported: %d\n", DAT); + activeDS.twCC = TWCC_CAPUNSUPPORTED; twRC = TWRC_FAILURE; break; } @@ -382,48 +297,14 @@ static TW_UINT16 SANE_ImageGroupHandler ( switch (DAT) { - case DAT_CIECOLOR: - if (MSG == MSG_GET) - twRC = SANE_CIEColorGet (pOrigin, pData); - else - twRC = TWRC_FAILURE; - break; - - case DAT_EXTIMAGEINFO: - if (MSG == MSG_GET) - twRC = SANE_ExtImageInfoGet (pOrigin, pData); - else - twRC = TWRC_FAILURE; - break; - - case DAT_GRAYRESPONSE: - switch (MSG) - { - case MSG_RESET: - twRC = SANE_GrayResponseReset (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_GrayResponseSet (pOrigin, pData); - break; - default: - twRC = TWRC_FAILURE; - activeDS.twCC = TWCC_BADPROTOCOL; - FIXME("unrecognized operation triplet\n"); - break; - } - break; - case DAT_IMAGEFILEXFER: - if (MSG == MSG_GET) - twRC = SANE_ImageFileXferGet (pOrigin, pData); - else - twRC = TWRC_FAILURE; - break; - case DAT_IMAGEINFO: if (MSG == MSG_GET) twRC = SANE_ImageInfoGet (pOrigin, pData); else + { + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; + } break; case DAT_IMAGELAYOUT: @@ -443,7 +324,7 @@ static TW_UINT16 SANE_ImageGroupHandler ( break; default: twRC = TWRC_FAILURE; - activeDS.twCC = TWCC_BADPROTOCOL; + activeDS.twCC = TWCC_CAPBADOPERATION; ERR("unrecognized operation triplet\n"); break; } @@ -453,82 +334,27 @@ static TW_UINT16 SANE_ImageGroupHandler ( if (MSG == MSG_GET) twRC = SANE_ImageMemXferGet (pOrigin, pData); else + { + activeDS.twCC = TWCC_CAPBADOPERATION; twRC = TWRC_FAILURE; + } break; case DAT_IMAGENATIVEXFER: if (MSG == MSG_GET) twRC = SANE_ImageNativeXferGet (pOrigin, pData); else - twRC = TWRC_FAILURE; - break; - - case DAT_JPEGCOMPRESSION: - switch (MSG) - { - case MSG_GET: - twRC = SANE_JPEGCompressionGet (pOrigin, pData); - break; - case MSG_GETDEFAULT: - twRC = SANE_JPEGCompressionGetDefault (pOrigin, pData); - break; - case MSG_RESET: - twRC = SANE_JPEGCompressionReset (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_JPEGCompressionSet (pOrigin, pData); - break; - default: - twRC = TWRC_FAILURE; - activeDS.twCC = TWCC_BADPROTOCOL; - WARN("unrecognized operation triplet\n"); - break; - } - break; - - case DAT_PALETTE8: - switch (MSG) - { - case MSG_GET: - twRC = SANE_Palette8Get (pOrigin, pData); - break; - case MSG_GETDEFAULT: - twRC = SANE_Palette8GetDefault (pOrigin, pData); - break; - case MSG_RESET: - twRC = SANE_Palette8Reset (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_Palette8Set (pOrigin, pData); - break; - default: - twRC = TWRC_FAILURE; - activeDS.twCC = TWCC_BADPROTOCOL; - WARN("unrecognized operation triplet\n"); - } - break; - - case DAT_RGBRESPONSE: - switch (MSG) { - case MSG_RESET: - twRC = SANE_RGBResponseReset (pOrigin, pData); - break; - case MSG_SET: - twRC = SANE_RGBResponseSet (pOrigin, pData); - break; - default: - twRC = TWRC_FAILURE; - activeDS.twCC = TWCC_BADPROTOCOL; - WARN("unrecognized operation triplet\n"); - break; + activeDS.twCC = TWCC_CAPBADOPERATION; + twRC = TWRC_FAILURE; } break; default: twRC = TWRC_FAILURE; - activeDS.twCC = TWCC_BADPROTOCOL; - FIXME("unrecognized DG type %d\n", DAT); + activeDS.twCC = TWCC_CAPUNSUPPORTED; + WARN("unsupported DG type %d\n", DAT); + break; } return twRC; } @@ -554,7 +380,10 @@ DS_Entry ( pTW_IDENTITY pOrigin, twRC = SANE_ImageGroupHandler (pOrigin,DAT,MSG,pData); break; case DG_AUDIO: - FIXME("Audio group of controls not implemented yet.\n"); + WARN("Audio group of controls not implemented yet.\n"); + twRC = TWRC_FAILURE; + activeDS.twCC = TWCC_CAPUNSUPPORTED; + break; default: activeDS.twCC = TWCC_BADPROTOCOL; twRC = TWRC_FAILURE; @@ -656,16 +485,21 @@ static TW_UINT16 SANE_OpenDS( pTW_IDENTITY pOrigin, pTW_IDENTITY self) { break; } if (!sane_devlist[i]) { - FIXME("Scanner not found.\n"); + WARN("Scanner not found.\n"); return TWRC_FAILURE; } status = psane_open(sane_devlist[i]->name,&activeDS.deviceHandle); if (status == SANE_STATUS_GOOD) { - activeDS.currentState = 4; - activeDS.twCC = TWRC_SUCCESS; - return TWRC_SUCCESS; + activeDS.twCC = SANE_SaneSetDefaults(); + if (activeDS.twCC == TWCC_SUCCESS) { + activeDS.currentState = 4; + return TWRC_SUCCESS; + } + else + psane_close(activeDS.deviceHandle); } - FIXME("sane_open(%s): %s\n", sane_devlist[i]->name, psane_strstatus (status)); + else + ERR("sane_open(%s): %s\n", sane_devlist[i]->name, psane_strstatus (status)); return TWRC_FAILURE; } #endif diff --git a/dlls/sane.ds/ui.c b/dlls/sane.ds/ui.c index 31b51524534..147c7594314 100644 --- a/dlls/sane.ds/ui.c +++ b/dlls/sane.ds/ui.c @@ -853,10 +853,14 @@ static INT_PTR InitializeDialog(HWND hwnd) dd = SANE_UNFIX(*sf); HeapFree(GetProcessHeap(),0,sf); + /* Note that conversion of float -> SANE_Fixed is lossy; + * and when you truncate it into an integer, you can get + * unfortunate results. This calculation attempts + * to mitigate that harm */ if (s_quant) - pos = (dd / s_quant); + pos = ((dd + (s_quant/2.0)) / s_quant); else - pos = dd / 0.01; + pos = (dd + 0.005) / 0.01; SendMessageW(control, SBM_SETPOS, pos, TRUE); diff --git a/dlls/setupapi/dialog.c b/dlls/setupapi/dialog.c index aaa9453b25c..21135cdcd8b 100644 --- a/dlls/setupapi/dialog.c +++ b/dlls/setupapi/dialog.c @@ -183,6 +183,51 @@ static INT_PTR CALLBACK promptdisk_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR } /*********************************************************************** + * SetupPromptForDiskA (SETUPAPI.@) + */ +UINT WINAPI SetupPromptForDiskA(HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName, + PCSTR PathToSource, PCSTR FileSought, PCSTR TagFile, DWORD DiskPromptStyle, + PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize) +{ + WCHAR *DialogTitleW, *DiskNameW, *PathToSourceW; + WCHAR *FileSoughtW, *TagFileW, PathBufferW[MAX_PATH]; + UINT ret, length; + + TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_a(DialogTitle), + debugstr_a(DiskName), debugstr_a(PathToSource), debugstr_a(FileSought), + debugstr_a(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, + PathRequiredSize); + + DialogTitleW = strdupAtoW(DialogTitle); + DiskNameW = strdupAtoW(DiskName); + PathToSourceW = strdupAtoW(PathToSource); + FileSoughtW = strdupAtoW(FileSought); + TagFileW = strdupAtoW(TagFile); + + ret = SetupPromptForDiskW(hwndParent, DialogTitleW, DiskNameW, PathToSourceW, + FileSoughtW, TagFileW, DiskPromptStyle, PathBufferW, MAX_PATH, PathRequiredSize); + + HeapFree(GetProcessHeap(), 0, DialogTitleW); + HeapFree(GetProcessHeap(), 0, DiskNameW); + HeapFree(GetProcessHeap(), 0, PathToSourceW); + HeapFree(GetProcessHeap(), 0, FileSoughtW); + HeapFree(GetProcessHeap(), 0, TagFileW); + + if(ret == DPROMPT_SUCCESS) + { + length = WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, NULL, 0, NULL, NULL); + if(PathRequiredSize) *PathRequiredSize = length; + if(PathBuffer) + { + if(length > PathBufferSize) + return DPROMPT_BUFFERTOOSMALL; + WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, PathBuffer, length, NULL, NULL); + } + } + return ret; +} + +/*********************************************************************** * SetupPromptForDiskW (SETUPAPI.@) */ UINT WINAPI SetupPromptForDiskW(HWND hwndParent, PCWSTR DialogTitle, PCWSTR DiskName, diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 287cb7e475d..39974478197 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -247,20 +247,6 @@ BOOL WINAPI SetupDiGetClassImageList(PSP_CLASSIMAGELIST_DATA ClassImageListData) } /*********************************************************************** - * SetupPromptForDiskA (SETUPAPI.@) - */ -UINT WINAPI SetupPromptForDiskA(HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName, - PCSTR PathToSource, PCSTR FileSought, PCSTR TagFile, DWORD DiskPromptStyle, - PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize) -{ - FIXME("%p %s %s %s %s %s %d %p %d %p: stub\n", hwndParent, debugstr_a(DialogTitle), - debugstr_a(DiskName), debugstr_a(PathToSource), debugstr_a(FileSought), - debugstr_a(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, - PathRequiredSize); - return 0; -} - -/*********************************************************************** * CM_Locate_DevNodeA (SETUPAPI.@) */ CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags) diff --git a/dlls/setupapi/tests/parser.c b/dlls/setupapi/tests/parser.c index 0aa78c12d53..91a84252804 100644 --- a/dlls/setupapi/tests/parser.c +++ b/dlls/setupapi/tests/parser.c @@ -126,10 +126,10 @@ static const struct { ";\n;\nabc\r\n" STD_HEADER, ERROR_EXPECTED_SECTION_NAME, 3, 0 }, { ";\n;\nab\nab\n" STD_HEADER, ERROR_EXPECTED_SECTION_NAME, 3, 0 }, { ";aa\n;bb\n" STD_HEADER, 0, 0, 0 }, - { STD_HEADER " [TestSection\x00] \n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, - { STD_HEADER " [Test\x00Section] \n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, - { STD_HEADER " [TestSection\x00] \n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, - { STD_HEADER " [Test\x00Section] \n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, + { STD_HEADER " [TestSection\x00]\n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, + { STD_HEADER " [Test\x00Section]\n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, + { STD_HEADER " [TestSection\x00]\n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, + { STD_HEADER " [Test\x00Section]\n", ERROR_BAD_SECTION_NAME_LINE, 3, 0 }, }; static void test_invalid_files(void) diff --git a/dlls/shdocvw/tests/shdocvw.c b/dlls/shdocvw/tests/shdocvw.c index 8e7b1f3d213..17ea8d08625 100644 --- a/dlls/shdocvw/tests/shdocvw.c +++ b/dlls/shdocvw/tests/shdocvw.c @@ -357,4 +357,5 @@ START_TEST(shdocvw) test_URLSubRegQueryA(); test_ParseURLFromOutsideSourceA(); test_ParseURLFromOutsideSourceW(); + FreeLibrary(hshdocvw); } diff --git a/dlls/shell32/regsvr.c b/dlls/shell32/regsvr.c index 3f899173a41..a23190e3dde 100644 --- a/dlls/shell32/regsvr.c +++ b/dlls/shell32/regsvr.c @@ -658,6 +658,13 @@ static struct regsvr_coclass const coclass_list[] = { "shell32.dll", "Apartment" }, + { &CLSID_QueryAssociations, + "Query file associations", + 0, + NULL, + "shell32.dll", + "Apartment" + }, { &CLSID_ControlPanel, "Control Panel", IDS_CONTROLPANEL, diff --git a/dlls/shell32/tests/autocomplete.c b/dlls/shell32/tests/autocomplete.c index 782fc3592f6..20315c749ea 100644 --- a/dlls/shell32/tests/autocomplete.c +++ b/dlls/shell32/tests/autocomplete.c @@ -33,7 +33,7 @@ static HWND hMainWnd, hEdit; static HINSTANCE hinst; static int killfocus_count; -static void test_init(void) { +static BOOL test_init(void) { HRESULT r; IAutoComplete* ac; IUnknown *acSource; @@ -41,16 +41,28 @@ static void test_init(void) { /* AutoComplete instance */ r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, &IID_IAutoComplete, (LPVOID*)&ac); + if (r == REGDB_E_CLASSNOTREG) + { + win_skip("CLSID_AutoComplete is not registered\n"); + return FALSE; + } ok(SUCCEEDED(r), "no IID_IAutoComplete (0x%08x)\n", r); /* AutoComplete source */ r = CoCreateInstance(&CLSID_ACLMulti, NULL, CLSCTX_INPROC_SERVER, &IID_IACList, (LPVOID*)&acSource); + if (r == REGDB_E_CLASSNOTREG) + { + win_skip("CLSID_ACLMulti is not registered\n"); + return FALSE; + } ok(SUCCEEDED(r), "no IID_IACList (0x%08x)\n", r); /* bind to edit control */ r = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL); ok(SUCCEEDED(r), "Init failed (0x%08x)\n", r); + + return TRUE; } static void test_killfocus(void) { /* Test if WM_KILLFOCUS messages are handled properly by checking if @@ -106,7 +118,8 @@ START_TEST(autocomplete) { if(!ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n")) return; - test_init(); + if (!test_init()) + goto cleanup; test_killfocus(); PostQuitMessage(0); @@ -115,6 +128,7 @@ START_TEST(autocomplete) { DispatchMessageA(&msg); } +cleanup: DestroyWindow(hEdit); DestroyWindow(hMainWnd); diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index b8a78f80003..404c4130ada 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -707,7 +707,6 @@ static void test_GetAttributesOf(void) char cCurrDirA [MAX_PATH] = {0}; WCHAR cCurrDirW [MAX_PATH]; static WCHAR cTestDirW[] = {'t','e','s','t','d','i','r',0}; - static const WCHAR cBackSlash[] = {'\\',0}; IShellFolder *IDesktopFolder, *testIShellFolder; ITEMIDLIST *newPIDL; int len; @@ -768,19 +767,19 @@ static void test_GetAttributesOf(void) IShellFolder_Release(psfMyComputer); - /* create test directory */ - CreateFilesFolders(); - GetCurrentDirectoryA(MAX_PATH, cCurrDirA); len = lstrlenA(cCurrDirA); if (len == 0) { - trace("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n"); + win_skip("GetCurrentDirectoryA returned empty string. Skipping test_GetAttributesOf\n"); return; } if(cCurrDirA[len-1] == '\\') cCurrDirA[len-1] = 0; + /* create test directory */ + CreateFilesFolders(); + MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH); hr = SHGetDesktopFolder(&IDesktopFolder); @@ -808,8 +807,8 @@ static void test_GetAttributesOf(void) IMalloc_Free(ppM, newPIDL); /* append testdirectory name to path */ - lstrcatW(cCurrDirW, cBackSlash); - lstrcatW(cCurrDirW, cTestDirW); + lstrcatA(cCurrDirA, "\\testdir"); + MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH); hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0); ok(hr == S_OK, "ParseDisplayName failed %08x\n", hr); @@ -854,7 +853,7 @@ static void test_SHGetPathFromIDList(void) if(!pSHGetPathFromIDListW || !pSHGetSpecialFolderPathW) { - skip("SHGetPathFromIDListW() or SHGetSpecialFolderPathW() is missing\n"); + win_skip("SHGetPathFromIDListW() or SHGetSpecialFolderPathW() is missing\n"); return; } @@ -869,7 +868,16 @@ static void test_SHGetPathFromIDList(void) result = pSHGetSpecialFolderPathW(NULL, wszDesktop, CSIDL_DESKTOP, FALSE); ok(result, "SHGetSpecialFolderPathW(CSIDL_DESKTOP) failed! Last error: %u\n", GetLastError()); if (!result) return; - + + /* Check if we are on Win9x */ + SetLastError(0xdeadbeef); + lstrcmpiW(wszDesktop, wszDesktop); + if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("Most W-calls are not implemented\n"); + return; + } + result = pSHGetPathFromIDListW(pidlEmpty, wszPath); ok(result, "SHGetPathFromIDListW failed! Last error: %u\n", GetLastError()); if (!result) return; @@ -969,8 +977,8 @@ static void test_EnumObjects_and_CompareIDs(void) ITEMIDLIST *newPIDL; IShellFolder *IDesktopFolder, *testIShellFolder; char cCurrDirA [MAX_PATH] = {0}; - WCHAR cCurrDirW [MAX_PATH]; - static const WCHAR cTestDirW[] = {'\\','t','e','s','t','d','i','r',0}; + static const CHAR cTestDirA[] = "\\testdir"; + WCHAR cTestDirW[MAX_PATH]; int len; HRESULT hr; @@ -978,21 +986,21 @@ static void test_EnumObjects_and_CompareIDs(void) len = lstrlenA(cCurrDirA); if(len == 0) { - trace("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n"); + win_skip("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n"); return; } if(cCurrDirA[len-1] == '\\') cCurrDirA[len-1] = 0; - MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH); - lstrcatW(cCurrDirW, cTestDirW); + lstrcatA(cCurrDirA, cTestDirA); + MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cTestDirW, MAX_PATH); hr = SHGetDesktopFolder(&IDesktopFolder); ok(hr == S_OK, "SHGetDesktopfolder failed %08x\n", hr); CreateFilesFolders(); - hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0); + hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cTestDirW, NULL, &newPIDL, 0); ok(hr == S_OK, "ParseDisplayName failed %08x\n", hr); hr = IShellFolder_BindToObject(IDesktopFolder, newPIDL, NULL, (REFIID)&IID_IShellFolder, (LPVOID *)&testIShellFolder); diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c index d0e8dd8a0a5..3e371211d90 100644 --- a/dlls/shlwapi/tests/ordinal.c +++ b/dlls/shlwapi/tests/ordinal.c @@ -380,7 +380,9 @@ static void test_GetShellSecurityDescriptor(void) } psd = pGetShellSecurityDescriptor(NULL, 2); - ok(psd==NULL, "GetShellSecurityDescriptor should fail\n"); + ok(psd==NULL || + broken(psd==INVALID_HANDLE_VALUE), /* IE5 */ + "GetShellSecurityDescriptor should fail\n"); psd = pGetShellSecurityDescriptor(rgsup, 0); ok(psd==NULL, "GetShellSecurityDescriptor should fail\n"); @@ -392,6 +394,11 @@ static void test_GetShellSecurityDescriptor(void) win_skip("GetShellSecurityDescriptor is not implemented\n"); return; } + if (psd==INVALID_HANDLE_VALUE) + { + win_skip("GetShellSecurityDescriptor is broken on IE5\n"); + return; + } ok(psd!=NULL, "GetShellSecurityDescriptor failed\n"); if (psd!=NULL) { diff --git a/dlls/shlwapi/tests/path.c b/dlls/shlwapi/tests/path.c index 86c81983633..52eee2d7c8e 100644 --- a/dlls/shlwapi/tests/path.c +++ b/dlls/shlwapi/tests/path.c @@ -393,10 +393,10 @@ static void test_PathCombineW(void) wszString2[0] = 'a'; wszString = pPathCombineW(wszString2, NULL, NULL); ok (wszString == NULL || - broken(wszString[0] = 'a'), /* Win95 and some W2K */ + broken(wszString[0] == 'a'), /* Win95 and some W2K */ "Expected a NULL return\n"); ok (wszString2[0] == 0 || - broken(wszString[0] = 'a'), /* Win95 and some W2K */ + broken(wszString2[0] == 'a'), /* Win95 and some W2K */ "Destination string not empty\n"); HeapFree(GetProcessHeap(), 0, wszString2); @@ -411,7 +411,7 @@ static void test_PathCombineW(void) wszString = pPathCombineW(wbuf, wstr1, wstr2); ok(wszString == NULL, "Expected a NULL return\n"); ok(wbuf[0] == 0 || - broken(wbuf[0] = 0xbfbf), /* Win95 and some W2K */ + broken(wbuf[0] == 0xbfbf), /* Win95 and some W2K */ "Buffer contains data\n"); /* PathCombineW can be used in place */ diff --git a/dlls/shlwapi/tests/shreg.c b/dlls/shlwapi/tests/shreg.c index f088c2eb0a1..00cec4fc30c 100644 --- a/dlls/shlwapi/tests/shreg.c +++ b/dlls/shlwapi/tests/shreg.c @@ -122,8 +122,12 @@ static void test_SHGetValue(void) dwType = -1; dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", &dwType, buf, &dwSize); ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet); - ok( 0 == strcmp(sExpTestpath1, buf), "Comparing of (%s) with (%s) failed\n", buf, sExpTestpath1); - ok( REG_SZ == dwType, "Expected REG_SZ, got (%u)\n", dwType); + ok( 0 == strcmp(sExpTestpath1, buf) || + broken(0 == strcmp(sTestpath1, buf)), /* IE4.x */ + "Comparing of (%s) with (%s) failed\n", buf, sExpTestpath1); + ok( REG_SZ == dwType || + broken(REG_EXPAND_SZ == dwType), /* IE4.x */ + "Expected REG_SZ, got (%u)\n", dwType); strcpy(buf, sEmptyBuffer); dwSize = MAX_PATH; @@ -196,7 +200,9 @@ static void test_SHQUeryValueEx(void) dwSize = 6; dwRet = SHQueryValueExA( hKey, "Test3", NULL, NULL, NULL, &dwSize); ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); - ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + ok( dwSize >= nUsedBuffer2 || + broken(dwSize == (strlen(sTestpath2) + 1)), /* < IE4.x */ + "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); /* * Case 1 string shrinks during expanding @@ -208,7 +214,9 @@ static void test_SHQUeryValueEx(void) ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer); ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + ok( REG_SZ == dwType || + broken(REG_EXPAND_SZ == dwType), /* < IE6 */ + "Expected REG_SZ, got (%u)\n", dwType); /* * string grows during expanding @@ -220,8 +228,12 @@ static void test_SHQUeryValueEx(void) dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer); - ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + ok( dwSize >= nUsedBuffer2 || + broken(dwSize == (strlen(sTestpath2) + 1)), /* < IE6 */ + "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + ok( REG_SZ == dwType || + broken(REG_EXPAND_SZ == dwType), /* < IE6 */ + "Expected REG_SZ, got (%u)\n", dwType); /* * string grows during expanding @@ -233,7 +245,10 @@ static void test_SHQUeryValueEx(void) dwSize = strlen(sEnvvar2) - 2; dwType = -1; dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); - ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); + ok( ERROR_MORE_DATA == dwRet || + broken(ERROR_ENVVAR_NOT_FOUND == dwRet) || /* IE5.5 */ + broken(ERROR_SUCCESS == dwRet), /* < IE5.5*/ + "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); todo_wine { @@ -241,7 +256,9 @@ static void test_SHQUeryValueEx(void) "Expected empty or unexpanded string (win98), got (%s)\n", buf); } - ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + ok( dwSize >= nUsedBuffer2 || + broken(dwSize == (strlen("") + 1)), /* < IE 5.5 */ + "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); /* @@ -254,15 +271,22 @@ static void test_SHQUeryValueEx(void) dwSize = nExpLen2 - 4; dwType = -1; dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); - ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); + ok( ERROR_MORE_DATA == dwRet || + broken(ERROR_ENVVAR_NOT_FOUND == dwRet) || /* IE5.5 */ + broken(ERROR_SUCCESS == dwRet), /* < IE5.5 */ + "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); todo_wine { - ok( (0 == strcmp("", buf)) || (0 == strcmp(sEnvvar2, buf)), - "Expected empty or first part of the string \"%s\", got \"%s\"\n", sEnvvar2, buf); + ok( (0 == strcmp("", buf)) || (0 == strcmp(sEnvvar2, buf)) || + broken(0 == strcmp(sTestpath2, buf)), /* IE 5.5 */ + "Expected empty or first part of the string \"%s\", got \"%s\"\n", sEnvvar2, buf); } - ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + ok( dwSize >= nUsedBuffer2 || + broken(dwSize == (strlen(sEnvvar2) + 1)) || /* IE4.01 SP1 (W98) and IE5 (W98SE) */ + broken(dwSize == (strlen("") + 1)), /* IE4.01 (NT4) and IE5.x (W2K) */ + "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); /* @@ -273,7 +297,9 @@ static void test_SHQUeryValueEx(void) dwType = -1; dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, NULL, &dwSize); ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); - ok( dwSize >= nUsedBuffer2, "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + ok( dwSize >= nUsedBuffer2 || + broken(dwSize == (strlen(sTestpath2) + 1)), /* IE4.01 SP1 (Win98) */ + "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); RegCloseKey(hKey); diff --git a/dlls/snmpapi/tests/util.c b/dlls/snmpapi/tests/util.c index 7973917f8ae..64c75010445 100644 --- a/dlls/snmpapi/tests/util.c +++ b/dlls/snmpapi/tests/util.c @@ -107,7 +107,7 @@ static void test_SnmpUtilOidToA(void) { ret = SnmpUtilOidToA(NULL); ok(ret != NULL, "SnmpUtilOidToA failed\n"); - ok(!strcmp(ret, expect0), "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + ok(!strcmp(ret, expect0), "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect1); } @@ -115,34 +115,34 @@ static void test_SnmpUtilOidToA(void) ok(ret != NULL, "SnmpUtilOidToA failed\n"); ok(!strcmp(ret, expect0) || broken(!strcmp(ret, expect0_alt)), /* Win98, WinMe, NT4 */ - "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect0); ret = SnmpUtilOidToA(&oid1); ok(ret != NULL, "SnmpUtilOidToA failed\n"); - ok(!strcmp(ret, expect1), "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + ok(!strcmp(ret, expect1), "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect1); ret = SnmpUtilOidToA(&oid2); ok(ret != NULL, "SnmpUtilOidToA failed\n"); - ok(!strcmp(ret, expect2), "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + ok(!strcmp(ret, expect2), "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect2); ret = SnmpUtilOidToA(&oid3); ok(ret != NULL, "SnmpUtilOidToA failed\n"); - ok(!strcmp(ret, expect3), "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + ok(!strcmp(ret, expect3), "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect3); ret = SnmpUtilOidToA(&oid4); ok(ret != NULL, "SnmpUtilOidToA failed\n"); ok(!strcmp(ret, expect3) || broken(!strcmp(ret, expect3_alt)), /* Win98, WinMe, NT4 */ - "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect3); ret = SnmpUtilOidToA(&oid5); ok(ret != NULL, "SnmpUtilOidToA failed\n"); - ok(!strcmp(ret, expect4), "SnmpUtilOidToA failed got \n%s\n expected \n%s\n", + ok(!strcmp(ret, expect4), "SnmpUtilOidToA failed got\n%s\n expected\n%s\n", ret, expect4); } diff --git a/dlls/stress.dll16/Makefile.in b/dlls/stress.dll16/Makefile.in new file mode 100644 index 00000000000..1d45fc01515 --- /dev/null +++ b/dlls/stress.dll16/Makefile.in @@ -0,0 +1,15 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = stress.dll16 +IMPORTS = kernel32 +EXTRADLLFLAGS = -Wb,--subsystem,win16 + +SPEC_SRCS = stress.dll16.spec + +C_SRCS = stress.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/kernel32/stress.c b/dlls/stress.dll16/stress.c similarity index 100% rename from dlls/kernel32/stress.c rename to dlls/stress.dll16/stress.c diff --git a/dlls/kernel32/stress.spec b/dlls/stress.dll16/stress.dll16.spec similarity index 100% rename from dlls/kernel32/stress.spec rename to dlls/stress.dll16/stress.dll16.spec diff --git a/dlls/twain_32/README b/dlls/twain_32/README deleted file mode 100644 index 0b75a3635e2..00000000000 --- a/dlls/twain_32/README +++ /dev/null @@ -1,54 +0,0 @@ ------ Old Corel README, probably outdated ---------------------------------- -1. INTRODUCTION - -This library (twain_32.dll) is an implementation of TWAIN API for providing image acquisition devices (scanner or digital camera) support. It uses SANE drivers as the backend and translates TWAIN API calls into SANE API calls. Unlike the twain32 library on Windows platform, it combines the Data Source Manager and Data Sources into a single library. Thus it is our responsiblity to provide a graphical user interface and capability negotiation, which usually are performed by data sources. - - -2. WHAT'S IMPLEMENTED - -- Functions that dispatch operations specified by the operation triplets to the corresponding function. - -- All the operation triplets related to the Data Source Manager are implemented. Appplication is able to enumerate data sources and open them. - -- The operation triplets that deal with the UI (such as DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS, MSG_DISABLEDS and MSG_ENABLEDSUIONLY) are partially implemented although it does not really do much. - -- The operation triplets that deal with native image transfers (DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET) are also partially implemented. Still need to figure out how to convert the image data obtained from sane to the Windows DIB format. - -- Only the CAP_ICAPXFERMECH capability is implemented. - - -3. TO-DO - -- Image native transfer is not working correctly right now. It crashed the application due to the invalid DIB created. We need to fix this. - -- Implement other image transfer mode such as file transfer and memory transfer. - -- Support all required TWAIN capabilities that have not been implemented currently. There are a fixed number of capabilities specified by the TWAIN Specification. However, device capabilities are dynamic in SANE and there isn't a standard about the capability names. It would be difficult to negotiate capabilities in TWAIN given that we don't know what capabilities a SANE driver would provide. One possible solution to use a device configuration file to describe the mapping between capabilities supported by a SANE driver and those specified by TWAIN. -- Build a dynamic user interface that reflects the capabilities of different scanner devices. According to the TWAIN specification, each TWAIN driver need to provide its own user interface. However the SANE drivers do not have graphical frontends. Building a frontend for each SANE driver is a huge task. It is possible to have a dynamic frontend similar to xscanimage or xsane that works for all the devices. This is possibly the most difficult part. - -- check into legal issues regarding: - - TWAIN header file - - linking to SANE (maybe should dynamically link at run time?) - -- add autoconf rules for enabling based on whether sane is installed - -4. FILE LISTING - -twain32_main.c Functions to regconize operation tripets and dispatch - the requests to the corresponding functions. -dsm_ctrl.c Implementation of DG_CONTROL group operation triplets - destinated for source manager. -ds_ctrl.c Implementation of DG_CONTROL group operation triplets - destinated for data source. -ds_image.c Implementation of DG_IMAGE group operation triplets - destinated for data source. -ds_audio.c Implementation of DG_AUDIO group operation triplets - destinated for data source -capability.c Functions for negotiating capabilities -twain.h The original TWAIN header file -twain_i.h Header file for the internal twain functions - - --- -Shi Quan He -shiquan@cyberdude.com diff --git a/dlls/twain_32/TWAIN b/dlls/twain_32/TWAIN deleted file mode 100644 index b89f6be6bc7..00000000000 --- a/dlls/twain_32/TWAIN +++ /dev/null @@ -1,172 +0,0 @@ -Requirements to be a TWAIN-Compliant Source -Requirements -TWAIN-compliant Sources must support the following: -Operations ----------- -DG_CONTROL / DAT_CAPABILITY / MSG_GET -DG_CONTROL / DAT_CAPABILITY / MSG_GETCURRENT -DG_CONTROL / DAT_CAPABILITY / MSG_GETDEFAULT -DG_CONTROL / DAT_CAPABILITY / MSG_RESET -DG_CONTROL / DAT_CAPABILITY / MSG_SET -DG_CONTROL / DAT_EVENT / MSG_PROCESSEVENT -DG_CONTROL / DAT_IDENTITY / MSG_GET -DG_CONTROL / DAT_IDENTITY / MSG_OPENDS -DG_CONTROL / DAT_IDENTITY / MSG_CLOSEDS -DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER -DG_CONTROL / DAT_PENDINGXFERS / MSG_GET -DG_CONTROL / DAT_PENDINGXFERS / MSG_RESET -DG_CONTROL / DAT_SETUPMEMXFER / MSG_GET -DG_CONTROL / DAT_STATUS / MSG_GET -DG_CONTROL / DAT_USERINTERFACE / MSG_DISABLEDS -DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS -DG_CONTROL / DAT_XFERGROUP / MSG_GET -DG_IMAGE / DAT_IMAGEINFO / MSG_GET -DG_IMAGE / DAT_IMAGELAYOUT / MSG_GET -DG_IMAGE / DAT_IMAGELAYOUT / MSG_GETDEFAULT -DG_IMAGE / DAT_IMAGELAYOUT / MSG_RESET -DG_IMAGE / DAT_IMAGELAYOUT / MSG_SET -DG_IMAGE / DAT_IMAGEMEMXFER / MSG_GET -DG_IMAGE / DAT_IMAGENATIVEXFER / MSG_GET - -Capabilities ------------- -Every Source must support all five DG_CONTROL / DAT_CAPABILITY operations on: -CAP_XFERCOUNT -Every Source must support DG_CONTROL / DAT_CAPABILITY MSG_GET on: -CAP_SUPPORTEDCAPS -CAP_UICONTROLLABLE -Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY / -MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT on: -ICAP_COMPRESSION -ICAP_PLANARCHUNKY -ICAP_PHYSICALHEIGHT -ICAP_PHYSICALWIDTH -ICAP_PIXELFLAVOR -Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY / -MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT, MSG_RESET and MSG_SET on: -ICAP_BITDEPTH -ICAP_BITORDER -ICAP_PIXELTYPE -ICAP_UNITS -ICAP_XFERMECH -ICAP_XRESOLUTION -ICAP_YRESOLUTION -All Sources must implement the advertised features supported by their devices. They must -make these features available to applications via the TWAIN protocol. For example, a Source -that's connected to a device that has an ADF must support DG_CONTROL / -DAT_CAPABILITY / MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT on: -CAP_FEEDERENABLED -CAP_FEEDERLOADED -and DG_CONTROL / DAT_CAPABILITY / MSG_GET, MSG_GETCURRENT, -MSG_GETDEFAULT, MSG_RESET and MSG_SET on: -CAP_AUTOFEED -If the ADF also supports ejecting and rewinding of pages then the Source should also support -DG_CONTROL / DAT_CAPABILITY / MSG_GET, MSG_GETCURRENT, -MSG_GETDEFAULT, MSG_RESET and MSG_SET on: -CAP_CLEARPAGE -CAP_REWINDPAGE - - -******************************************************************************* - -From Application to Source Manager (Control Information) - -Data Group Data Argument Type Message -DG_CONTROL DAT_IDENTITY MSG_CLOSEDS - MSG_GETDEFAULT - MSG_GETFIRST - MSG_GETNEXT - MSG_OPENDS - MSG_USERSELECT -DG_CONTROL DAT_PARENT MSG_CLOSEDSM - MSG_OPENDSM -DG_CONTROL DAT_STATUS MSG_GET - -From Application to Source (Control Information) -Data Group Data Argument Type Message -DG_CONTROL DAT_CAPABILITY MSG_GET - MSG_GETCURRENT - MSG_GETDEFAULT - MSG_QUERYSUPPORT - MSG_RESET - MSG_SET -DG_CONTROL DAT_CUSTOMDSDATA MSG_GET - MSG_SET -DG_CONTROL DAT_FILESYSTEM MSG_AUTOMATICCAPTURE - DIRECTORY - MSG_CHANGEDIRECTORY - MSG_COPY - MSG_CREATEDIRECTORY - MSG_DELETE - MSG_FORMATMEDIA - MSG_GETCLOSE - MSG_GETFIRSTFILE - MSG_GETINFO - MSG_GETNEXTFILE - MSG_RENAME -DG_CONTROL DAT_EVENT MSG_PROCESSEVENT -DG_CONTROL DAT_PASSTHRU MSG_PASSTHRU -DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER - MSG_GET - MSG_RESET - MSG_STOPFEEDER -DG_CONTROL DAT_SETUPFILEXFER MSG_GET - MSG_GETDEFAULT - MSG_RESET - MSG_SET -DG_CONTROL DAT_SETUPFILEXFER2 MSG_GET - MSG_GETDEFAULT - MSG_RESET - MSG_SET -DG_CONTROL DAT_SETUPMEMXFER MSG_GET -DG_CONTROL DAT_STATUS MSG_GET -DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS - MSG_ENABLEDS - MSG_ENABLEDSUIONLY -DG_CONTROL DAT_XFERGROUP MSG_GET - MSG_SET - -From Application to Source (Image Information) -Data Group Data Argument Type Message -DG_IMAGE DAT_CIECOLOR MSG_GET -DG_IMAGE DAT_EXTIMAGEINFO MSG_GET -DG_IMAGE DAT_GRAYRESPONSE MSG_RESET - MSG_SET -DG_IMAGE DAT_IMAGEFILEXFER MSG_GET -DG_IMAGE DAT_IMAGEINFO MSG_GET -DG_IMAGE DAT_IMAGELAYOUT MSG_GET - MSG_GETDEFAULT - MSG_RESET - MSG_SET -DG_IMAGE DAT_IMAGEMEMXFER MSG_GET -DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET -DG_IMAGE DAT_JPEGCOMPRESSION MSG_GET - MSG_GETDEFAULT - MSG_RESET - MSG_SET -DG_IMAGE DAT_PALETTE8 MSG_GET - MSG_GETDEFAULT - MSG_RESET - MSG_SET -DG_IMAGE DAT_RGBRESPONSE MSG_RESET - MSG_SET - -From Application to Source (Audio Information) -Data Group Data Argument Type Message -DG_AUDIO DAT_AUDIOFILEXFER MSG_GET -DG_AUDIO DAT_AUDIOINFO MSG_GET -DG_AUDIO DAT_AUDIONATIVEXFER MSG_GET - -From Source Manager to Source (Control Information) -Data Group Data Argument Type Message -DG_CONTROL DAT_IDENTITY MSG_CLOSEDS - MSG_GET - MSG_OPENDS - -From Source to Application (Control Information via the Source Manager) -(Used by Windows Sources only) -Data Group Data Argument Type Message -DG_CONTROL DAT_NULL MSG_CLOSEDSOK - MSG_CLOSEDSREQ - MSG_DEVICEEVENT - MSG_XFERREADY diff --git a/dlls/twain_32/dsm_ctrl.c b/dlls/twain_32/dsm_ctrl.c index e0d0983570c..c34bd1d987d 100644 --- a/dlls/twain_32/dsm_ctrl.c +++ b/dlls/twain_32/dsm_ctrl.c @@ -103,8 +103,8 @@ twain_autodetect(void) { if (detectionrun) return; detectionrun = 1; - twain_add_onedriver("gphoto2.ds"); twain_add_onedriver("sane.ds"); + twain_add_onedriver("gphoto2.ds"); #if 0 twain_add_onedriver("c:\\windows\\Twain_32\\Largan\\sp503a.ds"); twain_add_onedriver("c:\\windows\\Twain_32\\vivicam10\\vivicam10.ds"); diff --git a/dlls/twain_32/tests/dsm.c b/dlls/twain_32/tests/dsm.c index 37ebf3b8e76..4218f25fe1b 100644 --- a/dlls/twain_32/tests/dsm.c +++ b/dlls/twain_32/tests/dsm.c @@ -106,7 +106,7 @@ static void check_get(TW_CAPABILITY *pCapability, TW_INT32 actual_support, { if (pCapability->ConType == TWON_ONEVALUE) { - TW_ONEVALUE *onev = (TW_ONEVALUE *) p; + TW_ONEVALUE *onev = p; ok(onev->Item == orig_value || !(actual_support & TWQC_GETCURRENT), "MSG_GET of 0x%x returned 0x%x, expecting 0x%x\n", pCapability->Cap, onev->Item, orig_value); trace("MSG_GET of 0x%x returned val 0x%x, type %d\n", pCapability->Cap, onev->Item, onev->ItemType); @@ -119,7 +119,7 @@ static void check_get(TW_CAPABILITY *pCapability, TW_INT32 actual_support, TW_UINT8 *p8; TW_UINT16 *p16; TW_UINT32 *p32; - TW_ENUMERATION *enumv = (TW_ENUMERATION *) p; + TW_ENUMERATION *enumv = p; p8 = enumv->ItemList; p16 = (TW_UINT16 *) p8; p32 = (TW_UINT32 *) p8; @@ -391,6 +391,198 @@ static void test_resolution(TW_IDENTITY *appid, TW_IDENTITY *source, TW_UINT16 c } } +static void test_physical(TW_IDENTITY *appid, TW_IDENTITY *source, TW_UINT16 captype, TW_INT32 minimum_support) +{ + TW_UINT16 rc; + TW_STATUS status; + TW_CAPABILITY cap; + TW_UINT32 val; + TW_UINT16 type; + TW_INT32 actual_support; + + memset(&cap, 0, sizeof(cap)); + cap.Cap = captype; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_QUERYSUPPORT, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_QUERYSUPPORT for type 0x%x\n", rc, status.ConditionCode, captype); + if (rc != TWRC_SUCCESS) + return; + ok(get_onevalue(cap.hContainer, (TW_UINT32 *) &actual_support, NULL), "Returned cap.hContainer invalid for QuerySupport on type 0x%x\n", captype); + ok((actual_support & minimum_support) == minimum_support, + "Error: minimum support 0x%x for type 0x%x, got 0x%x\n", minimum_support, + captype, actual_support); + + + if (actual_support & TWQC_GETCURRENT) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = captype; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_GETCURRENT, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_GETCURRENT for type 0x%x\n", rc, status.ConditionCode, captype); + if (rc == TWRC_SUCCESS) + { + get_onevalue(cap.hContainer, &val, &type); + ok(type == TWTY_FIX32, "GETCURRENT for PHYSICALXXX is not type FIX32, is type %d\n", type); + GlobalFree(cap.hContainer); + } + } + + if (actual_support & TWQC_GETDEFAULT) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = captype; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_GETDEFAULT, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_GETDEFAULT for type 0x%x\n", rc, status.ConditionCode, captype); + if (rc == TWRC_SUCCESS) + { + get_onevalue(cap.hContainer, &val, &type); + ok(type == TWTY_FIX32, "GETDEFAULT for PHYSICALXXX is not type FIX32, is type %d\n", type); + GlobalFree(cap.hContainer); + } + } + + if (actual_support & TWQC_GET) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = captype; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_GET, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_GET for type 0x%x\n", rc, status.ConditionCode, captype); + if (rc == TWRC_SUCCESS) + { + get_onevalue(cap.hContainer, &val, &type); + ok(type == TWTY_FIX32, "GET for PHYSICALXXX is not type FIX32, is type %d\n", type); + trace("GET for Physical type 0x%x returns 0x%x\n", captype, val); + GlobalFree(cap.hContainer); + } + } + +} + +static void test_supported_sizes(TW_IDENTITY *appid, TW_IDENTITY *source, TW_INT32 minimum_support) +{ + TW_UINT16 rc; + TW_STATUS status; + TW_CAPABILITY cap; + TW_UINT32 val; + TW_UINT16 type; + TW_INT32 actual_support; + TW_UINT32 orig_value; + TW_UINT32 default_value; + TW_UINT32 new_value = TWSS_NONE; + + + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_QUERYSUPPORT, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_QUERYSUPPORT for ICAP_SUPPORTEDSIZES\n", rc, status.ConditionCode); + if (rc != TWRC_SUCCESS) + return; + ok(get_onevalue(cap.hContainer, (TW_UINT32 *) &actual_support, NULL), "Returned cap.hContainer invalid for QuerySupport on ICAP_SUPPORTEDSIZES\n"); + ok((actual_support & minimum_support) == minimum_support, + "Error: minimum support 0x%x for ICAP_SUPPORTEDSIZES, got 0x%x\n", minimum_support, actual_support); + + if (actual_support & TWQC_GETCURRENT) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_GETCURRENT, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_GETCURRENT for ICAP_SUPPORTEDSIZES\n", rc, status.ConditionCode); + if (rc == TWRC_SUCCESS) + { + get_onevalue(cap.hContainer, &val, &type); + ok(type == TWTY_UINT16, "GETCURRENT for ICAP_SUPPORTEDSIZES is not type UINT16, is type %d\n", type); + trace("Current size is %d\n", val); + GlobalFree(cap.hContainer); + orig_value = val; + } + } + + if (actual_support & TWQC_GETDEFAULT) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_GETDEFAULT, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_GETDEFAULT for ICAP_SUPPORTEDSIZES\n", rc, status.ConditionCode); + if (rc == TWRC_SUCCESS) + { + get_onevalue(cap.hContainer, &val, &type); + ok(type == TWTY_UINT16, "GETDEFAULT for PHYSICALXXX is not type TWTY_UINT16, is type %d\n", type); + trace("Default size is %d\n", val); + GlobalFree(cap.hContainer); + default_value = val; + } + } + + if (actual_support & TWQC_GET) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_GET, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_GET for ICAP_SUPPORTEDSIZES\n", rc, status.ConditionCode); + check_get(&cap, actual_support, orig_value, default_value, &new_value); + } + + if (actual_support & TWQC_SET) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_ONEVALUE; + cap.hContainer = alloc_and_set_onevalue(new_value, TWTY_UINT16); + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_SET, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_SET for ICAP_SUPPORTEDSIZES\n", rc, status.ConditionCode); + GlobalFree(cap.hContainer); + + } + + if (actual_support & TWQC_RESET) + { + memset(&cap, 0, sizeof(cap)); + cap.Cap = ICAP_SUPPORTEDSIZES; + cap.ConType = TWON_DONTCARE16; + + rc = pDSM_Entry(appid, source, DG_CONTROL, DAT_CAPABILITY, MSG_RESET, &cap); + get_condition_code(appid, source, &status); + ok(rc == TWRC_SUCCESS && status.ConditionCode == TWCC_SUCCESS, + "Error [rc %d|cc %d] doing MSG_RESET for ICAP_SUPPORTEDSIZES\n", rc, status.ConditionCode); + if (rc == TWRC_SUCCESS) + GlobalFree(cap.hContainer); + } +} + static void test_single_source(TW_IDENTITY *appid, TW_IDENTITY *source) { @@ -453,10 +645,14 @@ static void test_single_source(TW_IDENTITY *appid, TW_IDENTITY *source) TWQC_GET | TWQC_GETDEFAULT | TWQC_GETCURRENT); todo_wine ok(capabilities[ICAP_PLANARCHUNKY], "ICAP_PLANARCHUNKY not supported\n"); - todo_wine ok(capabilities[ICAP_PHYSICALHEIGHT], "ICAP_PHYSICALHEIGHT not supported\n"); - todo_wine + if (capabilities[ICAP_PHYSICALHEIGHT]) + test_physical(appid, source, ICAP_PHYSICALHEIGHT, + TWQC_GET | TWQC_GETDEFAULT | TWQC_GETCURRENT); ok(capabilities[ICAP_PHYSICALWIDTH], "ICAP_PHYSICALWIDTH not supported\n"); + if (capabilities[ICAP_PHYSICALWIDTH]) + test_physical(appid, source, ICAP_PHYSICALWIDTH, + TWQC_GET | TWQC_GETDEFAULT | TWQC_GETCURRENT); ok(capabilities[ICAP_PIXELFLAVOR], "ICAP_PIXELFLAVOR not supported\n"); if (capabilities[ICAP_PIXELFLAVOR]) test_onevalue_cap(appid, source, ICAP_PIXELFLAVOR, TWTY_UINT16, @@ -492,6 +688,18 @@ static void test_single_source(TW_IDENTITY *appid, TW_IDENTITY *source) if (capabilities[ICAP_YRESOLUTION]) test_resolution(appid, source, ICAP_YRESOLUTION, TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET); + + /* Optional capabilities */ + if (capabilities[CAP_AUTOFEED]) + test_onevalue_cap(appid, source, CAP_AUTOFEED, TWTY_BOOL, + TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET); + if (capabilities[CAP_FEEDERENABLED]) + test_onevalue_cap(appid, source, CAP_FEEDERENABLED, TWTY_BOOL, + TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET); + if (capabilities[ICAP_SUPPORTEDSIZES]) + test_supported_sizes(appid, source, + TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET); + } } diff --git a/dlls/urlmon/Makefile.in b/dlls/urlmon/Makefile.in index 0a9497c517b..825eab256c6 100644 --- a/dlls/urlmon/Makefile.in +++ b/dlls/urlmon/Makefile.in @@ -14,6 +14,7 @@ C_SRCS = \ file.c \ format.c \ ftp.c \ + gopher.c \ http.c \ internet.c \ mk.c \ diff --git a/dlls/urlmon/ftp.c b/dlls/urlmon/ftp.c index f79641ee4a1..dbdd7a7fd37 100644 --- a/dlls/urlmon/ftp.c +++ b/dlls/urlmon/ftp.c @@ -1,5 +1,5 @@ /* - * Copyright 2005 Jacek Caban + * Copyright 2005-2009 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,17 +22,64 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); typedef struct { + Protocol base; + const IInternetProtocolVtbl *lpInternetProtocolVtbl; const IInternetPriorityVtbl *lpInternetPriorityVtbl; LONG ref; } FtpProtocol; -#define PROTOCOL_THIS(iface) DEFINE_THIS(FtpProtocol, InternetProtocol, iface) - #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl) +#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(FtpProtocol, base, iface) + +static HRESULT FtpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags, + IInternetBindInfo *bind_info) +{ + FtpProtocol *This = ASYNCPROTOCOL_THIS(prot); + + This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0, + request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE, + (DWORD_PTR)&This->base); + if (!This->base.request && GetLastError() != ERROR_IO_PENDING) { + WARN("InternetOpenUrl failed: %d\n", GetLastError()); + return INET_E_RESOURCE_NOT_FOUND; + } + + return S_OK; +} + +static HRESULT FtpProtocol_start_downloading(Protocol *prot) +{ + FtpProtocol *This = ASYNCPROTOCOL_THIS(prot); + DWORD size; + BOOL res; + + res = FtpGetFileSize(This->base.request, &size); + if(res) + This->base.content_length = size; + else + WARN("FtpGetFileSize failed: %d\n", GetLastError()); + + return S_OK; +} + +static void FtpProtocol_close_connection(Protocol *prot) +{ +} + +#undef ASYNCPROTOCOL_THIS + +static const ProtocolVtbl AsyncProtocolVtbl = { + FtpProtocol_open_request, + FtpProtocol_start_downloading, + FtpProtocol_close_connection +}; + +#define PROTOCOL_THIS(iface) DEFINE_THIS(FtpProtocol, InternetProtocol, iface) + static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { FtpProtocol *This = PROTOCOL_THIS(iface); @@ -77,6 +124,7 @@ static ULONG WINAPI FtpProtocol_Release(IInternetProtocol *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + protocol_close_connection(&This->base); heap_free(This); URLMON_UnlockModule(); @@ -90,16 +138,25 @@ static HRESULT WINAPI FtpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, DWORD grfPI, DWORD dwReserved) { FtpProtocol *This = PROTOCOL_THIS(iface); - FIXME("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink, - pOIBindInfo, grfPI, dwReserved); - return E_NOTIMPL; + + static const WCHAR ftpW[] = {'f','t','p',':'}; + + TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink, + pOIBindInfo, grfPI, dwReserved); + + if(strncmpW(szUrl, ftpW, sizeof(ftpW)/sizeof(WCHAR))) + return MK_E_SYNTAX; + + return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink, pOIBindInfo); } static HRESULT WINAPI FtpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) { FtpProtocol *This = PROTOCOL_THIS(iface); - FIXME("(%p)->(%p)\n", This, pProtocolData); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, pProtocolData); + + return protocol_continue(&This->base, pProtocolData); } static HRESULT WINAPI FtpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, @@ -113,8 +170,11 @@ static HRESULT WINAPI FtpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReas static HRESULT WINAPI FtpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions) { FtpProtocol *This = PROTOCOL_THIS(iface); - FIXME("(%p)->(%08x)\n", This, dwOptions); - return E_NOTIMPL; + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + protocol_close_connection(&This->base); + return S_OK; } static HRESULT WINAPI FtpProtocol_Suspend(IInternetProtocol *iface) @@ -135,8 +195,10 @@ static HRESULT WINAPI FtpProtocol_Read(IInternetProtocol *iface, void *pv, ULONG cb, ULONG *pcbRead) { FtpProtocol *This = PROTOCOL_THIS(iface); - FIXME("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); - return E_NOTIMPL; + + TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); + + return protocol_read(&This->base, pv, cb, pcbRead); } static HRESULT WINAPI FtpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, @@ -150,15 +212,19 @@ static HRESULT WINAPI FtpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER d static HRESULT WINAPI FtpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions) { FtpProtocol *This = PROTOCOL_THIS(iface); - FIXME("(%p)->(%08x)\n", This, dwOptions); - return E_NOTIMPL; + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + return protocol_lock_request(&This->base); } static HRESULT WINAPI FtpProtocol_UnlockRequest(IInternetProtocol *iface) { FtpProtocol *This = PROTOCOL_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + + TRACE("(%p)\n", This); + + return protocol_unlock_request(&This->base); } #undef PROTOCOL_THIS @@ -202,15 +268,21 @@ static ULONG WINAPI FtpPriority_Release(IInternetPriority *iface) static HRESULT WINAPI FtpPriority_SetPriority(IInternetPriority *iface, LONG nPriority) { FtpProtocol *This = PRIORITY_THIS(iface); - FIXME("(%p)->(%d)\n", This, nPriority); - return E_NOTIMPL; + + TRACE("(%p)->(%d)\n", This, nPriority); + + This->base.priority = nPriority; + return S_OK; } static HRESULT WINAPI FtpPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority) { FtpProtocol *This = PRIORITY_THIS(iface); - FIXME("(%p)->(%p)\n", This, pnPriority); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, pnPriority); + + *pnPriority = This->base.priority; + return S_OK; } #undef PRIORITY_THIS @@ -231,8 +303,9 @@ HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) URLMON_LockModule(); - ret = heap_alloc(sizeof(FtpProtocol)); + ret = heap_alloc_zero(sizeof(FtpProtocol)); + ret->base.vtbl = &AsyncProtocolVtbl; ret->lpInternetProtocolVtbl = &FtpProtocolVtbl; ret->lpInternetPriorityVtbl = &FtpPriorityVtbl; ret->ref = 1; diff --git a/dlls/urlmon/gopher.c b/dlls/urlmon/gopher.c new file mode 100644 index 00000000000..c562657152c --- /dev/null +++ b/dlls/urlmon/gopher.c @@ -0,0 +1,299 @@ +/* + * Copyright 2009 Jacek Caban 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 "urlmon_main.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(urlmon); + +typedef struct { + Protocol base; + + const IInternetProtocolVtbl *lpInternetProtocolVtbl; + const IInternetPriorityVtbl *lpInternetPriorityVtbl; + + LONG ref; +} GopherProtocol; + +#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) +#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl) + +#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(GopherProtocol, base, iface) + +static HRESULT GopherProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags, + IInternetBindInfo *bind_info) +{ + GopherProtocol *This = ASYNCPROTOCOL_THIS(prot); + + This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0, + request_flags, (DWORD_PTR)&This->base); + if (!This->base.request && GetLastError() != ERROR_IO_PENDING) { + WARN("InternetOpenUrl failed: %d\n", GetLastError()); + return INET_E_RESOURCE_NOT_FOUND; + } + + return S_OK; +} + +static HRESULT GopherProtocol_start_downloading(Protocol *prot) +{ + return S_OK; +} + +static void GopherProtocol_close_connection(Protocol *prot) +{ +} + +#undef ASYNCPROTOCOL_THIS + +static const ProtocolVtbl AsyncProtocolVtbl = { + GopherProtocol_open_request, + GopherProtocol_start_downloading, + GopherProtocol_close_connection +}; + +#define PROTOCOL_THIS(iface) DEFINE_THIS(GopherProtocol, InternetProtocol, iface) + +static HRESULT WINAPI GopherProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + *ppv = NULL; + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = PROTOCOL(This); + }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { + TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); + *ppv = PROTOCOL(This); + }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { + TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv); + *ppv = PROTOCOL(This); + }else if(IsEqualGUID(&IID_IInternetPriority, riid)) { + TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv); + *ppv = PRIORITY(This); + } + + if(*ppv) { + IInternetProtocol_AddRef(iface); + return S_OK; + } + + WARN("not supported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI GopherProtocol_AddRef(IInternetProtocol *iface) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) ref=%d\n", This, ref); + return ref; +} + +static ULONG WINAPI GopherProtocol_Release(IInternetProtocol *iface) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + heap_free(This); + + URLMON_UnlockModule(); + } + + return ref; +} + +static HRESULT WINAPI GopherProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, + IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, + DWORD grfPI, DWORD dwReserved) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink, + pOIBindInfo, grfPI, dwReserved); + + return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink, pOIBindInfo); +} + +static HRESULT WINAPI GopherProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pProtocolData); + + return protocol_continue(&This->base, pProtocolData); +} + +static HRESULT WINAPI GopherProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, + DWORD dwOptions) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); + return E_NOTIMPL; +} + +static HRESULT WINAPI GopherProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + protocol_close_connection(&This->base); + return S_OK; +} + +static HRESULT WINAPI GopherProtocol_Suspend(IInternetProtocol *iface) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI GopherProtocol_Resume(IInternetProtocol *iface) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI GopherProtocol_Read(IInternetProtocol *iface, void *pv, + ULONG cb, ULONG *pcbRead) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); + + return protocol_read(&This->base, pv, cb, pcbRead); +} + +static HRESULT WINAPI GopherProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, + DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); + return E_NOTIMPL; +} + +static HRESULT WINAPI GopherProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + return protocol_lock_request(&This->base); +} + +static HRESULT WINAPI GopherProtocol_UnlockRequest(IInternetProtocol *iface) +{ + GopherProtocol *This = PROTOCOL_THIS(iface); + + TRACE("(%p)\n", This); + + return protocol_unlock_request(&This->base); +} + +#undef PROTOCOL_THIS + +static const IInternetProtocolVtbl GopherProtocolVtbl = { + GopherProtocol_QueryInterface, + GopherProtocol_AddRef, + GopherProtocol_Release, + GopherProtocol_Start, + GopherProtocol_Continue, + GopherProtocol_Abort, + GopherProtocol_Terminate, + GopherProtocol_Suspend, + GopherProtocol_Resume, + GopherProtocol_Read, + GopherProtocol_Seek, + GopherProtocol_LockRequest, + GopherProtocol_UnlockRequest +}; + +#define PRIORITY_THIS(iface) DEFINE_THIS(GopherProtocol, InternetPriority, iface) + +static HRESULT WINAPI GopherPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv) +{ + GopherProtocol *This = PRIORITY_THIS(iface); + return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv); +} + +static ULONG WINAPI GopherPriority_AddRef(IInternetPriority *iface) +{ + GopherProtocol *This = PRIORITY_THIS(iface); + return IInternetProtocol_AddRef(PROTOCOL(This)); +} + +static ULONG WINAPI GopherPriority_Release(IInternetPriority *iface) +{ + GopherProtocol *This = PRIORITY_THIS(iface); + return IInternetProtocol_Release(PROTOCOL(This)); +} + +static HRESULT WINAPI GopherPriority_SetPriority(IInternetPriority *iface, LONG nPriority) +{ + GopherProtocol *This = PRIORITY_THIS(iface); + + TRACE("(%p)->(%d)\n", This, nPriority); + + This->base.priority = nPriority; + return S_OK; +} + +static HRESULT WINAPI GopherPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority) +{ + GopherProtocol *This = PRIORITY_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pnPriority); + + *pnPriority = This->base.priority; + return S_OK; +} + +#undef PRIORITY_THIS + +static const IInternetPriorityVtbl GopherPriorityVtbl = { + GopherPriority_QueryInterface, + GopherPriority_AddRef, + GopherPriority_Release, + GopherPriority_SetPriority, + GopherPriority_GetPriority +}; + +HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +{ + GopherProtocol *ret; + + TRACE("(%p %p)\n", pUnkOuter, ppobj); + + URLMON_LockModule(); + + ret = heap_alloc_zero(sizeof(GopherProtocol)); + + ret->base.vtbl = &AsyncProtocolVtbl; + ret->lpInternetProtocolVtbl = &GopherProtocolVtbl; + ret->lpInternetPriorityVtbl = &GopherPriorityVtbl; + ret->ref = 1; + + *ppobj = PROTOCOL(ret); + + return S_OK; +} diff --git a/dlls/urlmon/tests/misc.c b/dlls/urlmon/tests/misc.c index 2123392ebce..7702e1e167f 100644 --- a/dlls/urlmon/tests/misc.c +++ b/dlls/urlmon/tests/misc.c @@ -943,22 +943,27 @@ static void test_ZoneManager(void) IInternetZoneManager *zonemgr = NULL; BYTE buf[32]; HRESULT hres; + DWORD action = URLACTION_CREDENTIALS_USE; /* Implemented on all IE versions */ hres = CoInternetCreateZoneManager(NULL, &zonemgr, 0); ok(hres == S_OK, "CoInternetCreateZoneManager failed: %08x\n", hres); if(FAILED(hres)) return; - hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1a10, buf, + hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf, sizeof(DWORD), URLZONEREG_DEFAULT); ok(hres == S_OK, "GetZoneActionPolicy failed: %08x\n", hres); - ok(*(DWORD*)buf == 1, "policy=%d, expected 1\n", *(DWORD*)buf); + ok(*(DWORD*)buf == URLPOLICY_CREDENTIALS_SILENT_LOGON_OK || + *(DWORD*)buf == URLPOLICY_CREDENTIALS_MUST_PROMPT_USER || + *(DWORD*)buf == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT || + *(DWORD*)buf == URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY, + "unexpected policy=%d\n", *(DWORD*)buf); - hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1a10, NULL, + hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, NULL, sizeof(DWORD), URLZONEREG_DEFAULT); ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres); - hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, 0x1a10, buf, + hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 3, action, buf, 2, URLZONEREG_DEFAULT); ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres); @@ -966,7 +971,7 @@ static void test_ZoneManager(void) sizeof(DWORD), URLZONEREG_DEFAULT); ok(hres == E_FAIL, "GetZoneActionPolicy failed: %08x, expected E_FAIL\n", hres); - hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, 0x1a10, buf, + hres = IInternetZoneManager_GetZoneActionPolicy(zonemgr, 13, action, buf, sizeof(DWORD), URLZONEREG_DEFAULT); ok(hres == E_INVALIDARG, "GetZoneActionPolicy failed: %08x, expected E_INVALIDARG\n", hres); diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c index eb422828cdc..c9c42e8d673 100644 --- a/dlls/urlmon/tests/protocol.c +++ b/dlls/urlmon/tests/protocol.c @@ -110,7 +110,7 @@ static const WCHAR emptyW[] = {0}; static HRESULT expect_hrResult; static LPCWSTR file_name, http_url, expect_wsz; -static IInternetProtocol *http_protocol = NULL; +static IInternetProtocol *async_protocol = NULL; static BOOL first_data_notif = FALSE, http_is_first = FALSE, http_post_test = FALSE; static int state = 0, prot_state; @@ -128,6 +128,7 @@ static enum { FILE_TEST, HTTP_TEST, HTTPS_TEST, + FTP_TEST, MK_TEST, BIND_TEST } tested_protocol; @@ -135,13 +136,20 @@ static enum { static const WCHAR protocol_names[][10] = { {'f','i','l','e',0}, {'h','t','t','p',0}, + {'h','t','t','p','s',0}, + {'f','t','p',0}, {'m','k',0}, {'t','e','s','t',0} }; -static const WCHAR binding_urls[][30] = { +static const WCHAR binding_urls[][130] = { {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0}, {'h','t','t','p',':','/','/','t','e','s','t','/','t','e','s','t','.','h','t','m','l',0}, + {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s', + '.','c','o','m','/','t','e','s','t','.','h','t','m','l',0}, + {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g', + '/','p','u','b','/','o','t','h','e','r', + '/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0}, {'m','k',':','t','e','s','t',0}, {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0} }; @@ -356,37 +364,49 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL } if (!state) { - if (http_is_first) { - CLEAR_CALLED(ReportProgress_FINDINGRESOURCE); - CLEAR_CALLED(ReportProgress_CONNECTING); - CLEAR_CALLED(ReportProgress_PROXYDETECTING); - } else todo_wine { - CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE); - /* IE7 does call this */ - CLEAR_CALLED(ReportProgress_CONNECTING); + if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) { + if (http_is_first) { + CLEAR_CALLED(ReportProgress_FINDINGRESOURCE); + CLEAR_CALLED(ReportProgress_CONNECTING); + CLEAR_CALLED(ReportProgress_PROXYDETECTING); + } else todo_wine { + CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE); + /* IE7 does call this */ + CLEAR_CALLED(ReportProgress_CONNECTING); + } + } + if(tested_protocol == FTP_TEST) + todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST); + else + CHECK_CALLED(ReportProgress_SENDINGREQUEST); + if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) { + SET_EXPECT(OnResponse); + if(tested_protocol == HTTPS_TEST) + SET_EXPECT(ReportProgress_ACCEPTRANGES); + SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); + if(bindf & BINDF_NEEDFILE) + SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE); } - CHECK_CALLED(ReportProgress_SENDINGREQUEST); - SET_EXPECT(OnResponse); - if(tested_protocol == HTTPS_TEST) - SET_EXPECT(ReportProgress_ACCEPTRANGES); - SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); - if(bindf & BINDF_NEEDFILE) - SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE); } SET_EXPECT(ReportData); - hres = IInternetProtocol_Continue(http_protocol, pProtocolData); + hres = IInternetProtocol_Continue(async_protocol, pProtocolData); ok(hres == S_OK, "Continue failed: %08x\n", hres); - CHECK_CALLED(ReportData); + if(tested_protocol == FTP_TEST) + CLEAR_CALLED(ReportData); + else + CHECK_CALLED(ReportData); if (!state) { state = 1; - CHECK_CALLED(OnResponse); - if(tested_protocol == HTTPS_TEST) - CHECK_CALLED(ReportProgress_ACCEPTRANGES); - CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); - if(bindf & BINDF_NEEDFILE) - CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE); + if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) { + CHECK_CALLED(OnResponse); + if(tested_protocol == HTTPS_TEST) + CHECK_CALLED(ReportProgress_ACCEPTRANGES); + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + if(bindf & BINDF_NEEDFILE) + CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE); + } } SetEvent(event_complete); @@ -451,7 +471,7 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ok(szStatusText != NULL, "szStatusText == NULL\n"); break; case BINDSTATUS_SENDINGREQUEST: - CHECK_EXPECT(ReportProgress_SENDINGREQUEST); + CHECK_EXPECT2(ReportProgress_SENDINGREQUEST); if(tested_protocol == FILE_TEST) { ok(szStatusText != NULL, "szStatusText == NULL\n"); if(szStatusText) @@ -508,7 +528,7 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax); ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION), "grcfBSCF = %08x\n", grfBSCF); - }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST)) { + }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST)) { if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE)) CHECK_EXPECT(ReportData); else if (http_post_test) @@ -570,9 +590,12 @@ static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HR { CHECK_EXPECT(ReportResult); - ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n", - hrResult, expect_hrResult); - if(SUCCEEDED(hrResult)) + if(tested_protocol == FTP_TEST) + ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult); + else + ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n", + hrResult, expect_hrResult); + if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST) ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError); else ok(dwError != ERROR_SUCCESS, "dwError == ERROR_SUCCESS\n"); @@ -1529,7 +1552,7 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL is_first) if (http_post_test) SET_EXPECT(GetBindString_POST_COOKIE); - hres = IInternetProtocol_Start(http_protocol, url, &protocol_sink, &bind_info, 0, 0); + hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0); ok(hres == S_OK, "Start failed: %08x\n", hres); if(FAILED(hres)) return FALSE; @@ -1558,6 +1581,35 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL is_first) return TRUE; } +static void test_protocol_terminate(IInternetProtocol *protocol) +{ + BYTE buf[3600]; + DWORD cb; + HRESULT hres; + + hres = IInternetProtocol_LockRequest(protocol, 0); + ok(hres == S_OK, "LockRequest failed: %08x\n", hres); + + hres = IInternetProtocol_Read(protocol, buf, 1, &cb); + ok(hres == S_FALSE, "Read failed: %08x\n", hres); + + hres = IInternetProtocol_Terminate(protocol, 0); + ok(hres == S_OK, "Terminate failed: %08x\n", hres); + + /* This wait is to give the internet handles being freed in Terminate + * enough time to actually terminate in all cases. Internet handles + * terminate asynchronously and native reuses the main InternetOpen + * handle. The only case in which this seems to be necessary is on + * wine with native wininet and urlmon, resulting in the next time + * test_http_protocol_url being called the first data notification actually + * being an extra last data notification from the previous connection + * about once out of every ten times. */ + Sleep(100); + + hres = IInternetProtocol_UnlockRequest(protocol); + ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres); +} + /* is_first refers to whether this is the first call to this function * _for this url_ */ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) @@ -1588,13 +1640,14 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) return; hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, - (void**)&http_protocol); + (void**)&async_protocol); ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres); if(SUCCEEDED(hres)) { BYTE buf[3600]; DWORD cb; + ULONG ref; - test_priority(http_protocol); + test_priority(async_protocol); SET_EXPECT(ReportProgress_FINDINGRESOURCE); SET_EXPECT(ReportProgress_CONNECTING); @@ -1616,7 +1669,7 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) SET_EXPECT(ReportResult); expect_hrResult = S_OK; - hres = IInternetProtocol_Read(http_protocol, buf, 1, &cb); + hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb); ok((hres == E_PENDING && cb==0) || (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); @@ -1631,9 +1684,9 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) SET_EXPECT(Switch); else SET_EXPECT(ReportData); - hres = IInternetProtocol_Read(http_protocol, buf, sizeof(buf), &cb); + hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb); if(hres == E_PENDING) { - hres = IInternetProtocol_Read(http_protocol, buf, 1, &cb); + hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb); ok((hres == E_PENDING && cb==0) || (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); WaitForSingleObject(event_complete, INFINITE); @@ -1641,7 +1694,7 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) CHECK_CALLED(Switch); else CHECK_CALLED(ReportData); - } else { + }else { if(bindf & BINDF_FROMURLMON) CHECK_NOT_CALLED(Switch); else @@ -1652,29 +1705,9 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) ok(hres == S_FALSE, "Read failed: %08x\n", hres); CHECK_CALLED(ReportResult); - hres = IInternetProtocol_LockRequest(http_protocol, 0); - ok(hres == S_OK, "LockRequest failed: %08x\n", hres); - - hres = IInternetProtocol_Read(http_protocol, buf, 1, &cb); - ok(hres == S_FALSE, "Read failed: %08x\n", hres); - - hres = IInternetProtocol_Terminate(http_protocol, 0); - ok(hres == S_OK, "Terminate failed: %08x\n", hres); - - /* This wait is to give the internet handles being freed in Terminate - * enough time to actually terminate in all cases. Internet handles - * terminate asynchronously and native reuses the main InternetOpen - * handle. The only case in which this seems to be necessary is on - * wine with native wininet and urlmon, resulting in the next time - * test_http_protocol_url being called the first data notification actually - * being an extra last data notification from the previous connection - * about once out of every ten times. */ - Sleep(100); - - hres = IInternetProtocol_UnlockRequest(http_protocol); - ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres); - - IInternetProtocol_Release(http_protocol); + test_protocol_terminate(async_protocol); + ref = IInternetProtocol_Release(async_protocol); + ok(!ref, "ref=%x\n", hres); } IClassFactory_Release(factory); @@ -1724,6 +1757,126 @@ static void test_https_protocol(void) test_http_protocol_url(codeweavers_url, TRUE, TRUE); } + +static void test_ftp_protocol(void) +{ + IInternetProtocolInfo *protocol_info; + IClassFactory *factory; + IUnknown *unk; + BYTE buf[4096]; + ULONG ref; + DWORD cb; + HRESULT hres; + + static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g', + '/','p','u','b','/','o','t','h','e','r','/', + 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0}; + + trace("Testing ftp protocol...\n"); + + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE; + state = 0; + tested_protocol = FTP_TEST; + first_data_notif = TRUE; + expect_hrResult = E_PENDING; + + hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); + ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info); + ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres); + + hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory); + ok(hres == S_OK, "Could not get IClassFactory interface\n"); + IUnknown_Release(unk); + if(FAILED(hres)) + return; + + hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, + (void**)&async_protocol); + IClassFactory_Release(factory); + ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres); + + test_priority(async_protocol); + + SET_EXPECT(GetBindInfo); + SET_EXPECT(GetBindString_USER_AGENT); + SET_EXPECT(ReportProgress_FINDINGRESOURCE); + SET_EXPECT(ReportProgress_CONNECTING); + SET_EXPECT(ReportProgress_SENDINGREQUEST); + SET_EXPECT(Switch); + + hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0); + ok(hres == S_OK, "Start failed: %08x\n", hres); + CHECK_CALLED(GetBindInfo); + todo_wine CHECK_NOT_CALLED(GetBindString_USER_AGENT); + + SET_EXPECT(ReportResult); + + hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb); + ok((hres == E_PENDING && cb==0) || + (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); + + WaitForSingleObject(event_complete, INFINITE); + CHECK_CALLED(Switch); + + while(1) { + SET_EXPECT(Switch); + + hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb); + if(hres == E_PENDING) { + WaitForSingleObject(event_complete, INFINITE); + CHECK_CALLED(Switch); + }else { + CHECK_NOT_CALLED(Switch); + if(cb == 0) break; + } + } + + ok(hres == S_FALSE, "Read failed: %08x\n", hres); + CHECK_CALLED(ReportResult); + + test_protocol_terminate(async_protocol); + + ref = IInternetProtocol_Release(async_protocol); + ok(!ref, "ref=%d\n", ref); +} + +static void test_gopher_protocol(void) +{ + IInternetProtocolInfo *protocol_info; + IClassFactory *factory; + IUnknown *unk; + HRESULT hres; + + trace("Testing gopher protocol...\n"); + + hres = CoGetClassObject(&CLSID_GopherProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); + ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info); + ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres); + + hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory); + ok(hres == S_OK, "Could not get IClassFactory interface\n"); + IUnknown_Release(unk); + if(FAILED(hres)) + return; + + hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, + (void**)&async_protocol); + IClassFactory_Release(factory); + ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres); + + test_priority(async_protocol); + + IInternetProtocol_Release(async_protocol); +} + static void test_mk_protocol(void) { IInternetProtocolInfo *protocol_info; @@ -2011,6 +2164,8 @@ START_TEST(protocol) test_file_protocol(); test_http_protocol(); test_https_protocol(); + test_ftp_protocol(); + test_gopher_protocol(); test_mk_protocol(); test_CreateBinding(); test_binding(FILE_TEST); diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index e56d0ca4b29..6b57e1f5913 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -147,6 +147,9 @@ static const WCHAR MK_URL[] = {'m','k',':','@','M','S','I','T','S','t','o','r',' static const WCHAR https_urlW[] = {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m', '/','t','e','s','t','.','h','t','m','l',0}; +static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g', + '/','p','u','b','/','o','t','h','e','r','/', + 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0}; static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; @@ -179,7 +182,8 @@ static LPCWSTR urls[] = { INDEX_HTML, ITS_URL, MK_URL, - https_urlW + https_urlW, + ftp_urlW }; static WCHAR file_url[INTERNET_MAX_URL_LENGTH]; @@ -190,7 +194,8 @@ static enum { FILE_TEST, ITS_TEST, MK_TEST, - HTTPS_TEST + HTTPS_TEST, + FTP_TEST } test_protocol; static enum { @@ -1150,6 +1155,8 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP case BINDSTATUS_FINDINGRESOURCE: if(iface == &objbsc) CHECK_EXPECT(Obj_OnProgress_FINDINGRESOURCE); + else if(test_protocol == FTP_TEST) + todo_wine CHECK_EXPECT(OnProgress_FINDINGRESOURCE); else CHECK_EXPECT(OnProgress_FINDINGRESOURCE); if((bindf & BINDF_ASYNCHRONOUS) && emulate_protocol) @@ -1158,6 +1165,8 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP case BINDSTATUS_CONNECTING: if(iface == &objbsc) CHECK_EXPECT(Obj_OnProgress_CONNECTING); + else if(test_protocol == FTP_TEST) + todo_wine CHECK_EXPECT(OnProgress_CONNECTING); else CHECK_EXPECT(OnProgress_CONNECTING); if((bindf & BINDF_ASYNCHRONOUS) && emulate_protocol) @@ -1166,6 +1175,8 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP case BINDSTATUS_SENDINGREQUEST: if(iface == &objbsc) CHECK_EXPECT(Obj_OnProgress_SENDINGREQUEST); + else if(test_protocol == FTP_TEST) + CHECK_EXPECT2(OnProgress_SENDINGREQUEST); else CHECK_EXPECT(OnProgress_SENDINGREQUEST); if((bindf & BINDF_ASYNCHRONOUS) && emulate_protocol) @@ -2077,7 +2088,8 @@ static void test_BindToStorage(int protocol, BOOL emul, DWORD t) SET_EXPECT(OnProgress_FINDINGRESOURCE); SET_EXPECT(OnProgress_CONNECTING); } - if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST) + if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST + || test_protocol == FILE_TEST) SET_EXPECT(OnProgress_SENDINGREQUEST); if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) SET_EXPECT(OnResponse); @@ -2085,7 +2097,7 @@ static void test_BindToStorage(int protocol, BOOL emul, DWORD t) SET_EXPECT(OnProgress_BEGINDOWNLOADDATA); if(test_protocol == FILE_TEST) SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE); - if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) + if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST) SET_EXPECT(OnProgress_DOWNLOADINGDATA); SET_EXPECT(OnProgress_ENDDOWNLOADDATA); if(tymed != TYMED_FILE || test_protocol != ABOUT_TEST) @@ -2161,13 +2173,15 @@ static void test_BindToStorage(int protocol, BOOL emul, DWORD t) } if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST) CHECK_CALLED(OnProgress_SENDINGREQUEST); + else if(test_protocol == FTP_TEST) + todo_wine CHECK_CALLED(OnProgress_SENDINGREQUEST); if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) CHECK_CALLED(OnResponse); CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA); if(test_protocol == FILE_TEST) CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE); - if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) + if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST) CLEAR_CALLED(OnProgress_DOWNLOADINGDATA); CHECK_CALLED(OnProgress_ENDDOWNLOADDATA); if(tymed != TYMED_FILE || test_protocol != ABOUT_TEST) @@ -2708,6 +2722,11 @@ START_TEST(url) trace("test URLDownloadToFile for http protocol...\n"); test_URLDownloadToFile(HTTP_TEST, FALSE); + bindf |= BINDF_NOWRITECACHE; + + trace("ftp test...\n"); + test_BindToStorage(FTP_TEST, FALSE, TYMED_ISTREAM); + trace("test failures...\n"); test_BindToStorage_fail(); } diff --git a/dlls/urlmon/umon.c b/dlls/urlmon/umon.c index bbaed5b7a2a..770e46e3624 100644 --- a/dlls/urlmon/umon.c +++ b/dlls/urlmon/umon.c @@ -33,251 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); -/* native urlmon.dll uses this key, too */ -static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 }; - -/*static BOOL registered_wndclass = FALSE;*/ - -typedef struct { - const IBindingVtbl *lpVtbl; - - LONG ref; - - LPWSTR URLName; - - HWND hwndCallback; - IBindCtx *pBC; - HINTERNET hinternet, hconnect, hrequest; - HANDLE hCacheFile; - IUMCacheStream *pstrCache; - IBindStatusCallback *pbscb; - DWORD total_read, expected_size; -} Binding; - -static HRESULT WINAPI Binding_QueryInterface(IBinding* iface, REFIID riid, void **ppvObject) -{ - Binding *This = (Binding*)iface; - - TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject); - - if((This == NULL) || (ppvObject == NULL)) - return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IBinding, riid)) { - *ppvObject = iface; - IBinding_AddRef(iface); - return S_OK; - } - - *ppvObject = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI Binding_AddRef(IBinding* iface) -{ - Binding *This = (Binding*)iface; - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - return ref; -} - -static ULONG WINAPI Binding_Release(IBinding* iface) -{ - Binding *This = (Binding*)iface; - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%d\n",This, ref); - - if(!ref) { - heap_free(This->URLName); - if (This->hCacheFile) - CloseHandle(This->hCacheFile); - if (This->pstrCache) - { - UMCloseCacheFileStream(This->pstrCache); - IStream_Release((IStream *)This->pstrCache); - } - if (This->pbscb) - IBindStatusCallback_Release(This->pbscb); - - heap_free(This); - - URLMON_UnlockModule(); - } - - return ref; -} - -static HRESULT WINAPI Binding_Abort(IBinding* iface) -{ - Binding *This = (Binding*)iface; - - FIXME("(%p): stub\n", This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI Binding_GetBindResult(IBinding* iface, CLSID* pclsidProtocol, DWORD* pdwResult, LPOLESTR* pszResult, DWORD* pdwReserved) -{ - Binding *This = (Binding*)iface; - - FIXME("(%p)->(%p, %p, %p, %p): stub\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved); - - return E_NOTIMPL; -} - -static HRESULT WINAPI Binding_GetPriority(IBinding* iface, LONG* pnPriority) -{ - Binding *This = (Binding*)iface; - - FIXME("(%p)->(%p): stub\n", This, pnPriority); - - return E_NOTIMPL; -} - -static HRESULT WINAPI Binding_Resume(IBinding* iface) -{ - Binding *This = (Binding*)iface; - - FIXME("(%p): stub\n", This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI Binding_SetPriority(IBinding* iface, LONG nPriority) -{ - Binding *This = (Binding*)iface; - - FIXME("(%p)->(%d): stub\n", This, nPriority); - - return E_NOTIMPL; -} - -static HRESULT WINAPI Binding_Suspend(IBinding* iface) -{ - Binding *This = (Binding*)iface; - - FIXME("(%p): stub\n", This); - - return E_NOTIMPL; -} - -static void Binding_CloseCacheDownload(Binding *This) -{ - CloseHandle(This->hCacheFile); - This->hCacheFile = 0; - UMCloseCacheFileStream(This->pstrCache); - IStream_Release((IStream *)This->pstrCache); - This->pstrCache = 0; -} - -static HRESULT Binding_MoreCacheData(Binding *This, const char *buf, DWORD dwBytes) -{ - DWORD written; - - if (WriteFile(This->hCacheFile, buf, dwBytes, &written, NULL) && written == dwBytes) - { - HRESULT hr; - - This->total_read += written; - hr = IBindStatusCallback_OnProgress(This->pbscb, - This->total_read + written, - This->expected_size, - (This->total_read == written) ? - BINDSTATUS_BEGINDOWNLOADDATA : - BINDSTATUS_DOWNLOADINGDATA, - This->URLName); - if (hr == S_OK) - { - STGMEDIUM stg; - FORMATETC fmt; - - fmt.cfFormat = 0; - fmt.ptd = NULL; - fmt.dwAspect = 0; - fmt.lindex = -1; - fmt.tymed = TYMED_ISTREAM; - - stg.tymed = TYMED_ISTREAM; - stg.u.pstm = (IStream *)This->pstrCache; - stg.pUnkForRelease = NULL; - - hr = IBindStatusCallback_OnDataAvailable(This->pbscb, - (This->total_read == written) ? - BSCF_FIRSTDATANOTIFICATION : - BSCF_INTERMEDIATEDATANOTIFICATION, - This->total_read + written, - &fmt, - &stg); - } - if (written < dwBytes) - return STG_E_MEDIUMFULL; - else - return hr; - } - return HRESULT_FROM_WIN32(GetLastError()); -} - -static void Binding_FinishedDownload(Binding *This, HRESULT hr) -{ - STGMEDIUM stg; - FORMATETC fmt; - - fmt.ptd = NULL; - fmt.dwAspect = 0; - fmt.lindex = -1; - fmt.tymed = TYMED_ISTREAM; - - stg.tymed = TYMED_ISTREAM; - stg.u.pstm = (IStream *)This->pstrCache; - stg.pUnkForRelease = NULL; - - IBindStatusCallback_OnProgress(This->pbscb, This->total_read, This->expected_size, - BINDSTATUS_ENDDOWNLOADDATA, This->URLName); - IBindStatusCallback_OnDataAvailable(This->pbscb, BSCF_LASTDATANOTIFICATION, This->total_read, &fmt, &stg); - if (hr != S_OK) - { - WCHAR *pwchError = 0; - - FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, (DWORD) hr, - 0, (LPWSTR) &pwchError, - 0, NULL); - if (!pwchError) - { - static const WCHAR achFormat[] = { '%', '0', '8', 'x', 0 }; - - pwchError =(WCHAR *) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * 9); - wsprintfW(pwchError, achFormat, hr); - } - IBindStatusCallback_OnStopBinding(This->pbscb, hr, pwchError); - LocalFree(pwchError); - } - else - { - IBindStatusCallback_OnStopBinding(This->pbscb, hr, NULL); - } - IBindStatusCallback_Release(This->pbscb); - This->pbscb = 0; -} - -static const IBindingVtbl BindingVtbl = -{ - Binding_QueryInterface, - Binding_AddRef, - Binding_Release, - Binding_Abort, - Binding_Suspend, - Binding_Resume, - Binding_SetPriority, - Binding_GetPriority, - Binding_GetBindResult -}; - -/* filemoniker data structure */ typedef struct { const IMonikerVtbl* lpvtbl; /* VTable relative to the IMoniker interface.*/ @@ -493,195 +248,6 @@ static HRESULT WINAPI URLMonikerImpl_BindToObject(IMoniker* iface, /****************************************************************************** * URLMoniker_BindToStorage ******************************************************************************/ -static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, IBindCtx* pbc, VOID** ppvObject) -{ - HRESULT hres; - BINDINFO bi; - DWORD bindf; - WCHAR szFileName[MAX_PATH + 1]; - Binding *bind; - int len; - - WARN("(%s %p %p)\n", debugstr_w(URLName), pbc, ppvObject); - - bind = heap_alloc_zero(sizeof(Binding)); - bind->lpVtbl = &BindingVtbl; - bind->ref = 1; - URLMON_LockModule(); - - len = lstrlenW(URLName)+1; - bind->URLName = heap_alloc(len*sizeof(WCHAR)); - memcpy(bind->URLName, URLName, len*sizeof(WCHAR)); - - hres = UMCreateStreamOnCacheFile(bind->URLName, 0, szFileName, &bind->hCacheFile, &bind->pstrCache); - - if(SUCCEEDED(hres)) { - TRACE("Created stream...\n"); - - *ppvObject = (void *) bind->pstrCache; - IStream_AddRef((IStream *) bind->pstrCache); - - hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown**)&bind->pbscb); - if(SUCCEEDED(hres)) { - TRACE("Got IBindStatusCallback...\n"); - - memset(&bi, 0, sizeof(bi)); - bi.cbSize = sizeof(bi); - bindf = 0; - hres = IBindStatusCallback_GetBindInfo(bind->pbscb, &bindf, &bi); - if(SUCCEEDED(hres)) { - URL_COMPONENTSW url; - WCHAR *host, *path, *user, *pass; - DWORD dwService = 0; - BOOL bSuccess; - - TRACE("got bindinfo. bindf = %08x extrainfo = %s bindinfof = %08x bindverb = %08x iid %s\n", - bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb, debugstr_guid(&bi.iid)); - hres = IBindStatusCallback_OnStartBinding(bind->pbscb, 0, (IBinding*)bind); - TRACE("OnStartBinding rets %08x\n", hres); - - bind->expected_size = 0; - bind->total_read = 0; - - memset(&url, 0, sizeof(url)); - url.dwStructSize = sizeof(url); - url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1; - InternetCrackUrlW(URLName, 0, ICU_ESCAPE, &url); - host = heap_alloc((url.dwHostNameLength + 1) * sizeof(WCHAR)); - memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR)); - host[url.dwHostNameLength] = '\0'; - path = heap_alloc((url.dwUrlPathLength + 1) * sizeof(WCHAR)); - memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR)); - path[url.dwUrlPathLength] = '\0'; - if (url.dwUserNameLength) - { - user = heap_alloc(((url.dwUserNameLength + 1) * sizeof(WCHAR))); - memcpy(user, url.lpszUserName, url.dwUserNameLength * sizeof(WCHAR)); - user[url.dwUserNameLength] = 0; - } - else - { - user = 0; - } - if (url.dwPasswordLength) - { - pass = heap_alloc(((url.dwPasswordLength + 1) * sizeof(WCHAR))); - memcpy(pass, url.lpszPassword, url.dwPasswordLength * sizeof(WCHAR)); - pass[url.dwPasswordLength] = 0; - } - else - { - pass = 0; - } - - - do { - bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0); - if (!bind->hinternet) - { - hres = HRESULT_FROM_WIN32(GetLastError()); - break; - } - - switch ((DWORD) url.nScheme) - { - case INTERNET_SCHEME_FTP: - if (!url.nPort) - url.nPort = INTERNET_DEFAULT_FTP_PORT; - dwService = INTERNET_SERVICE_FTP; - break; - - case INTERNET_SCHEME_GOPHER: - if (!url.nPort) - url.nPort = INTERNET_DEFAULT_GOPHER_PORT; - dwService = INTERNET_SERVICE_GOPHER; - break; - } - - bind->hconnect = InternetConnectW(bind->hinternet, host, url.nPort, user, pass, - dwService, 0, (DWORD_PTR)bind); - if (!bind->hconnect) - { - hres = HRESULT_FROM_WIN32(GetLastError()); - CloseHandle(bind->hinternet); - break; - } - - hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, 0x22, NULL); - hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL); - hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CONNECTING, NULL); - hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL); - - bSuccess = FALSE; - - switch (dwService) - { - case INTERNET_SERVICE_GOPHER: - bind->hrequest = GopherOpenFileW(bind->hconnect, - path, - 0, - INTERNET_FLAG_RELOAD, - 0); - if (bind->hrequest) - bSuccess = TRUE; - else - hres = HRESULT_FROM_WIN32(GetLastError()); - break; - - case INTERNET_SERVICE_FTP: - bind->hrequest = FtpOpenFileW(bind->hconnect, - path, - GENERIC_READ, - FTP_TRANSFER_TYPE_BINARY | - INTERNET_FLAG_TRANSFER_BINARY | - INTERNET_FLAG_RELOAD, - 0); - if (bind->hrequest) - bSuccess = TRUE; - else - hres = HRESULT_FROM_WIN32(GetLastError()); - break; - } - if(bSuccess) - { - TRACE("res = %d gle = %u url len = %d\n", hres, GetLastError(), bind->expected_size); - - IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName); - - while(1) { - char buf[4096]; - DWORD bufread; - if(InternetReadFile(bind->hrequest, buf, sizeof(buf), &bufread)) { - TRACE("read %d bytes %s...\n", bufread, debugstr_an(buf, 10)); - if(bufread == 0) break; - hres = Binding_MoreCacheData(bind, buf, bufread); - } else - break; - } - InternetCloseHandle(bind->hrequest); - hres = S_OK; - } - - InternetCloseHandle(bind->hconnect); - InternetCloseHandle(bind->hinternet); - } while(0); - - Binding_FinishedDownload(bind, hres); - Binding_CloseCacheDownload(bind); - - heap_free(user); - heap_free(pass); - heap_free(path); - heap_free(host); - } - } - } - - IBinding_Release((IBinding*)bind); - - return hres; -} - static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, @@ -689,28 +255,12 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface, VOID** ppvObject) { URLMonikerImpl *This = (URLMonikerImpl*)iface; - WCHAR schema[64]; - BOOL bret; - URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW), schema, - sizeof(schema)/sizeof(WCHAR), 0, NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; + TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject); if(pmkToLeft) FIXME("Unsupported pmkToLeft\n"); - bret = InternetCrackUrlW(This->URLName, 0, ICU_ESCAPE, &url); - if(!bret) { - ERR("InternetCrackUrl failed: %u\n", GetLastError()); - return E_FAIL; - } - - if(IsEqualGUID(&IID_IStream, riid) && - ( url.nScheme == INTERNET_SCHEME_FTP - || url.nScheme == INTERNET_SCHEME_GOPHER)) - return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, ppvObject); - - TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject); - return bind_to_storage(This->URLName, pbc, riid, ppvObject); } diff --git a/dlls/urlmon/umstream.c b/dlls/urlmon/umstream.c index 48cc769d266..5a942f612f6 100644 --- a/dlls/urlmon/umstream.c +++ b/dlls/urlmon/umstream.c @@ -30,342 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); -static const IStreamVtbl stvt; - -HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, - DWORD dwSize, - LPWSTR pszFileName, - HANDLE *phfile, - IUMCacheStream **ppstr) -{ - IUMCacheStream* ucstr; - HANDLE handle; - DWORD size; - LPWSTR url, c, ext = NULL; - HRESULT hr; - - size = (strlenW(pszURL)+1)*sizeof(WCHAR); - url = heap_alloc(size); - memcpy(url, pszURL, size); - - for (c = url; *c && *c != '#' && *c != '?'; ++c) - { - if (*c == '.') - ext = c+1; - else if(*c == '/') - ext = NULL; - } - - *c = 0; - - if(!CreateUrlCacheEntryW(url, dwSize, ext, pszFileName, 0)) - hr = HRESULT_FROM_WIN32(GetLastError()); - else - hr = S_OK; - - heap_free(url); - - if (hr != S_OK) - return hr; - - TRACE("Opening %s\n", debugstr_w(pszFileName) ); - - handle = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL ); - if( handle == INVALID_HANDLE_VALUE ) - return HRESULT_FROM_WIN32(GetLastError()); - - if (phfile) - { - /* Call CreateFileW again because we need a handle with its own file pointer, and DuplicateHandle will return - * a handle that shares its file pointer with the original. - */ - *phfile = CreateFileW( pszFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); - - if (*phfile == (HANDLE) HFILE_ERROR) - { - DWORD dwError = GetLastError(); - - CloseHandle(handle); - return HRESULT_FROM_WIN32(dwError); - } - } - - ucstr = heap_alloc_zero(sizeof(IUMCacheStream)); - if(ucstr) - { - ucstr->pszURL = heap_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszURL) + 1)); - if (ucstr->pszURL) - { - ucstr->pszFileName = heap_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszFileName) + 1)); - if (ucstr->pszFileName) - { - ucstr->lpVtbl=&stvt; - ucstr->ref = 1; - ucstr->handle = handle; - ucstr->closed = 0; - lstrcpyW(ucstr->pszURL, pszURL); - lstrcpyW(ucstr->pszFileName, pszFileName); - - *ppstr = ucstr; - - return S_OK; - } - heap_free(ucstr->pszURL); - } - heap_free(ucstr); - } - CloseHandle(handle); - if (phfile) - CloseHandle(*phfile); - return E_OUTOFMEMORY; -} - -void UMCloseCacheFileStream(IUMCacheStream *This) -{ - if (!This->closed) - { - FILETIME ftZero; - - ftZero.dwLowDateTime = ftZero.dwHighDateTime = 0; - - This->closed = 1; - CommitUrlCacheEntryW(This->pszURL, - This->pszFileName, - ftZero, - ftZero, - NORMAL_CACHE_ENTRY, - 0, - 0, - 0, - 0); - } -} - -/************************************************************************** -* IStream_fnQueryInterface -*/ -static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, - REFIID riid, - LPVOID *ppvObj) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IStream)) - { - *ppvObj = This; - } - - if(*ppvObj) - { - IStream_AddRef((IStream*)*ppvObj); - TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/************************************************************************** -* IStream_fnAddRef -*/ -static ULONG WINAPI IStream_fnAddRef(IStream *iface) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(count=%u)\n", This, refCount - 1); - - return refCount; -} - -/************************************************************************** -* IStream_fnRelease -*/ -static ULONG WINAPI IStream_fnRelease(IStream *iface) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(count=%u)\n", This, refCount + 1); - - if (!refCount) - { - TRACE(" destroying UMCacheStream (%p)\n",This); - UMCloseCacheFileStream(This); - CloseHandle(This->handle); - heap_free(This->pszFileName); - heap_free(This->pszURL); - heap_free(This); - } - return refCount; -} - -static HRESULT WINAPI IStream_fnRead (IStream * iface, - void* pv, - ULONG cb, - ULONG* pcbRead) -{ - ULONG dwBytesRead; - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)->(%p,0x%08x,%p)\n",This, pv, cb, pcbRead); - - if ( !pv ) - return STG_E_INVALIDPOINTER; - - if ( !pcbRead) - pcbRead = &dwBytesRead; - - if ( ! ReadFile( This->handle, pv, cb, pcbRead, NULL ) ) - return S_FALSE; - - if (!*pcbRead) - return This->closed ? S_FALSE : E_PENDING; - return S_OK; -} - -static HRESULT WINAPI IStream_fnWrite (IStream * iface, - const void* pv, - ULONG cb, - ULONG* pcbWritten) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI IStream_fnSeek (IStream * iface, - LARGE_INTEGER dlibMove, - DWORD dwOrigin, - ULARGE_INTEGER* plibNewPosition) -{ - LARGE_INTEGER newpos; - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - if (!SetFilePointerEx( This->handle, dlibMove, &newpos, dwOrigin )) - return E_FAIL; - - if (plibNewPosition) - plibNewPosition->QuadPart = newpos.QuadPart; - - return S_OK; -} - -static HRESULT WINAPI IStream_fnSetSize (IStream * iface, - ULARGE_INTEGER libNewSize) -{ - LARGE_INTEGER newpos; - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - newpos.QuadPart = libNewSize.QuadPart; - if( ! SetFilePointerEx( This->handle, newpos, NULL, FILE_BEGIN ) ) - return E_FAIL; - - if( ! SetEndOfFile( This->handle ) ) - return E_FAIL; - - return S_OK; -} - -static HRESULT WINAPI IStream_fnCopyTo (IStream * iface, - IStream* pstm, - ULARGE_INTEGER cb, - ULARGE_INTEGER* pcbRead, - ULARGE_INTEGER* pcbWritten) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI IStream_fnCommit (IStream * iface, - DWORD grfCommitFlags) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI IStream_fnRevert (IStream * iface) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnLockRegion (IStream * iface, - ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, - DWORD dwLockType) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface, - ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, - DWORD dwLockType) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnStat (IStream * iface, - STATSTG* pstatstg, - DWORD grfStatFlag) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnClone (IStream * iface, - IStream** ppstm) -{ - IUMCacheStream *This = (IUMCacheStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} - -static const IStreamVtbl stvt = -{ - IStream_fnQueryInterface, - IStream_fnAddRef, - IStream_fnRelease, - IStream_fnRead, - IStream_fnWrite, - IStream_fnSeek, - IStream_fnSetSize, - IStream_fnCopyTo, - IStream_fnCommit, - IStream_fnRevert, - IStream_fnLockRegion, - IStream_fnUnlockRegion, - IStream_fnStat, - IStream_fnClone - -}; - typedef struct ProxyBindStatusCallback { const IBindStatusCallbackVtbl *lpVtbl; diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c index bbf58c7719b..159b57dbcb3 100644 --- a/dlls/urlmon/urlmon_main.c +++ b/dlls/urlmon/urlmon_main.c @@ -173,6 +173,8 @@ static const ClassFactory FileProtocolCF = { &ClassFactoryVtbl, FileProtocol_Construct}; static const ClassFactory FtpProtocolCF = { &ClassFactoryVtbl, FtpProtocol_Construct}; +static const ClassFactory GopherProtocolCF = + { &ClassFactoryVtbl, GopherProtocol_Construct}; static const ClassFactory HttpProtocolCF = { &ClassFactoryVtbl, HttpProtocol_Construct}; static const ClassFactory HttpSProtocolCF = @@ -193,6 +195,7 @@ struct object_creation_info static const WCHAR wszFile[] = {'f','i','l','e',0}; static const WCHAR wszFtp[] = {'f','t','p',0}; +static const WCHAR wszGopher[] = {'g','o','p','h','e','r',0}; static const WCHAR wszHttp[] = {'h','t','t','p',0}; static const WCHAR wszHttps[] = {'h','t','t','p','s',0}; static const WCHAR wszMk[] = {'m','k',0}; @@ -201,6 +204,7 @@ static const struct object_creation_info object_creation[] = { { &CLSID_FileProtocol, CLASSFACTORY(&FileProtocolCF), wszFile }, { &CLSID_FtpProtocol, CLASSFACTORY(&FtpProtocolCF), wszFtp }, + { &CLSID_GopherProtocol, CLASSFACTORY(&GopherProtocolCF), wszGopher }, { &CLSID_HttpProtocol, CLASSFACTORY(&HttpProtocolCF), wszHttp }, { &CLSID_HttpSProtocol, CLASSFACTORY(&HttpSProtocolCF), wszHttps }, { &CLSID_MkProtocol, CLASSFACTORY(&MkProtocolCF), wszMk }, diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 10776f9193a..c5faa6116bb 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -42,6 +42,7 @@ extern HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); +extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); /********************************************************************** @@ -55,19 +56,6 @@ static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_ref #define DEFINE_THIS2(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,ifc))) #define DEFINE_THIS(cls,ifc,iface) DEFINE_THIS2(cls,lp ## ifc ## Vtbl,iface) -typedef struct -{ - const IStreamVtbl *lpVtbl; - LONG ref; - HANDLE handle; - BOOL closed; - WCHAR *pszFileName; - WCHAR *pszURL; -} IUMCacheStream; - -HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, DWORD dwSize, LPWSTR pszFileName, HANDLE *phfile, IUMCacheStream **ppstr); -void UMCloseCacheFileStream(IUMCacheStream *pstr); - IInternetProtocolInfo *get_protocol_info(LPCWSTR url); HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret); BOOL is_registered_protocol(LPCWSTR); diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index 28d6fbdf7c0..da8cb8ccc0e 100644 --- a/dlls/user32/Makefile.in +++ b/dlls/user32/Makefile.in @@ -10,9 +10,6 @@ DELAYIMPORTS = imm32 SPEC_SRCS16 = \ ddeml.spec \ - display.drv.spec \ - keyboard.drv.spec \ - mouse.drv.spec \ user.exe.spec C_SRCS = \ @@ -68,10 +65,7 @@ C_SRCS = \ C_SRCS16 = \ bidi16.c \ comm16.c \ - display.c \ hook16.c \ - kbd16.c \ - mouse16.c \ network.c \ user16.c \ wnd16.c @@ -81,8 +75,6 @@ RC_SRCS = resources/user32.rc SVG_SRCS = resources/oic_winlogo.svg RC_SRCS16 = \ - resources/display.rc \ - resources/mouse.rc \ resources/version16.rc EXTRASUBDIRS = resources @@ -94,18 +86,6 @@ EXTRASUBDIRS = resources user.exe.spec.o: user.exe.spec resources/version16.res $(WINEBUILD) $(WINEBUILDFLAGS) --dll -o $@ --heap 65520 --main-module $(MODULE) --res resources/version16.res --export $(SRCDIR)/user.exe.spec -display.drv.spec.o: display.drv.spec resources/display.res - $(WINEBUILD) $(WINEBUILDFLAGS) --dll -o $@ --main-module $(MODULE) --res resources/display.res --export $(SRCDIR)/display.drv.spec - -mouse.drv.spec.o: mouse.drv.spec resources/mouse.res - $(WINEBUILD) $(WINEBUILDFLAGS) --dll -o $@ --main-module $(MODULE) --res resources/mouse.res --export $(SRCDIR)/mouse.drv.spec - -resources/display.res: resources/display.rc - $(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/resources/display.rc - -resources/mouse.res: resources/mouse.rc - $(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/resources/mouse.rc - resources/version16.res: resources/version16.rc $(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/resources/version16.rc diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index ee9fb3f4e19..eadcc3d81a3 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -3902,7 +3902,7 @@ static void EDIT_WM_SetFocus(EDITSTATE *es) ReleaseDC(es->hwndSelf, hdc); } - CreateCaret(es->hwndSelf, 0, 2, es->line_height); + CreateCaret(es->hwndSelf, 0, 1, es->line_height); EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); ShowCaret(es->hwndSelf); @@ -3952,7 +3952,7 @@ static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw) EDIT_UpdateText(es, NULL, TRUE); if (es->flags & EF_FOCUSED) { DestroyCaret(); - CreateCaret(es->hwndSelf, 0, 2, es->line_height); + CreateCaret(es->hwndSelf, 0, 1, es->line_height); EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); ShowCaret(es->hwndSelf); diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 8bcd2353d08..fc6f981b927 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -1981,7 +1981,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, { MENUITEM *ip = &lppop->items[lppop->FocusedItem]; SendMessageW( hwndOwner, WM_MENUSELECT, - MAKELONG(ip->fType & MF_POPUP ? wIndex: ip->wID, + MAKEWPARAM(ip->fType & MF_POPUP ? wIndex: ip->wID, ip->fType | ip->fState | (lppop->wFlags & MF_SYSMENU)), (LPARAM)hmenu); } @@ -1992,7 +1992,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, if((pos=MENU_FindSubMenu(&topmenu, hmenu))!=NO_SELECTED_ITEM){ POPUPMENU *ptm = MENU_GetMenu( topmenu ); MENUITEM *ip = &ptm->items[pos]; - SendMessageW( hwndOwner, WM_MENUSELECT, MAKELONG(pos, + SendMessageW( hwndOwner, WM_MENUSELECT, MAKEWPARAM(pos, ip->fType | ip->fState | (ptm->wFlags & MF_SYSMENU)), (LPARAM)topmenu); } @@ -2386,7 +2386,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */ if (!(wFlags & TPM_NONOTIFY)) SendMessageW( hwndOwner, WM_INITMENUPOPUP, (WPARAM)item->hSubMenu, - MAKELONG( menu->FocusedItem, IS_SYSTEM_MENU(menu) )); + MAKELPARAM( menu->FocusedItem, IS_SYSTEM_MENU(menu) )); item = &menu->items[menu->FocusedItem]; rect = item->rect; @@ -3307,7 +3307,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, MAKELPARAM(0, IS_SYSTEM_MENU(menu)) ); } MENU_SelectItem( mt.hOwnerWnd, mt.hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); - SendMessageW( mt.hOwnerWnd, WM_MENUSELECT, MAKELONG(0,0xffff), 0 ); + SendMessageW( mt.hOwnerWnd, WM_MENUSELECT, MAKEWPARAM(0,0xffff), 0 ); } /* Reset the variable for hiding menu */ @@ -3447,21 +3447,26 @@ track_menu: MENU_ExitTracking( hwnd ); } - /********************************************************************** - * TrackPopupMenu (USER32.@) - * - * Like the win32 API, the function return the command ID only if the - * flag TPM_RETURNCMD is on. - * + * TrackPopupMenuEx (USER32.@) */ -BOOL WINAPI TrackPopupMenu( HMENU hMenu, UINT wFlags, INT x, INT y, - INT nReserved, HWND hWnd, const RECT *lpRect ) +BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y, + HWND hWnd, LPTPMPARAMS lpTpm ) { BOOL ret = FALSE; - TRACE("hmenu %p flags %04x (%d,%d) reserved %d hwnd %p rect %s\n", - hMenu, wFlags, x, y, nReserved, hWnd, wine_dbgstr_rect(lpRect)); + TRACE("hmenu %p flags %04x (%d,%d) hwnd %p lpTpm %p rect %s\n", + hMenu, wFlags, x, y, hWnd, lpTpm, + lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" ); + + /* Parameter check */ + /* FIXME: this check is performed several times, here and in the called + functions. That could be optimized */ + if (!MENU_GetMenu( hMenu )) + { + SetLastError( ERROR_INVALID_MENU_HANDLE ); + return FALSE; + } MENU_InitTracking(hWnd, hMenu, TRUE, wFlags); @@ -3470,21 +3475,24 @@ BOOL WINAPI TrackPopupMenu( HMENU hMenu, UINT wFlags, INT x, INT y, SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0); if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 )) - ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, lpRect ); + ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, + lpTpm ? &lpTpm->rcExclude : NULL ); MENU_ExitTracking(hWnd); return ret; } /********************************************************************** - * TrackPopupMenuEx (USER32.@) + * TrackPopupMenu (USER32.@) + * + * Like the win32 API, the function return the command ID only if the + * flag TPM_RETURNCMD is on. + * */ -BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y, - HWND hWnd, LPTPMPARAMS lpTpm ) +BOOL WINAPI TrackPopupMenu( HMENU hMenu, UINT wFlags, INT x, INT y, + INT nReserved, HWND hWnd, const RECT *lpRect ) { - FIXME("not fully implemented\n" ); - return TrackPopupMenu( hMenu, wFlags, x, y, 0, hWnd, - lpTpm ? &lpTpm->rcExclude : NULL ); + return TrackPopupMenuEx( hMenu, wFlags, x, y, hWnd, NULL); } /*********************************************************************** diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index b243e27173c..93f85f2bb87 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -2069,6 +2069,9 @@ BOOL WINAPI EnableScrollBar( HWND hwnd, UINT nBar, UINT flags ) if (bFineWithMe && infoPtr->flags == flags) return FALSE; infoPtr->flags = flags; + if (nBar == SB_CTL && (flags == ESB_DISABLE_BOTH || flags == ESB_ENABLE_BOTH)) + EnableWindow(hwnd, flags == ESB_ENABLE_BOTH); + SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE ); return TRUE; } diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c index 921aade0c65..06fa35018fa 100644 --- a/dlls/user32/tests/menu.c +++ b/dlls/user32/tests/menu.c @@ -114,6 +114,7 @@ typedef struct /* globals to communicate between test and wndproc */ static BOOL bMenuVisible; +static BOOL got_input; static HMENU hMenus[4]; #define MOD_SIZE 10 @@ -139,12 +140,25 @@ static int MOD_odheight; static SIZE MODsizes[MOD_NRMENUS]= { {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}, {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}}; static int MOD_GotDrawItemMsg = FALSE; +static int gflag_initmenupopup, + gflag_entermenuloop, + gflag_initmenu; + /* wndproc used by test_menu_ownerdraw() */ static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) { + case WM_INITMENUPOPUP: + gflag_initmenupopup++; + break; + case WM_ENTERMENULOOP: + gflag_entermenuloop++; + break; + case WM_INITMENU: + gflag_initmenu++; + break; case WM_MEASUREITEM: { MEASUREITEMSTRUCT* pmis = (MEASUREITEMSTRUCT*)lparam; @@ -211,7 +225,8 @@ static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg, } case WM_ENTERIDLE: { - ok( lparam, "Menu window handle is NULL!\n"); + ok( lparam || broken(!lparam), /* win9x, nt4 */ + "Menu window handle is NULL!\n"); PostMessage(hwnd, WM_CANCELMODE, 0, 0); return TRUE; } @@ -263,7 +278,7 @@ static void test_menu_locked_by_window(void) ok(ret, "DrawMenuBar failed with error %d\n", GetLastError()); } ret = IsMenu(GetMenu(hwnd)); - ok(!ret, "Menu handle should have been destroyed\n"); + ok(!ret || broken(ret) /* nt4 */, "Menu handle should have been destroyed\n"); SendMessage(hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0); /* did we process the WM_INITMENU message? */ @@ -1748,23 +1763,23 @@ static struct menu_mouse_tests_s { BOOL _todo_wine; } menu_tests[] = { /* for each test, send keys or clicks and check for menu visibility */ - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 0}, TRUE, FALSE }, /* test 0 */ + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 0}, TRUE, FALSE }, /* test 0 */ { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, VK_ESCAPE, 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', VK_ESCAPE, 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', VK_ESCAPE, 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 'P', 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 'P', 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE }, - { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 'P', 0}, TRUE, FALSE }, + { INPUT_KEYBOARD, {{0}}, {VK_MENU, 'M', 'P', 0}, TRUE, FALSE }, { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE }, { INPUT_MOUSE, {{1, 2}, {0}}, {0}, TRUE, TRUE }, /* test 18 */ @@ -1791,7 +1806,7 @@ static void send_key(WORD wVk) pSendInput(2, (INPUT *) i, sizeof(INPUT)); } -static void click_menu(HANDLE hWnd, struct menu_item_pair_s *mi) +static BOOL click_menu(HANDLE hWnd, struct menu_item_pair_s *mi) { HMENU hMenu = hMenus[mi->uMenu]; TEST_INPUT i[3]; @@ -1800,7 +1815,7 @@ static void click_menu(HANDLE hWnd, struct menu_item_pair_s *mi) int screen_w = GetSystemMetrics(SM_CXSCREEN); int screen_h = GetSystemMetrics(SM_CYSCREEN); BOOL ret = GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r); - if(!ret) return; + if(!ret) return FALSE; memset(i, 0, sizeof(i)); i[0].type = i[1].type = i[2].type = INPUT_MOUSE; @@ -1813,10 +1828,11 @@ static void click_menu(HANDLE hWnd, struct menu_item_pair_s *mi) i[0].u.mi.dwFlags |= MOUSEEVENTF_MOVE; i[1].u.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN; i[2].u.mi.dwFlags |= MOUSEEVENTF_LEFTUP; - pSendInput(3, (INPUT *) i, sizeof(INPUT)); + ret = pSendInput(3, (INPUT *) i, sizeof(INPUT)); /* hack to prevent mouse message buildup in Wine */ while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg ); + return ret; } static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter) @@ -1828,15 +1844,23 @@ static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter) /* mixed keyboard/mouse test */ for (i = 0; menu_tests[i].type != -1; i++) { - int elapsed = 0; + int ret = TRUE, elapsed = 0; + + got_input = i && menu_tests[i-1].bMenuVisible; if (menu_tests[i].type == INPUT_KEYBOARD) for (j = 0; menu_tests[i].wVk[j] != 0; j++) send_key(menu_tests[i].wVk[j]); else for (j = 0; menu_tests[i].menu_item_pairs[j].uMenu != 0; j++) - click_menu(hWnd, &menu_tests[i].menu_item_pairs[j]); + if (!(ret = click_menu(hWnd, &menu_tests[i].menu_item_pairs[j]))) break; + if (!ret) + { + skip( "test %u: failed to send input\n", i ); + PostMessage( hWnd, WM_CANCELMODE, 0, 0 ); + return 0; + } while (menu_tests[i].bMenuVisible != bMenuVisible) { if (elapsed > 200) @@ -1845,6 +1869,13 @@ static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter) Sleep(20); } + if (!got_input) + { + skip( "test %u: didn't receive input\n", i ); + PostMessage( hWnd, WM_CANCELMODE, 0, 0 ); + return 0; + } + if (menu_tests[i]._todo_wine) { todo_wine { @@ -1867,6 +1898,16 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, case WM_EXITMENULOOP: bMenuVisible = FALSE; break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_NCMOUSEMOVE: + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + got_input = TRUE; + /* fall through */ default: return( DefWindowProcA( hWnd, msg, wParam, lParam ) ); } @@ -2600,6 +2641,113 @@ static void test_menu_setmenuinfo(void) return; } +/* little func to easy switch either TrackPopupMenu() or TrackPopupMenuEx() */ +static DWORD MyTrackPopupMenu( int ex, HMENU hmenu, UINT flags, INT x, INT y, HWND hwnd, LPTPMPARAMS ptpm) +{ + return ex + ? TrackPopupMenuEx( hmenu, flags, x, y, hwnd, ptpm) + : TrackPopupMenu( hmenu, flags, x, y, 0, hwnd, NULL); +} + +/* some TrackPopupMenu and TrackPopupMenuEx tests */ +/* the LastError values differ between NO_ERROR and invalid handle */ +/* between all windows versions tested. The first value is that valid on XP */ +/* Vista was the only that made returned different error values */ +/* between the TrackPopupMenu and TrackPopupMenuEx functions */ +static void test_menu_trackpopupmenu(void) +{ + BOOL ret; + HMENU hmenu; + DWORD gle; + int Ex; + HWND hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL, + WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, + NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError()); + if (!hwnd) return; + SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)menu_ownerdraw_wnd_proc); + for( Ex = 0; Ex < 2; Ex++) + { + hmenu = CreatePopupMenu(); + ok(hmenu != NULL, "CreateMenu failed with error %d\n", GetLastError()); + if (!hmenu) + { + DestroyWindow(hwnd); + return; + } + /* display the menu */ + /* start with an invalid menu handle */ + gle = 0xdeadbeef; + gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0; + ret = MyTrackPopupMenu( Ex, NULL, 0x100, 100,100, hwnd, NULL); + gle = GetLastError(); + ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : ""); + ok( gle == ERROR_INVALID_MENU_HANDLE + || broken (gle == 0xdeadbeef) /* win95 */ + || broken (gle == NO_ERROR) /* win98/ME */ + ,"TrackPopupMenu%s error got %u expected %u\n", + Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE); + ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu), + "got unexpected message(s)%s%s%s\n", + gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ", + gflag_entermenuloop ? "WM_INITMENULOOP ": "", + gflag_initmenu ? "WM_INITMENU": ""); + /* another one but not NULL */ + gle = 0xdeadbeef; + gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0; + ret = MyTrackPopupMenu( Ex, (HMENU)hwnd, 0x100, 100,100, hwnd, NULL); + gle = GetLastError(); + ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : ""); + ok( gle == ERROR_INVALID_MENU_HANDLE + || broken (gle == 0xdeadbeef) /* win95 */ + || broken (gle == NO_ERROR) /* win98/ME */ + ,"TrackPopupMenu%s error got %u expected %u\n", + Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE); + ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu), + "got unexpected message(s)%s%s%s\n", + gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ", + gflag_entermenuloop ? "WM_INITMENULOOP ": "", + gflag_initmenu ? "WM_INITMENU": ""); + /* now a somewhat successfull call */ + gle = 0xdeadbeef; + gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0; + ret = MyTrackPopupMenu( Ex, hmenu, 0x100, 100,100, hwnd, NULL); + gle = GetLastError(); + ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret); + ok( gle == NO_ERROR + || gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k */ + || broken (gle == 0xdeadbeef) /* win95 */ + ,"TrackPopupMenu%s error got %u expected %u or %u\n", + Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE); + ok( gflag_initmenupopup && gflag_entermenuloop && gflag_initmenu, + "missed expected message(s)%s%s%s\n", + !gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ", + !gflag_entermenuloop ? "WM_INITMENULOOP ": "", + !gflag_initmenu ? "WM_INITMENU": ""); + /* and another */ + ret = AppendMenuA( hmenu, MF_STRING, 1, "winetest"); + ok( ret, "AppendMenA has failed!\n"); + gle = 0xdeadbeef; + gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0; + ret = MyTrackPopupMenu( Ex, hmenu, 0x100, 100,100, hwnd, NULL); + gle = GetLastError(); + ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret); + ok( gle == NO_ERROR + || gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k and Vista in the TrackPopupMenuEx case */ + || broken (gle == 0xdeadbeef) /* win95 */ + ,"TrackPopupMenu%s error got %u expected %u or %u\n", + Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE); + ok( gflag_initmenupopup && gflag_entermenuloop && gflag_initmenu, + "missed expected message(s)%s%s%s\n", + !gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ", + !gflag_entermenuloop ? "WM_INITMENULOOP ": "", + !gflag_initmenu ? "WM_INITMENU": ""); + DestroyMenu(hmenu); + } + /* clean up */ + DestroyWindow(hwnd); +} + START_TEST(menu) { init_function_pointers(); @@ -2635,4 +2783,5 @@ START_TEST(menu) test_menu_flags(); test_menu_hilitemenuitem(); + test_menu_trackpopupmenu(); } diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index d8bfd26b851..3a20cba8cd4 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -180,6 +180,7 @@ static const struct message WmSWP_ShowOverlappedSeq[] = { { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { WM_SYNCPAINT, sent|optional }, { WM_PAINT, sent|optional }, { WM_NCPAINT, sent|beginpaint|optional }, { WM_GETTEXT, sent|defwinproc|optional }, @@ -370,7 +371,7 @@ static const struct message WmSwitchNotMaximizedChild[] = { static const struct message WmSWP_FrameChanged_clip[] = { { WM_WINDOWPOSCHANGING, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED }, { WM_NCCALCSIZE, sent|wparam|parent, 1 }, - { WM_NCPAINT, sent|parent }, /* wparam != 1 */ + { WM_NCPAINT, sent|parent|optional }, /* wparam != 1 */ { WM_GETTEXT, sent|parent|defwinproc|optional }, { WM_ERASEBKGND, sent|parent|optional }, /* FIXME: remove optional once Wine is fixed */ { WM_NCPAINT, sent }, /* wparam != 1 */ @@ -389,12 +390,12 @@ static const struct message WmSWP_FrameChangedDeferErase[] = { { WM_NCCALCSIZE, sent|wparam|parent, 1 }, { WM_WINDOWPOSCHANGED, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, - { WM_PAINT, sent|parent }, - { WM_NCPAINT, sent|beginpaint|parent }, /* wparam != 1 */ + { WM_PAINT, sent|parent|optional }, + { WM_NCPAINT, sent|beginpaint|parent|optional }, /* wparam != 1 */ { WM_GETTEXT, sent|beginpaint|parent|defwinproc|optional }, { WM_PAINT, sent }, { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */ - { WM_ERASEBKGND, sent|beginpaint }, + { WM_ERASEBKGND, sent|beginpaint|optional }, { 0 } }; @@ -405,14 +406,14 @@ static const struct message WmSWP_FrameChangedDeferErase[] = { static const struct message WmSWP_FrameChanged_noclip[] = { { WM_WINDOWPOSCHANGING, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED }, { WM_NCCALCSIZE, sent|wparam|parent, 1 }, - { WM_NCPAINT, sent|parent }, /* wparam != 1 */ + { WM_NCPAINT, sent|parent|optional }, /* wparam != 1 */ { WM_GETTEXT, sent|parent|defwinproc|optional }, - { WM_ERASEBKGND, sent|parent|optional }, /* FIXME: remove optional once Wine is fixed */ + { WM_ERASEBKGND, sent|parent|optional }, { WM_WINDOWPOSCHANGED, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { WM_PAINT, sent }, { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */ - { WM_ERASEBKGND, sent|beginpaint }, + { WM_ERASEBKGND, sent|beginpaint|optional }, { 0 } }; @@ -449,6 +450,7 @@ static const struct message WmShowOverlappedSeq[] = { { WM_GETTEXT, sent|optional }, { WM_NCPAINT, sent|optional }, { WM_ERASEBKGND, sent|optional }, + { WM_SYNCPAINT, sent|optional }, #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE * messages. Does that mean that CreateWindow doesn't set initial * window dimensions for overlapped windows? @@ -495,6 +497,7 @@ static const struct message WmShowMaxOverlappedSeq[] = { { WM_ERASEBKGND, sent|optional }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { WM_SYNCPAINT, sent|optional }, { WM_PAINT, sent|optional }, { WM_NCPAINT, sent|beginpaint|optional }, { WM_ERASEBKGND, sent|beginpaint|optional }, @@ -1269,6 +1272,8 @@ static const struct message WmEndCustomDialogSeq[] = { { WM_ACTIVATE, sent|wparam, 0 }, { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_GETTEXT, sent|optional|defwinproc }, { HCBT_SETFOCUS, hook }, { WM_KILLFOCUS, sent }, { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, @@ -1346,7 +1351,7 @@ static const struct message WmModalDialogSeq[] = { { WM_CTLCOLORDLG, sent|optional }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { WM_PAINT, sent|optional }, - { WM_CTLCOLORBTN, sent }, + { WM_CTLCOLORBTN, sent|optional }, { WM_ENTERIDLE, sent|parent|optional }, { WM_ENTERIDLE, sent|parent|optional }, { WM_ENTERIDLE, sent|parent|optional }, @@ -1815,6 +1820,7 @@ static void add_message_(int line, const struct recvd_message *msg) msg->descr, msg->hwnd, dis->CtlType, dis->CtlID, dis->itemID, dis->itemAction, dis->itemState); + di.u.lp = 0; di.u.item.type = dis->CtlType; di.u.item.ctl_id = dis->CtlID; di.u.item.item_id = dis->itemID; @@ -1995,10 +2001,10 @@ static void ok_sequence_(const struct message *expected_list, const char *contex if ((expected->lParam ^ actual->lParam) & ~expected->lp_mask) dump++; } } - if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && - (expected->flags & optional)) + if ((expected->flags & optional) && + ((expected->flags ^ actual->flags) & (defwinproc|parent))) { - /* don't match messages if their defwinproc status differs */ + /* don't match optional messages if their defwinproc or parent status differs */ expected++; count++; continue; @@ -3665,7 +3671,7 @@ static void test_mdi_messages(void) */ active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); ok(active_child == mdi_child || /* win2k */ - !active_child, /* win9x */ + !active_child || active_child == mdi_child2, /* win9x */ "wrong active MDI child %p\n", active_child); flush_sequence(); @@ -4484,8 +4490,6 @@ static void test_messages(void) flush_events(); ok_sequence(WmOptionalPaint, "ShowWindow(SW_SHOW):overlapped already visible", FALSE); - ok(GetActiveWindow() == hwnd, "window should be active\n"); - ok(GetFocus() == hwnd, "window should have input focus\n"); SetWindowPos(hwnd, 0,0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE); ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped", FALSE); ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n"); @@ -5622,7 +5626,7 @@ static const struct message WmInvalidateErasePaint[] = { { WM_PAINT, sent }, { WM_NCPAINT, sent|wparam|beginpaint, 1 }, { WM_GETTEXT, sent|beginpaint|defwinproc|optional }, - { WM_ERASEBKGND, sent|beginpaint }, + { WM_ERASEBKGND, sent|beginpaint|optional }, { 0 } }; @@ -5693,7 +5697,7 @@ static const struct message WmChildPaintNc[] = { { WM_PAINT, sent }, { WM_NCPAINT, sent|beginpaint }, { WM_GETTEXT, sent|beginpaint|defwinproc|optional }, - { WM_ERASEBKGND, sent|beginpaint }, + { WM_ERASEBKGND, sent|beginpaint|optional }, { 0 } }; @@ -8201,6 +8205,14 @@ static const struct message ScrollWindowPaint1[] = { { WM_PAINT, sent }, { WM_ERASEBKGND, sent|beginpaint }, { WM_GETTEXTLENGTH, sent|optional }, + { WM_PAINT, sent|optional }, + { WM_NCPAINT, sent|beginpaint|optional }, + { WM_GETTEXT, sent|optional }, + { WM_GETTEXT, sent|optional }, + { WM_GETTEXT, sent|optional }, + { WM_GETTEXT, sent|optional }, + { WM_GETTEXT, sent|optional }, + { WM_ERASEBKGND, sent|optional }, { 0 } }; @@ -8968,6 +8980,7 @@ static void test_PeekMessage(void) ok(GetLastError() == ERROR_INVALID_FLAGS, "wrong error %d\n", GetLastError()); qstatus = GetQueueStatus(qs_all_input); } + qstatus &= ~MAKELONG( 0x4000, 0x4000 ); /* sometimes set on Win95 */ ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE), "wrong qstatus %08x\n", qstatus); @@ -9886,6 +9899,7 @@ static const struct message WmShowNoActivate_2[] = { { HCBT_SETFOCUS, hook|optional }, { HCBT_ACTIVATE, hook|optional }, /* win2003 doesn't send it */ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2003 doesn't send it */ + { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { HCBT_SETFOCUS, hook|optional }, /* win2003 doesn't send it */ { 0 } }; @@ -10427,13 +10441,20 @@ static const struct message SetActiveWindowSeq0[] = { WM_ACTIVATEAPP, sent|wparam|optional, 0 }, { WM_ACTIVATEAPP, sent|wparam|optional, 0 }, { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_KILLFOCUS, sent|optional }, { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE }, { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, { WM_NCACTIVATE, sent|wparam|optional, 1 }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ACTIVATE, sent|wparam|optional, 1 }, { HCBT_SETFOCUS, hook|optional }, - { WM_KILLFOCUS, sent|defwinproc }, + { WM_KILLFOCUS, sent|defwinproc|optional }, + { WM_IME_SETCONTEXT, sent|defwinproc|optional }, + { WM_IME_SETCONTEXT, sent|defwinproc|optional }, + { WM_IME_SETCONTEXT, sent|defwinproc|optional }, + { WM_IME_SETCONTEXT, sent|defwinproc|optional }, + { WM_IME_SETCONTEXT, sent|defwinproc|optional }, + { WM_IME_SETCONTEXT, sent|defwinproc|optional }, { WM_IME_SETCONTEXT, sent|defwinproc|optional }, { WM_IME_SETCONTEXT, sent|defwinproc|optional }, { WM_IME_SETCONTEXT, sent|defwinproc|optional }, @@ -10541,7 +10562,7 @@ static void test_SetActiveWindow(void) trace("SetActiveWindow(0)\n"); ret = SetActiveWindow(0); ok( ret == popup, "Failed to SetActiveWindow(0)\n"); - ok_sequence(SetActiveWindowSeq0, "SetActiveWindow(0)", TRUE); + ok_sequence(SetActiveWindowSeq0, "SetActiveWindow(0)", FALSE); flush_sequence(); trace("SetActiveWindow(hwnd), hwnd visible\n"); diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 9547d543082..46080cac8a5 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -54,15 +54,26 @@ static void scrollbar_test1(void) ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_BOTH ); ok( ret, "The scrollbar should be disabled.\n" ); - todo_wine - { - ok( !IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" ); - } + ok( !IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" ); ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH ); ok( ret, "The scrollbar should be enabled.\n" ); ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" ); + /* test buttons separately */ + ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_LTUP ); + ok( ret, "The scrollbar LTUP button should be disabled.\n" ); + ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" ); + ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH ); + ok( ret, "The scrollbar should be enabled.\n" ); + ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" ); + + ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_RTDN ); + ok( ret, "The scrollbar RTDN button should be disabled.\n" ); + ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" ); + ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH ); + ok( ret, "The scrollbar should be enabled.\n" ); + ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" ); } static void scrollbar_test2(void) diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index 1dba6829ac7..c8bb551f582 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -1099,184 +1099,6 @@ static void test_ScriptLayout(void) } } -static const struct -{ - LGRPID group; - LCID lcid; - SCRIPT_DIGITSUBSTITUTE sds; - DWORD uDefaultLanguage; - DWORD fContextDigits; - WORD fDigitSubstitute; -} -subst_data[] = -{ - { 0x01, 0x00403, { 9, 3, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00406, { 9, 6, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00407, { 9, 7, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00409, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0040a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0040b, { 9, 11, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0040c, { 9, 12, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0040f, { 9, 15, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00410, { 9, 16, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00413, { 9, 19, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00414, { 9, 20, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00416, { 9, 22, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0041d, { 9, 29, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00421, { 9, 33, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0042d, { 9, 45, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00432, { 9, 50, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00434, { 9, 52, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00435, { 9, 53, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00436, { 9, 54, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00438, { 9, 56, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0043a, { 9, 58, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0043b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0043e, { 9, 62, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00441, { 9, 65, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00452, { 9, 82, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00456, { 9, 86, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0046b, { 9, 107, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0046c, { 9, 108, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00481, { 9, 129, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00807, { 9, 7, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00809, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0080a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0080c, { 9, 12, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00810, { 9, 16, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00813, { 9, 19, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00814, { 9, 20, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00816, { 9, 22, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0081d, { 9, 29, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0083b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0083e, { 9, 62, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0086b, { 9, 107, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00c07, { 9, 7, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00c09, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00c0a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00c0c, { 9, 12, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00c3b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x00c6b, { 9, 107, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01007, { 9, 7, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01009, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0100a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0100c, { 9, 12, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0103b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01407, { 9, 7, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01409, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0140a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0140c, { 9, 12, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0143b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01809, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0180a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0180c, { 9, 12, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0183b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01c09, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01c0a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x01c3b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x02009, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0200a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0203b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x02409, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0240a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0243b, { 9, 59, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x02809, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0280a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x02c09, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x02c0a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x03009, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0300a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x03409, { 9, 9, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0340a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0380a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x03c0a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0400a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0440a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0480a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x04c0a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x0500a, { 9, 10, 1, 0 }, 9, 0, 0 }, - { 0x01, 0x10407, { 9, 7, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x00405, { 9, 5, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0040e, { 9, 14, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x00415, { 9, 21, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x00418, { 9, 24, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0041a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0041b, { 9, 27, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0041c, { 9, 28, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x00424, { 9, 36, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0081a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0101a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0141a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x0181a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x02, 0x1040e, { 9, 14, 1, 0 }, 9, 0, 0 }, - { 0x03, 0x00425, { 9, 37, 1, 0 }, 9, 0, 0 }, - { 0x03, 0x00426, { 9, 38, 1, 0 }, 9, 0, 0 }, - { 0x03, 0x00427, { 9, 39, 1, 0 }, 9, 0, 0 }, - { 0x04, 0x00408, { 9, 8, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00402, { 9, 2, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00419, { 9, 25, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00422, { 9, 34, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00423, { 9, 35, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x0042f, { 9, 47, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x0043f, { 9, 63, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00440, { 9, 64, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00444, { 9, 68, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00450, { 9, 80, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x0082c, { 9, 44, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00843, { 9, 67, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x00c1a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x05, 0x01c1a, { 9, 26, 1, 0 }, 9, 0, 0 }, - { 0x06, 0x0041f, { 9, 31, 1, 0 }, 9, 0, 0 }, - { 0x06, 0x0042c, { 9, 44, 1, 0 }, 9, 0, 0 }, - { 0x06, 0x00443, { 9, 67, 1, 0 }, 9, 0, 0 }, - { 0x07, 0x00411, { 9, 17, 1, 0 }, 9, 0, 0 }, - { 0x08, 0x00412, { 9, 18, 1, 0 }, 9, 0, 0 }, - { 0x09, 0x00404, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x09, 0x00c04, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x09, 0x01404, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x09, 0x21404, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x09, 0x30404, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x0a, 0x00804, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x0a, 0x01004, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x0a, 0x20804, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x0a, 0x21004, { 9, 4, 1, 0 }, 9, 0, 0 }, - { 0x0b, 0x0041e, { 9, 30, 1, 0 }, 9, 0, 0 }, - { 0x0c, 0x0040d, { 9, 13, 1, 0 }, 9, 0, 0 }, - { 0x0d, 0x00401, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x00420, { 9, 32, 1, 0 }, 9, 0, 0 }, - { 0x0d, 0x00429, { 41, 41, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x0045a, { 9, 90, 1, 0 }, 9, 0, 0 }, - { 0x0d, 0x00465, { 9, 101, 1, 0 }, 9, 0, 0 }, - { 0x0d, 0x00801, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x00c01, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x01001, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x01401, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x01801, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x01c01, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x02001, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x02401, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x02801, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x02c01, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x03001, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x03401, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x03801, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x03c01, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0d, 0x04001, { 1, 1, 0, 0 }, 9, 0, 0 }, - { 0x0e, 0x0042a, { 9, 42, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x00439, { 9, 57, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x00446, { 9, 70, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x00447, { 9, 71, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x00449, { 9, 73, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x0044a, { 9, 74, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x0044b, { 9, 75, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x0044e, { 9, 78, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x0044f, { 9, 79, 1, 0 }, 9, 0, 0 }, - { 0x0f, 0x00457, { 9, 87, 1, 0 }, 9, 0, 0 }, - { 0x10, 0x00437, { 9, 55, 1, 0 }, 9, 0, 0 }, - { 0x10, 0x10437, { 9, 55, 1, 0 }, 9, 0, 0 }, - { 0x11, 0x0042b, { 9, 43, 1, 0 }, 9, 0, 0 } -}; - static BOOL CALLBACK enum_proc(LGRPID group, LCID lcid, LPSTR locale, LONG_PTR lparam) { HRESULT hr; @@ -1284,7 +1106,6 @@ static BOOL CALLBACK enum_proc(LGRPID group, LCID lcid, LPSTR locale, LONG_PTR l SCRIPT_CONTROL sc; SCRIPT_STATE ss; LCID lcid_old; - unsigned int i; if (!IsValidLocale(lcid, LCID_INSTALLED)) return TRUE; @@ -1301,21 +1122,6 @@ static BOOL CALLBACK enum_proc(LGRPID group, LCID lcid, LPSTR locale, LONG_PTR l hr = ScriptApplyDigitSubstitution(&sds, &sc, &ss); ok(hr == S_OK, "ScriptApplyDigitSubstitution failed: 0x%08x\n", hr); - for (i = 0; i < sizeof(subst_data)/sizeof(subst_data[0]); i++) - { - if (group == subst_data[i].group && lcid == subst_data[i].lcid) - { - ok(!memcmp(&sds, &subst_data[i].sds, sizeof(sds)), - "substitution data does not match\n"); - - ok(sc.uDefaultLanguage == subst_data[i].uDefaultLanguage, - "sc.uDefaultLanguage does not match\n"); - ok(sc.fContextDigits == subst_data[i].fContextDigits, - "sc.fContextDigits does not match\n"); - ok(ss.fDigitSubstitute == subst_data[i].fDigitSubstitute, - "ss.fDigitSubstitute does not match\n"); - } - } SetThreadLocale(lcid_old); return TRUE; } diff --git a/dlls/win87em.dll16/Makefile.in b/dlls/win87em.dll16/Makefile.in new file mode 100644 index 00000000000..929361d2215 --- /dev/null +++ b/dlls/win87em.dll16/Makefile.in @@ -0,0 +1,15 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = win87em.dll16 +IMPORTS = kernel32 +EXTRADLLFLAGS = -Wb,--subsystem,win16 + +SPEC_SRCS = win87em.dll16.spec + +C_SRCS = win87em.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/kernel32/win87em.c b/dlls/win87em.dll16/win87em.c similarity index 90% rename from dlls/kernel32/win87em.c rename to dlls/win87em.dll16/win87em.c index 416d0553c49..35a04c4fcd4 100644 --- a/dlls/kernel32/win87em.c +++ b/dlls/win87em.dll16/win87em.c @@ -57,7 +57,7 @@ static WORD StackTop = 175; static WORD StackBottom = 0; static WORD Inthandler02hVar = 1; -static void WIN87_ClearCtrlWord( CONTEXT86 *context ) +static void WIN87_ClearCtrlWord( CONTEXT *context ) { context->Eax &= ~0xffff; /* set AX to 0 */ if (Installed) @@ -69,7 +69,7 @@ static void WIN87_ClearCtrlWord( CONTEXT86 *context ) StatusWord_3 = StatusWord_2 = 0; } -static void WIN87_SetCtrlWord( CONTEXT86 *context ) +static void WIN87_SetCtrlWord( CONTEXT *context ) { CtrlWord_1 = LOWORD(context->Eax); context->Eax &= ~0x00c3; @@ -82,7 +82,7 @@ static void WIN87_SetCtrlWord( CONTEXT86 *context ) CtrlWord_2 = LOWORD(context->Eax); } -static void WIN87_Init( CONTEXT86 *context ) +static void WIN87_Init( CONTEXT *context ) { if (Installed) { #ifdef __i386__ @@ -99,12 +99,11 @@ static void WIN87_Init( CONTEXT86 *context ) /*********************************************************************** * _fpMath (WIN87EM.1) */ -void WINAPI WIN87_fpmath( CONTEXT86 *context ) +void WINAPI _fpMath( CONTEXT *context ) { - TRACE("(cs:eip=%x:%x es=%x bx=%04x ax=%04x dx=%04x)\n", - (WORD)context->SegCs, context->Eip, - (WORD)context->SegEs, (WORD)context->Ebx, - (WORD)context->Eax, (WORD)context->Edx ); + TRACE("(cs:eip=%04x:%04x es=%04x bx=%04x ax=%04x dx=%04x)\n", + context->SegCs, context->Eip, context->SegEs, context->Ebx, + context->Eax, context->Edx ); switch(LOWORD(context->Ebx)) { @@ -224,8 +223,7 @@ void WINAPI WIN87_fpmath( CONTEXT86 *context ) /*********************************************************************** * __WinEm87Info (WIN87EM.3) */ -void WINAPI WIN87_WinEm87Info(struct Win87EmInfoStruct *pWIS, - int cbWin87EmInfoStruct) +void WINAPI __WinEm87Info(struct Win87EmInfoStruct *pWIS, int cbWin87EmInfoStruct) { FIXME("(%p,%d), stub !\n",pWIS,cbWin87EmInfoStruct); } @@ -233,8 +231,7 @@ void WINAPI WIN87_WinEm87Info(struct Win87EmInfoStruct *pWIS, /*********************************************************************** * __WinEm87Restore (WIN87EM.4) */ -void WINAPI WIN87_WinEm87Restore(void *pWin87EmSaveArea, - int cbWin87EmSaveArea) +void WINAPI __WinEm87Restore(void *pWin87EmSaveArea, int cbWin87EmSaveArea) { FIXME("(%p,%d), stub !\n", pWin87EmSaveArea,cbWin87EmSaveArea); @@ -243,7 +240,7 @@ void WINAPI WIN87_WinEm87Restore(void *pWin87EmSaveArea, /*********************************************************************** * __WinEm87Save (WIN87EM.5) */ -void WINAPI WIN87_WinEm87Save(void *pWin87EmSaveArea, int cbWin87EmSaveArea) +void WINAPI __WinEm87Save(void *pWin87EmSaveArea, int cbWin87EmSaveArea) { FIXME("(%p,%d), stub !\n", pWin87EmSaveArea,cbWin87EmSaveArea); diff --git a/dlls/win87em.dll16/win87em.dll16.spec b/dlls/win87em.dll16/win87em.dll16.spec new file mode 100644 index 00000000000..0b9024c2d22 --- /dev/null +++ b/dlls/win87em.dll16/win87em.dll16.spec @@ -0,0 +1,4 @@ +1 pascal -register _fpMath() _fpMath +3 pascal -ret16 __WinEm87Info(ptr word) __WinEm87Info +4 pascal -ret16 __WinEm87Restore(ptr word) __WinEm87Restore +5 pascal -ret16 __WinEm87Save(ptr word) __WinEm87Save diff --git a/dlls/windebug.dll16/Makefile.in b/dlls/windebug.dll16/Makefile.in new file mode 100644 index 00000000000..5615a2c02a5 --- /dev/null +++ b/dlls/windebug.dll16/Makefile.in @@ -0,0 +1,15 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = windebug.dll16 +IMPORTS = kernel32 +EXTRADLLFLAGS = -Wb,--subsystem,win16 + +SPEC_SRCS = windebug.dll16.spec + +C_SRCS = windebug.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/kernel32/windebug.c b/dlls/windebug.dll16/windebug.c similarity index 100% rename from dlls/kernel32/windebug.c rename to dlls/windebug.dll16/windebug.c diff --git a/dlls/kernel32/windebug.spec b/dlls/windebug.dll16/windebug.dll16.spec similarity index 100% rename from dlls/kernel32/windebug.spec rename to dlls/windebug.dll16/windebug.dll16.spec diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index b05b541d5a4..8d632946e26 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -212,7 +212,8 @@ static void shader_arb_load_constants( GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst[i].const_num, data)); deviceImpl->activeContext->pshader_const_dirty[psi->bumpenvmatconst[i].const_num] = 1; - if(psi->luminanceconst[i].const_num != -1) { + if (psi->luminanceconst[i].const_num != WINED3D_CONST_NUM_UNUSED) + { /* WINED3DTSS_BUMPENVLSCALE and WINED3DTSS_BUMPENVLOFFSET are next to each other. * point gl to the scale, and load 4 floats. x = scale, y = offset, z and w are junk, we * don't care about them. The pointers are valid for sure because the stateblock is bigger. @@ -777,7 +778,9 @@ static void pshader_hw_bem(const SHADER_OPCODE_ARG *arg) int i; for(i = 0; i < This->numbumpenvmatconsts; i++) { - if(This->bumpenvmatconst[i].const_num != -1 && This->bumpenvmatconst[i].texunit == sampler_code) { + if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED + && This->bumpenvmatconst[i].texunit == sampler_code) + { has_bumpmat = TRUE; break; } @@ -1232,13 +1235,17 @@ static void pshader_hw_texbem(const SHADER_OPCODE_ARG *arg) pshader_get_register_name(arg->shader, dst, reg_coord); for(i = 0; i < This->numbumpenvmatconsts; i++) { - if(This->bumpenvmatconst[i].const_num != -1 && reg_dest_code == This->bumpenvmatconst[i].texunit) { + if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED + && reg_dest_code == This->bumpenvmatconst[i].texunit) + { has_bumpmat = TRUE; break; } } for(i = 0; i < This->numbumpenvmatconsts; i++) { - if(This->luminanceconst[i].const_num != -1 && reg_dest_code == This->luminanceconst[i].texunit) { + if (This->luminanceconst[i].const_num != WINED3D_CONST_NUM_UNUSED + && reg_dest_code == This->luminanceconst[i].texunit) + { has_luminance = TRUE; break; } diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 55552089c6c..a8c137f9b45 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -834,7 +834,8 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi */ for(i = 0; i < desc->num_textures_used; i++) { mapped_stage = This->texUnitMap[i]; - if(mapped_stage != -1) { + if (mapped_stage != WINED3D_UNMAPPED_STAGE) + { GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("glActiveTextureARB"); texture_activate_dimensions(i, stateblock, context); diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index c0d92c5ff81..cd4952d8050 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -34,348 +34,106 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); #define VB_MAXDECLCHANGES 100 /* After that number we stop converting */ #define VB_RESETDECLCHANGE 1000 /* Reset the changecount after that number of draws */ -/* IUnknown methods */ - -static HRESULT STDMETHODCALLTYPE buffer_QueryInterface(IWineD3DBuffer *iface, - REFIID riid, void **object) -{ - TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); - - if (IsEqualGUID(riid, &IID_IWineD3DBuffer) - || IsEqualGUID(riid, &IID_IWineD3DResource) - || IsEqualGUID(riid, &IID_IWineD3DBase) - || IsEqualGUID(riid, &IID_IUnknown)) - { - IUnknown_AddRef(iface); - *object = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); - - *object = NULL; - - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) +static void buffer_create_buffer_object(struct wined3d_buffer *This) { - struct wined3d_buffer *This = (struct wined3d_buffer *)iface; - ULONG refcount = InterlockedIncrement(&This->resource.ref); + GLenum error, gl_usage; + IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - TRACE("%p increasing refcount to %u\n", This, refcount); + TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n", + This, debug_d3dusage(This->resource.usage)); - return refcount; -} + /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */ + ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); + ENTER_GL(); -static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface) -{ - struct wined3d_buffer *This = (struct wined3d_buffer *)iface; - ULONG refcount = InterlockedDecrement(&This->resource.ref); + /* Make sure that the gl error is cleared. Do not use checkGLcall + * here because checkGLcall just prints a fixme and continues. However, + * if an error during VBO creation occurs we can fall back to non-vbo operation + * with full functionality(but performance loss) + */ + while (glGetError() != GL_NO_ERROR); - TRACE("%p decreasing refcount to %u\n", This, refcount); + /* Basically the FVF parameter passed to CreateVertexBuffer is no good + * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with + * IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer + * look like. This means that on each DrawPrimitive call the vertex buffer has to be verified + * to check if the rhw and color values are in the correct format. + */ - if (!refcount) + GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object)); + error = glGetError(); + if (!This->buffer_object || error != GL_NO_ERROR) { - resource_cleanup((IWineD3DResource *)iface); - HeapFree(GetProcessHeap(), 0, This); + ERR("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error); + goto fail; } - return refcount; -} - -/* IWineD3DBase methods */ - -static HRESULT STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface, IUnknown **parent) -{ - return resource_get_parent((IWineD3DResource *)iface, parent); -} - -/* IWineD3DResource methods */ - -static HRESULT STDMETHODCALLTYPE buffer_GetDevice(IWineD3DBuffer *iface, IWineD3DDevice **device) -{ - return resource_get_device((IWineD3DResource *)iface, device); -} - -static HRESULT STDMETHODCALLTYPE buffer_SetPrivateData(IWineD3DBuffer *iface, - REFGUID guid, const void *data, DWORD data_size, DWORD flags) -{ - return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags); -} - -static HRESULT STDMETHODCALLTYPE buffer_GetPrivateData(IWineD3DBuffer *iface, - REFGUID guid, void *data, DWORD *data_size) -{ - return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size); -} - -static HRESULT STDMETHODCALLTYPE buffer_FreePrivateData(IWineD3DBuffer *iface, REFGUID guid) -{ - return resource_free_private_data((IWineD3DResource *)iface, guid); -} - -static DWORD STDMETHODCALLTYPE buffer_SetPriority(IWineD3DBuffer *iface, DWORD priority) -{ - return resource_set_priority((IWineD3DResource *)iface, priority); -} - -static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) -{ - return resource_get_priority((IWineD3DResource *)iface); -} - -static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) -{ - TRACE("iface %p\n", iface); -} - -static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) -{ - TRACE("iface %p\n", iface); -} - -static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface) -{ - return resource_get_type((IWineD3DResource *)iface); -} - -const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = -{ - /* IUnknown methods */ - buffer_QueryInterface, - buffer_AddRef, - buffer_Release, - /* IWineD3DBase methods */ - buffer_GetParent, - /* IWineD3DResource methods */ - buffer_GetDevice, - buffer_SetPrivateData, - buffer_GetPrivateData, - buffer_FreePrivateData, - buffer_SetPriority, - buffer_GetPriority, - buffer_PreLoad, - buffer_UnLoad, - buffer_GetType, -}; - -/* IUnknown methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_QueryInterface(IWineD3DVertexBuffer *iface, - REFIID riid, void **object) -{ - TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); - - if (IsEqualGUID(riid, &IID_IWineD3DVertexBuffer) - || IsEqualGUID(riid, &IID_IWineD3DResource) - || IsEqualGUID(riid, &IID_IWineD3DBase) - || IsEqualGUID(riid, &IID_IUnknown)) + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + error = glGetError(); + if (error != GL_NO_ERROR) { - IUnknown_AddRef(iface); - *object = iface; - return S_OK; + ERR("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error); + goto fail; } - WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); - - *object = NULL; - - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE IWineD3DVertexBufferImpl_AddRef(IWineD3DVertexBuffer *iface) -{ - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; - ULONG refcount = InterlockedIncrement(&This->resource.ref); - - TRACE("%p increasing refcount to %u\n", This, refcount); - - return refcount; -} - -static ULONG STDMETHODCALLTYPE IWineD3DVertexBufferImpl_Release(IWineD3DVertexBuffer *iface) -{ - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; - ULONG refcount = InterlockedDecrement(&This->resource.ref); - - TRACE("%p decreasing refcount to %u\n", This, refcount); - - if (!refcount) + /* Don't use static, because dx apps tend to update the buffer + * quite often even if they specify 0 usage. Because we always keep the local copy + * we never read from the vbo and can create a write only opengl buffer. + */ + switch(This->resource.usage & (WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC)) { - if (This->vbo) - { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - - ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - } - - resource_cleanup((IWineD3DResource *)iface); - HeapFree(GetProcessHeap(), 0, This); - } - - return refcount; -} - -/* IWineD3DBase methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetParent(IWineD3DVertexBuffer *iface, IUnknown **parent) -{ - return resource_get_parent((IWineD3DResource *)iface, parent); -} - -/* IWineD3DResource methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetDevice(IWineD3DVertexBuffer *iface, - IWineD3DDevice **device) -{ - return resource_get_device((IWineD3DResource *)iface, device); -} - -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_SetPrivateData(IWineD3DVertexBuffer *iface, - REFGUID guid, const void *data, DWORD data_size, DWORD flags) -{ - return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags); -} - -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetPrivateData(IWineD3DVertexBuffer *iface, - REFGUID guid, void *data, DWORD *data_size) -{ - return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size); -} - -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_FreePrivateData(IWineD3DVertexBuffer *iface, REFGUID guid) -{ - return resource_free_private_data((IWineD3DResource *)iface, guid); -} - -static DWORD STDMETHODCALLTYPE IWineD3DVertexBufferImpl_SetPriority(IWineD3DVertexBuffer *iface, DWORD priority) -{ - return resource_set_priority((IWineD3DResource *)iface, priority); -} - -static DWORD STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetPriority(IWineD3DVertexBuffer *iface) -{ - return resource_get_priority((IWineD3DResource *)iface); -} - -static inline void fixup_d3dcolor(DWORD *pos) -{ - DWORD srcColor = *pos; - - /* Color conversion like in drawStridedSlow. watch out for little endianity - * If we want that stuff to work on big endian machines too we have to consider more things - * - * 0xff000000: Alpha mask - * 0x00ff0000: Blue mask - * 0x0000ff00: Green mask - * 0x000000ff: Red mask - */ - *pos = 0; - *pos |= (srcColor & 0xff00ff00) ; /* Alpha Green */ - *pos |= (srcColor & 0x00ff0000) >> 16; /* Red */ - *pos |= (srcColor & 0x000000ff) << 16; /* Blue */ -} - -static inline void fixup_transformed_pos(float *p) -{ - float x, y, z, w; + case WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC: + case WINED3DUSAGE_DYNAMIC: + TRACE("Gl usage = GL_STREAM_DRAW\n"); + gl_usage = GL_STREAM_DRAW_ARB; + break; - /* rhw conversion like in drawStridedSlow */ - if (p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps))) - { - x = p[0]; - y = p[1]; - z = p[2]; - w = 1.0; - } - else - { - w = 1.0 / p[3]; - x = p[0] * w; - y = p[1] * w; - z = p[2] * w; + case WINED3DUSAGE_WRITEONLY: + default: + TRACE("Gl usage = GL_DYNAMIC_DRAW\n"); + gl_usage = GL_DYNAMIC_DRAW_ARB; + break; } - p[0] = x; - p[1] = y; - p[2] = z; - p[3] = w; -} - -static DWORD *find_conversion_shift(IWineD3DVertexBufferImpl *This, - const WineDirect3DVertexStridedData *strided, DWORD stride) -{ - DWORD *ret, i, shift, j, type; - DWORD orig_type_size; - if (!stride) + /* Reserve memory for the buffer. The amount of data won't change + * so we are safe with calling glBufferData once with a NULL ptr and + * calling glBufferSubData on updates + */ + GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, This->resource.size, NULL, gl_usage)); + error = glGetError(); + if (error != GL_NO_ERROR) { - TRACE("No shift\n"); - return NULL; + ERR("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error); + goto fail; } - This->conv_stride = stride; - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWORD) * stride); - for (i = 0; i < MAX_ATTRIBS; ++i) - { - if (strided->u.input[i].VBO != This->vbo) continue; + LEAVE_GL(); - type = strided->u.input[i].dwType; - if (type == WINED3DDECLTYPE_FLOAT16_2) - { - shift = 4; - } - else if (type == WINED3DDECLTYPE_FLOAT16_4) - { - shift = 8; - /* Pre-shift the last 4 bytes in the FLOAT16_4 by 4 bytes - this makes FLOAT16_2 and FLOAT16_4 conversions - * compatible - */ - for (j = 4; j < 8; ++j) - { - ret[(DWORD_PTR)strided->u.input[i].lpData + j] += 4; - } - } - else - { - shift = 0; - } - This->conv_stride += shift; + This->buffer_object_size = This->resource.size; + This->buffer_object_usage = gl_usage; + This->dirty_start = 0; + This->dirty_end = This->resource.size; + This->flags |= WINED3D_BUFFER_DIRTY; - if (shift) - { - orig_type_size = WINED3D_ATR_TYPESIZE(type) * WINED3D_ATR_SIZE(type); - for (j = (DWORD_PTR)strided->u.input[i].lpData + orig_type_size; j < stride; ++j) - { - ret[j] += shift; - } - } - } + return; - if (TRACE_ON(d3d)) - { - TRACE("Dumping conversion shift:\n"); - for (i = 0; i < stride; ++i) - { - TRACE("[%d]", ret[i]); - } - TRACE("\n"); - } +fail: + /* Clean up all vbo init, but continue because we can work without a vbo :-) */ + ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n"); + if (This->buffer_object) GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); + This->buffer_object = 0; + LEAVE_GL(); - return ret; + return; } -static inline BOOL process_converted_attribute(IWineD3DVertexBufferImpl *This, - const enum vbo_conversion_type conv_type, const WineDirect3DStridedData *attrib, - DWORD *stride_this_run, const DWORD type) +static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, + const enum wined3d_buffer_conversion_type conversion_type, + const WineDirect3DStridedData *attrib, DWORD *stride_this_run, const DWORD type) { DWORD attrib_size; BOOL ret = FALSE; - int i; + unsigned int i; DWORD offset = This->resource.wineD3DDevice->stateBlock->streamOffset[attrib->streamNo]; DWORD_PTR data; @@ -403,8 +161,9 @@ static inline BOOL process_converted_attribute(IWineD3DVertexBufferImpl *This, */ TRACE("Reconverting because converted attributes occur, and the stride changed\n"); This->stride = *stride_this_run; - HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This->conv_map); - This->conv_map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->conv_map) * This->stride); + HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This->conversion_map); + This->conversion_map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(*This->conversion_map) * This->stride); ret = TRUE; } } @@ -413,19 +172,19 @@ static inline BOOL process_converted_attribute(IWineD3DVertexBufferImpl *This, attrib_size = WINED3D_ATR_SIZE(type) * WINED3D_ATR_TYPESIZE(type); for (i = 0; i < attrib_size; ++i) { - if (This->conv_map[data + i] != conv_type) + if (This->conversion_map[data + i] != conversion_type) { TRACE("Byte %ld in vertex changed\n", i + data); - TRACE("It was type %d, is %d now\n", This->conv_map[data + i], conv_type); + TRACE("It was type %d, is %d now\n", This->conversion_map[data + i], conversion_type); ret = TRUE; - This->conv_map[data + i] = conv_type; + This->conversion_map[data + i] = conversion_type; } } return ret; } -static inline BOOL check_attribute(IWineD3DVertexBufferImpl *This, +static BOOL buffer_check_attribute(struct wined3d_buffer *This, const WineDirect3DStridedData *attrib, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color, DWORD *stride_this_run, BOOL *float16_used) { @@ -435,13 +194,13 @@ static inline BOOL check_attribute(IWineD3DVertexBufferImpl *This, /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is * there, on nonexistent attribs the vbo is 0. */ - if (attrib->VBO != This->vbo) return FALSE; + if (attrib->VBO != This->buffer_object) return FALSE; type = attrib->dwType; /* Look for newly appeared conversion */ if (!GL_SUPPORT(NV_HALF_FLOAT) && (type == WINED3DDECLTYPE_FLOAT16_2 || type == WINED3DDECLTYPE_FLOAT16_4)) { - ret = process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run, type); + ret = buffer_process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run, type); if (is_ffp_position) FIXME("Test FLOAT16 fixed function processing positions\n"); else if (is_ffp_color) FIXME("test FLOAT16 fixed function processing colors\n"); @@ -449,34 +208,100 @@ static inline BOOL check_attribute(IWineD3DVertexBufferImpl *This, } else if (check_d3dcolor && type == WINED3DDECLTYPE_D3DCOLOR) { - ret = process_converted_attribute(This, CONV_D3DCOLOR, attrib, stride_this_run, WINED3DDECLTYPE_D3DCOLOR); + ret = buffer_process_converted_attribute(This, CONV_D3DCOLOR, + attrib, stride_this_run, WINED3DDECLTYPE_D3DCOLOR); if (!is_ffp_color) FIXME("Test for non-color fixed function D3DCOLOR type\n"); } else if (is_ffp_position && type == WINED3DDECLTYPE_FLOAT4) { - ret = process_converted_attribute(This, CONV_POSITIONT, attrib, stride_this_run, WINED3DDECLTYPE_FLOAT4); + ret = buffer_process_converted_attribute(This, CONV_POSITIONT, + attrib, stride_this_run, WINED3DDECLTYPE_FLOAT4); + } + else if (This->conversion_map) + { + ret = buffer_process_converted_attribute(This, CONV_NONE, + attrib, stride_this_run, type); + } + + return ret; +} + +static UINT *find_conversion_shift(struct wined3d_buffer *This, + const WineDirect3DVertexStridedData *strided, UINT stride) +{ + UINT *ret, i, j, shift, orig_type_size; + DWORD type; + + if (!stride) + { + TRACE("No shift\n"); + return NULL; + } + + This->conversion_stride = stride; + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWORD) * stride); + for (i = 0; i < MAX_ATTRIBS; ++i) + { + if (strided->u.input[i].VBO != This->buffer_object) continue; + + type = strided->u.input[i].dwType; + if (type == WINED3DDECLTYPE_FLOAT16_2) + { + shift = 4; + } + else if (type == WINED3DDECLTYPE_FLOAT16_4) + { + shift = 8; + /* Pre-shift the last 4 bytes in the FLOAT16_4 by 4 bytes - this makes FLOAT16_2 and FLOAT16_4 conversions + * compatible + */ + for (j = 4; j < 8; ++j) + { + ret[(DWORD_PTR)strided->u.input[i].lpData + j] += 4; + } + } + else + { + shift = 0; + } + This->conversion_stride += shift; + + if (shift) + { + orig_type_size = WINED3D_ATR_TYPESIZE(type) * WINED3D_ATR_SIZE(type); + for (j = (DWORD_PTR)strided->u.input[i].lpData + orig_type_size; j < stride; ++j) + { + ret[j] += shift; + } + } } - else if (This->conv_map) + + if (TRACE_ON(d3d)) { - ret = process_converted_attribute(This, CONV_NONE, attrib, stride_this_run, type); + TRACE("Dumping conversion shift:\n"); + for (i = 0; i < stride; ++i) + { + TRACE("[%d]", ret[i]); + } + TRACE("\n"); } return ret; } -static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *This) +static BOOL buffer_find_decl(struct wined3d_buffer *This) { IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - BOOL ret = FALSE; - int i; - DWORD stride_this_run = 0; + UINT stride_this_run = 0; BOOL float16_used = FALSE; + BOOL ret = FALSE; + unsigned int i; /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer. * Once we have our declaration there is no need to look it up again. */ - if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->Flags & VBFLAG_HASDESC) return FALSE; + if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->flags & WINED3D_BUFFER_HASDESC) return FALSE; TRACE("Finding vertex buffer conversion information\n"); /* Certain declaration types need some fixups before we can pass them to @@ -528,15 +353,15 @@ static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T */ if (!((IWineD3DVertexDeclarationImpl *) device->stateBlock->vertexDecl)->half_float_conv_needed) { - if (This->conv_map) + if (This->conversion_map) { TRACE("Now using shaders without conversion, but conversion used before\n"); - HeapFree(GetProcessHeap(), 0, This->conv_map); - HeapFree(GetProcessHeap(), 0, This->conv_shift); - This->conv_map = NULL; + HeapFree(GetProcessHeap(), 0, This->conversion_map); + HeapFree(GetProcessHeap(), 0, This->conversion_shift); + This->conversion_map = NULL; This->stride = 0; - This->conv_shift = NULL; - This->conv_stride = 0; + This->conversion_shift = NULL; + This->conversion_stride = 0; return TRUE; } else @@ -546,195 +371,287 @@ static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T } for (i = 0; i < MAX_ATTRIBS; ++i) { - ret = check_attribute(This, &device->strided_streams.u.input[i], + ret = buffer_check_attribute(This, &device->strided_streams.u.input[i], FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; } - /* Recalculate the conversion shift map if the declaration has changed, - * and we're using float16 conversion or used it on the last run - */ - if (ret && (float16_used || This->conv_map)) + /* Recalculate the conversion shift map if the declaration has changed, + * and we're using float16 conversion or used it on the last run + */ + if (ret && (float16_used || This->conversion_map)) + { + HeapFree(GetProcessHeap(), 0, This->conversion_shift); + This->conversion_shift = find_conversion_shift(This, &device->strided_streams, This->stride); + } + } + else + { + /* Fixed function is a bit trickier. We have to take care for D3DCOLOR types, FLOAT4 positions and of course + * FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all + * the attributes that our current fixed function pipeline implementation cares for. + */ + BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA); + ret = buffer_check_attribute(This, &device->strided_streams.u.s.position, + TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.normal, + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.diffuse, + !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.specular, + !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[0], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[1], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[2], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[3], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[4], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[5], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[6], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[7], + TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; + + if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n"); + } + + if (stride_this_run == 0 && This->conversion_map) + { + /* Sanity test */ + if (!ret) ERR("no converted attributes found, old conversion map exists, and no declaration change?\n"); + HeapFree(GetProcessHeap(), 0, This->conversion_map); + This->conversion_map = NULL; + This->stride = 0; + } + + if (ret) TRACE("Conversion information changed\n"); + + return ret; +} + +static void buffer_check_buffer_object_size(struct wined3d_buffer *This) +{ + UINT size = This->conversion_stride ? + This->conversion_stride * (This->resource.size / This->stride) : This->resource.size; + if (This->buffer_object_size != size) + { + TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size); + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + checkGLcall("glBindBufferARB"); + GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->buffer_object_usage)); + This->buffer_object_size = size; + checkGLcall("glBufferDataARB"); + LEAVE_GL(); + } +} + +static inline void fixup_d3dcolor(DWORD *dst_color) +{ + DWORD src_color = *dst_color; + + /* Color conversion like in drawStridedSlow. watch out for little endianity + * If we want that stuff to work on big endian machines too we have to consider more things + * + * 0xff000000: Alpha mask + * 0x00ff0000: Blue mask + * 0x0000ff00: Green mask + * 0x000000ff: Red mask + */ + *dst_color = 0; + *dst_color |= (src_color & 0xff00ff00); /* Alpha Green */ + *dst_color |= (src_color & 0x00ff0000) >> 16; /* Red */ + *dst_color |= (src_color & 0x000000ff) << 16; /* Blue */ +} + +static inline void fixup_transformed_pos(float *p) +{ + float x, y, z, w; + + /* rhw conversion like in drawStridedSlow */ + if (p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps))) + { + x = p[0]; + y = p[1]; + z = p[2]; + w = 1.0; + } + else + { + w = 1.0 / p[3]; + x = p[0] * w; + y = p[1] * w; + z = p[2] * w; + } + p[0] = x; + p[1] = y; + p[2] = z; + p[3] = w; +} + +const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) +{ + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + + *buffer_object = This->buffer_object; + if (!This->buffer_object) + { + if (This->flags & WINED3D_BUFFER_CREATEBO) { - HeapFree(GetProcessHeap(), 0, This->conv_shift); - This->conv_shift = find_conversion_shift(This, &device->strided_streams, This->stride); + buffer_create_buffer_object(This); + This->flags &= ~WINED3D_BUFFER_CREATEBO; + if (This->buffer_object) + { + *buffer_object = This->buffer_object; + return (const BYTE *)offset; + } } + return This->resource.allocatedMemory + offset; } else { - /* Fixed function is a bit trickier. We have to take care for D3DCOLOR types, FLOAT4 positions and of course - * FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all - * the attributes that our current fixed function pipeline implementation cares for. - */ - BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA); - ret = check_attribute(This, &device->strided_streams.u.s.position, - TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.normal, - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.diffuse, - !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.specular, - !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[0], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[1], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[2], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[3], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[4], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[5], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[6], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = check_attribute(This, &device->strided_streams.u.s.texCoords[7], - TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - - if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n"); + return (const BYTE *)offset; } +} + +/* IUnknown methods */ - if (stride_this_run == 0 && This->conv_map) +static HRESULT STDMETHODCALLTYPE buffer_QueryInterface(IWineD3DBuffer *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IWineD3DBuffer) + || IsEqualGUID(riid, &IID_IWineD3DResource) + || IsEqualGUID(riid, &IID_IWineD3DBase) + || IsEqualGUID(riid, &IID_IUnknown)) { - /* Sanity test */ - if (!ret) ERR("no converted attributes found, old conversion map exists, and no declaration change?\n"); - HeapFree(GetProcessHeap(), 0, This->conv_map); - This->conv_map = NULL; - This->stride = 0; + IUnknown_AddRef(iface); + *object = iface; + return S_OK; } - This->Flags |= VBFLAG_HASDESC; - if (ret) TRACE("Conversion information changed\n"); + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); - return ret; + *object = NULL; + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) +{ + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + ULONG refcount = InterlockedIncrement(&This->resource.ref); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; } -static void check_vbo_size(IWineD3DVertexBufferImpl *This) +static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) { - DWORD size = This->conv_stride ? This->conv_stride * (This->resource.size / This->stride) : This->resource.size; - if (This->vbo_size != size) + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + + TRACE("iface %p\n", iface); + + /* This is easy: The whole content is shadowed in This->resource.allocatedMemory, + * so we only have to destroy the vbo. Only do it if we have a vbo, which implies + * that vbos are supported + */ + if (This->buffer_object) { - TRACE("Old size %d, creating new size %d\n", This->vbo_size, size); + IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + + ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); - checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->vbo_usage)); - This->vbo_size = size; - checkGLcall("glBufferDataARB"); + GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); + checkGLcall("glDeleteBuffersARB"); LEAVE_GL(); + This->buffer_object = 0; + This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */ } } -static void CreateVBO(IWineD3DVertexBufferImpl *This) +static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface) { - GLenum error, glUsage; - DWORD vboUsage = This->resource.usage; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - - TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n", - This, debug_d3dusage(vboUsage)); - - /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */ - ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - - /* Make sure that the gl error is cleared. Do not use checkGLcall - * here because checkGLcall just prints a fixme and continues. However, - * if an error during VBO creation occurs we can fall back to non-vbo operation - * with full functionality(but performance loss) - */ - while(glGetError() != GL_NO_ERROR); + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + ULONG refcount = InterlockedDecrement(&This->resource.ref); - /* Basically the FVF parameter passed to CreateVertexBuffer is no good - * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with - * IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer - * look like. This means that on each DrawPrimitive call the vertex buffer has to be verified - * to check if the rhw and color values are in the correct format. - */ + TRACE("%p decreasing refcount to %u\n", This, refcount); - GL_EXTCALL(glGenBuffersARB(1, &This->vbo)); - error = glGetError(); - if (This->vbo == 0 || error != GL_NO_ERROR) + if (!refcount) { - WARN("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error); - goto error; + buffer_UnLoad(iface); + resource_cleanup((IWineD3DResource *)iface); + HeapFree(GetProcessHeap(), 0, This); } - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); - error = glGetError(); - if (error != GL_NO_ERROR) - { - WARN("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error); - goto error; - } + return refcount; +} - /* Don't use static, because dx apps tend to update the buffer - * quite often even if they specify 0 usage. Because we always keep the local copy - * we never read from the vbo and can create a write only opengl buffer. - */ - switch(vboUsage & (WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC)) - { - case WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC: - case WINED3DUSAGE_DYNAMIC: - TRACE("Gl usage = GL_STREAM_DRAW\n"); - glUsage = GL_STREAM_DRAW_ARB; - break; +/* IWineD3DBase methods */ - case WINED3DUSAGE_WRITEONLY: - default: - TRACE("Gl usage = GL_DYNAMIC_DRAW\n"); - glUsage = GL_DYNAMIC_DRAW_ARB; - break; - } +static HRESULT STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface, IUnknown **parent) +{ + return resource_get_parent((IWineD3DResource *)iface, parent); +} - /* Reserve memory for the buffer. The amount of data won't change - * so we are safe with calling glBufferData once with a NULL ptr and - * calling glBufferSubData on updates - */ - GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, This->resource.size, NULL, glUsage)); - error = glGetError(); - if (error != GL_NO_ERROR) - { - WARN("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error); - goto error; - } - This->vbo_size = This->resource.size; - This->vbo_usage = glUsage; - This->dirtystart = 0; - This->dirtyend = This->resource.size; - This->Flags |= VBFLAG_DIRTY; +/* IWineD3DResource methods */ - LEAVE_GL(); +static HRESULT STDMETHODCALLTYPE buffer_GetDevice(IWineD3DBuffer *iface, IWineD3DDevice **device) +{ + return resource_get_device((IWineD3DResource *)iface, device); +} - return; +static HRESULT STDMETHODCALLTYPE buffer_SetPrivateData(IWineD3DBuffer *iface, + REFGUID guid, const void *data, DWORD data_size, DWORD flags) +{ + return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags); +} -error: - /* Clean up all vbo init, but continue because we can work without a vbo :-) */ - FIXME("Failed to create a vertex buffer object. Continuing, but performance issues can occur\n"); - if (This->vbo) GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo)); - This->vbo = 0; - LEAVE_GL(); +static HRESULT STDMETHODCALLTYPE buffer_GetPrivateData(IWineD3DBuffer *iface, + REFGUID guid, void *data, DWORD *data_size) +{ + return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size); +} - return; +static HRESULT STDMETHODCALLTYPE buffer_FreePrivateData(IWineD3DBuffer *iface, REFGUID guid) +{ + return resource_free_private_data((IWineD3DResource *)iface, guid); } -static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *iface) +static DWORD STDMETHODCALLTYPE buffer_SetPriority(IWineD3DBuffer *iface, DWORD priority) +{ + return resource_set_priority((IWineD3DResource *)iface, priority); +} + +static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) +{ + return resource_get_priority((IWineD3DResource *)iface); +} + +static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) { - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface; + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - BYTE *data; UINT start = 0, end = 0, vertices; - BOOL declChanged = FALSE; - int i, j; - TRACE("(%p)->()\n", This); + BOOL decl_changed = FALSE; + unsigned int i, j; + BYTE *data; + + TRACE("iface %p\n", iface); - if (!This->vbo) + if (!This->buffer_object) { /* TODO: Make converting independent from VBOs */ - if (This->Flags & VBFLAG_CREATEVBO) + if (This->flags & WINED3D_BUFFER_CREATEBO) { - CreateVBO(This); - This->Flags &= ~VBFLAG_CREATEVBO; + buffer_create_buffer_object(This); + This->flags &= ~WINED3D_BUFFER_CREATEBO; } else { @@ -743,44 +660,33 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf } /* Reading the declaration makes only sense if the stateblock is finalized and the buffer bound to a stream */ - if (device->isInDraw && This->bindCount > 0) + if (device->isInDraw && This->bind_count > 0) { - declChanged = IWineD3DVertexBufferImpl_FindDecl(This); - } - else if (This->Flags & VBFLAG_HASDESC) - { - /* Reuse the declaration stored in the buffer. It will most likely not change, and if it does - * the stream source state handler will call PreLoad again and the change will be caught - */ - } - else - { - /* Cannot get a declaration, and no declaration is stored in the buffer. It is pointless to preload - * now. When the buffer is used, PreLoad will be called by the stream source state handler and a valid - * declaration for the buffer can be found - */ - return; + decl_changed = buffer_find_decl(This); + This->flags |= WINED3D_BUFFER_HASDESC; } + if (!decl_changed && !(This->flags & WINED3D_BUFFER_HASDESC && This->flags & WINED3D_BUFFER_DIRTY)) return; + /* If applications change the declaration over and over, reconverting all the time is a huge * performance hit. So count the declaration changes and release the VBO if there are too many * of them (and thus stop converting) */ - if (declChanged) + if (decl_changed) { - ++This->declChanges; - This->draws = 0; + ++This->conversion_count; + This->draw_count = 0; - if (This->declChanges > VB_MAXDECLCHANGES) + if (This->conversion_count > VB_MAXDECLCHANGES) { FIXME("Too many declaration changes, stopping converting\n"); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo)); + GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); checkGLcall("glDeleteBuffersARB"); LEAVE_GL(); - This->vbo = 0; - HeapFree(GetProcessHeap(), 0, This->conv_shift); + This->buffer_object = 0; + HeapFree(GetProcessHeap(), 0, This->conversion_shift); /* The stream source state handler might have read the memory of the vertex buffer already * and got the memory in the vbo which is not valid any longer. Dirtify the stream source @@ -791,7 +697,7 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf return; } - check_vbo_size(This); + buffer_check_buffer_object_size(This); } else { @@ -799,42 +705,37 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf * changes it every minute drop the VBO after VB_MAX_DECL_CHANGES minutes. So count draws without * decl changes and reset the decl change count after a specific number of them */ - ++This->draws; - if (This->draws > VB_RESETDECLCHANGE) This->declChanges = 0; + ++This->draw_count; + if (This->draw_count > VB_RESETDECLCHANGE) This->conversion_count = 0; } - if (declChanged) + if (decl_changed) { /* The declaration changed, reload the whole buffer */ WARN("Reloading buffer because of decl change\n"); start = 0; end = This->resource.size; } - else if(This->Flags & VBFLAG_DIRTY) + else { /* No decl change, but dirty data, reload the changed stuff */ - if (This->conv_shift) + if (This->conversion_shift) { - if (This->dirtystart != 0 || This->dirtyend != 0) + if (This->dirty_start != 0 || This->dirty_end != 0) { FIXME("Implement partial buffer loading with shifted conversion\n"); } } - start = This->dirtystart; - end = This->dirtyend; - } - else - { - /* Desc not changed, buffer not dirty, nothing to do :-) */ - return; + start = This->dirty_start; + end = This->dirty_end; } /* Mark the buffer clean */ - This->Flags &= ~VBFLAG_DIRTY; - This->dirtystart = 0; - This->dirtyend = 0; + This->flags &= ~WINED3D_BUFFER_DIRTY; + This->dirty_start = 0; + This->dirty_end = 0; - if (!This->conv_map) + if (!This->conversion_map) { /* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory * directly into the vbo. Do not free the system memory copy because drawPrimitive may need it if @@ -847,7 +748,7 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); } ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); checkGLcall("glBindBufferARB"); GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start)); checkGLcall("glBufferSubDataARB"); @@ -858,24 +759,25 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf /* Now for each vertex in the buffer that needs conversion */ vertices = This->resource.size / This->stride; - if (This->conv_shift) + if (This->conversion_shift) { TRACE("Shifted conversion\n"); - data = HeapAlloc(GetProcessHeap(), 0, vertices * This->conv_stride); + data = HeapAlloc(GetProcessHeap(), 0, vertices * This->conversion_stride); for (i = start / This->stride; i < min((end / This->stride) + 1, vertices); ++i) { for (j = 0; j < This->stride; ++j) { - switch(This->conv_map[j]) + switch(This->conversion_map[j]) { case CONV_NONE: - data[This->conv_stride * i + j + This->conv_shift[j]] = This->resource.allocatedMemory[This->stride * i + j]; + data[This->conversion_stride * i + j + This->conversion_shift[j]] + = This->resource.allocatedMemory[This->stride * i + j]; break; case CONV_FLOAT16_2: { - float *out = (float *)(&data[This->conv_stride * i + j + This->conv_shift[j]]); + float *out = (float *)(&data[This->conversion_stride * i + j + This->conversion_shift[j]]); const WORD *in = (WORD *)(&This->resource.allocatedMemory[i * This->stride + j]); out[1] = float_16_to_32(in + 1); @@ -885,15 +787,16 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf } default: - FIXME("Unimplemented conversion %d in shifted conversion\n", This->conv_map[j]); + FIXME("Unimplemented conversion %d in shifted conversion\n", This->conversion_map[j]); + break; } } } ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conv_stride, data)); + GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conversion_stride, data)); checkGLcall("glBufferSubDataARB"); LEAVE_GL(); } @@ -905,7 +808,7 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf { for (j = 0; j < This->stride; ++j) { - switch(This->conv_map[j]) + switch(This->conversion_map[j]) { case CONV_NONE: /* Done already */ @@ -924,13 +827,13 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf case CONV_FLOAT16_2: ERR("Did not expect FLOAT16 conversion in unshifted conversion\n"); default: - FIXME("Unimplemented conversion %d in shifted conversion\n", This->conv_map[j]); + FIXME("Unimplemented conversion %d in shifted conversion\n", This->conversion_map[j]); } } } ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); checkGLcall("glBindBufferARB"); GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data + start)); checkGLcall("glBufferSubDataARB"); @@ -940,164 +843,112 @@ static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuf HeapFree(GetProcessHeap(), 0, data); } -static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_UnLoad(IWineD3DVertexBuffer *iface) -{ - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - - TRACE("(%p)\n", This); - - /* This is easy: The whole content is shadowed in This->resource.allocatedMemory, - * so we only have to destroy the vbo. Only do it if we have a vbo, which implies - * that vbos are supported - */ - if (This->vbo) - { - ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - This->vbo = 0; - This->Flags |= VBFLAG_CREATEVBO; /* Recreate the VBO next load */ - } -} - -static WINED3DRESOURCETYPE STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetType(IWineD3DVertexBuffer *iface) +static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface) { return resource_get_type((IWineD3DResource *)iface); } -/* IWineD3DVertexBuffer methods */ +/* IWineD3DBuffer methods */ -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface, - UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags) +static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, UINT size, BYTE **data, DWORD flags) { - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; - BYTE *data; + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; - TRACE("(%p)->%d, %d, %p, %08x\n", This, OffsetToLock, SizeToLock, ppbData, Flags); + TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags); - InterlockedIncrement(&This->lockcount); + InterlockedIncrement(&This->lock_count); - if (This->Flags & VBFLAG_DIRTY) + if (This->flags & WINED3D_BUFFER_DIRTY) { - if (This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock; - if (SizeToLock) + if (This->dirty_start > offset) This->dirty_start = offset; + + if (size) { - if (This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock; + if (This->dirty_end < offset + size) This->dirty_end = offset + size; } else { - This->dirtyend = This->resource.size; + This->dirty_end = This->resource.size; } } else { - This->dirtystart = OffsetToLock; - if (SizeToLock) This->dirtyend = OffsetToLock + SizeToLock; - else This->dirtyend = This->resource.size; + This->dirty_start = offset; + if (size) This->dirty_end = offset + size; + else This->dirty_end = This->resource.size; } - data = This->resource.allocatedMemory; - This->Flags |= VBFLAG_DIRTY; - *ppbData = data + OffsetToLock; + This->flags |= WINED3D_BUFFER_DIRTY; + + *data = This->resource.allocatedMemory + offset; - TRACE("(%p) : returning memory of %p (base:%p,offset:%u)\n", This, data + OffsetToLock, data, OffsetToLock); + TRACE("Returning memory at %p (base %p, offset %u)\n", *data, This->resource.allocatedMemory, offset); /* TODO: check Flags compatibility with This->currentDesc.Usage (see MSDN) */ return WINED3D_OK; } -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) +static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) { - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; - LONG lockcount; + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; TRACE("(%p)\n", This); - lockcount = InterlockedDecrement(&This->lockcount); - if (lockcount > 0) + if (InterlockedDecrement(&This->lock_count)) { /* Delay loading the buffer until everything is unlocked */ - TRACE("Ignoring the unlock\n"); + TRACE("Ignoring unlock\n"); return WINED3D_OK; } - if (This->Flags & VBFLAG_HASDESC) + if (This->flags & WINED3D_BUFFER_HASDESC) { - IWineD3DVertexBufferImpl_PreLoad(iface); + buffer_PreLoad(iface); } return WINED3D_OK; } -static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetDesc(IWineD3DVertexBuffer *iface, - WINED3DVERTEXBUFFER_DESC *pDesc) +static HRESULT STDMETHODCALLTYPE buffer_GetDesc(IWineD3DBuffer *iface, WINED3DVERTEXBUFFER_DESC *desc) { - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; TRACE("(%p)\n", This); - pDesc->Format = This->resource.format; - pDesc->Type = This->resource.resourceType; - pDesc->Usage = This->resource.usage; - pDesc->Pool = This->resource.pool; - pDesc->Size = This->resource.size; - pDesc->FVF = This->fvf; + desc->Format = This->resource.format; + desc->Type = This->resource.resourceType; + desc->Usage = This->resource.usage; + desc->Pool = This->resource.pool; + desc->Size = This->resource.size; + desc->FVF = This->fvf; return WINED3D_OK; } -const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl = +const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = { /* IUnknown methods */ - IWineD3DVertexBufferImpl_QueryInterface, - IWineD3DVertexBufferImpl_AddRef, - IWineD3DVertexBufferImpl_Release, + buffer_QueryInterface, + buffer_AddRef, + buffer_Release, /* IWineD3DBase methods */ - IWineD3DVertexBufferImpl_GetParent, + buffer_GetParent, /* IWineD3DResource methods */ - IWineD3DVertexBufferImpl_GetDevice, - IWineD3DVertexBufferImpl_SetPrivateData, - IWineD3DVertexBufferImpl_GetPrivateData, - IWineD3DVertexBufferImpl_FreePrivateData, - IWineD3DVertexBufferImpl_SetPriority, - IWineD3DVertexBufferImpl_GetPriority, - IWineD3DVertexBufferImpl_PreLoad, - IWineD3DVertexBufferImpl_UnLoad, - IWineD3DVertexBufferImpl_GetType, - /* IWineD3DVertexBuffer methods */ - IWineD3DVertexBufferImpl_Lock, - IWineD3DVertexBufferImpl_Unlock, - IWineD3DVertexBufferImpl_GetDesc, + buffer_GetDevice, + buffer_SetPrivateData, + buffer_GetPrivateData, + buffer_FreePrivateData, + buffer_SetPriority, + buffer_GetPriority, + buffer_PreLoad, + buffer_UnLoad, + buffer_GetType, + /* IWineD3DBuffer methods */ + buffer_Map, + buffer_Unmap, + buffer_GetDesc, }; -const BYTE *IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer *iface, DWORD iOffset, GLint *vbo) -{ - IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface; - - *vbo = This->vbo; - if (!This->vbo) - { - if (This->Flags & VBFLAG_CREATEVBO) - { - CreateVBO(This); - This->Flags &= ~VBFLAG_CREATEVBO; - if (This->vbo) - { - *vbo = This->vbo; - return (const BYTE *)iOffset; - } - } - return This->resource.allocatedMemory + iOffset; - } - else - { - return (const BYTE *)iOffset; - } -} - /* IUnknown methods */ static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_QueryInterface(IWineD3DIndexBuffer *iface, diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 3258909cf48..6353aa77bf0 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -919,31 +919,50 @@ out: * *****************************************************************************/ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *context) { - UINT t, s; - WineD3DContext **oldArray = This->contexts; + WineD3DContext **new_array; + BOOL found = FALSE; + UINT i; TRACE("Removing ctx %p\n", context); - This->numContexts--; - - if(This->numContexts) { - This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * This->numContexts); - if(!This->contexts) { - ERR("Cannot allocate a new context array, PANIC!!!\n"); - } - t = 0; - /* Note that we decreased numContexts a few lines up, so use '<=' instead of '<' */ - for(s = 0; s <= This->numContexts; s++) { - if(oldArray[s] == context) continue; - This->contexts[t] = oldArray[s]; - t++; + for (i = 0; i < This->numContexts; ++i) + { + if (This->contexts[i] == context) + { + HeapFree(GetProcessHeap(), 0, context); + found = TRUE; + break; } - } else { + } + + if (!found) + { + ERR("Context %p doesn't exist in context array\n", context); + return; + } + + while (i < This->numContexts - 1) + { + This->contexts[i] = This->contexts[i + 1]; + ++i; + } + + --This->numContexts; + if (!This->numContexts) + { + HeapFree(GetProcessHeap(), 0, This->contexts); This->contexts = NULL; + return; } - HeapFree(GetProcessHeap(), 0, context); - HeapFree(GetProcessHeap(), 0, oldArray); + new_array = HeapReAlloc(GetProcessHeap(), 0, This->contexts, This->numContexts * sizeof(*This->contexts)); + if (!new_array) + { + ERR("Failed to shrink context array. Oh well.\n"); + return; + } + + This->contexts = new_array; } /***************************************************************************** diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 871a59abf20..63f7352a736 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -59,6 +59,89 @@ static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResour **********************************************************/ const float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; /* When needed for comparisons */ +/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these + * actually have the same values in GL and D3D. */ +static GLenum gl_primitive_type_from_d3d(WINED3DPRIMITIVETYPE primitive_type) +{ + switch(primitive_type) + { + case WINED3DPT_POINTLIST: + return GL_POINTS; + + case WINED3DPT_LINELIST: + return GL_LINES; + + case WINED3DPT_LINESTRIP: + return GL_LINE_STRIP; + + case WINED3DPT_TRIANGLELIST: + return GL_TRIANGLES; + + case WINED3DPT_TRIANGLESTRIP: + return GL_TRIANGLE_STRIP; + + case WINED3DPT_TRIANGLEFAN: + return GL_TRIANGLE_FAN; + + case WINED3DPT_LINELIST_ADJ: + return GL_LINES_ADJACENCY_ARB; + + case WINED3DPT_LINESTRIP_ADJ: + return GL_LINE_STRIP_ADJACENCY_ARB; + + case WINED3DPT_TRIANGLELIST_ADJ: + return GL_TRIANGLES_ADJACENCY_ARB; + + case WINED3DPT_TRIANGLESTRIP_ADJ: + return GL_TRIANGLE_STRIP_ADJACENCY_ARB; + + default: + FIXME("Unhandled primitive type %s\n", debug_d3dprimitivetype(primitive_type)); + return GL_NONE; + } +} + +static WINED3DPRIMITIVETYPE d3d_primitive_type_from_gl(GLenum primitive_type) +{ + switch(primitive_type) + { + case GL_POINTS: + return WINED3DPT_POINTLIST; + + case GL_LINES: + return WINED3DPT_LINELIST; + + case GL_LINE_STRIP: + return WINED3DPT_LINESTRIP; + + case GL_TRIANGLES: + return WINED3DPT_TRIANGLELIST; + + case GL_TRIANGLE_STRIP: + return WINED3DPT_TRIANGLESTRIP; + + case GL_TRIANGLE_FAN: + return WINED3DPT_TRIANGLEFAN; + + case GL_LINES_ADJACENCY_ARB: + return WINED3DPT_LINELIST_ADJ; + + case GL_LINE_STRIP_ADJACENCY_ARB: + return WINED3DPT_LINESTRIP_ADJ; + + case GL_TRIANGLES_ADJACENCY_ARB: + return WINED3DPT_TRIANGLELIST_ADJ; + + case GL_TRIANGLE_STRIP_ADJACENCY_ARB: + return WINED3DPT_TRIANGLESTRIP_ADJ; + + default: + FIXME("Unhandled primitive type %s\n", debug_d3dprimitivetype(primitive_type)); + return WINED3DPT_UNDEFINED; + } +} + + /********************************************************** * IUnknown parts follows **********************************************************/ @@ -175,11 +258,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage, - DWORD FVF, WINED3DPOOL Pool, IWineD3DVertexBuffer** ppVertexBuffer, HANDLE *sharedHandle, - IUnknown *parent) { +static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage, + DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DVertexBufferImpl *object; + struct wined3d_buffer *object; WINED3DFORMAT Format = WINED3DFMT_VERTEXDATA; /* Dummy format for now */ int dxVersion = ( (IWineD3DImpl *) This->wineD3D)->dxVersion; HRESULT hr; @@ -206,7 +289,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac return WINED3DERR_OUTOFVIDEOMEMORY; } - object->lpVtbl = &IWineD3DVertexBuffer_Vtbl; + object->vtbl = &wined3d_buffer_vtbl; hr = resource_init(&object->resource, WINED3DRTYPE_VERTEXBUFFER, This, Size, Usage, Format, Pool, parent); if (FAILED(hr)) { @@ -221,7 +304,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object); TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object); - *ppVertexBuffer = (IWineD3DVertexBuffer *)object; + *ppVertexBuffer = (IWineD3DBuffer *)object; object->fvf = FVF; @@ -250,7 +333,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac } else if(dxVersion <= 7 && conv) { TRACE("Not creating a vbo because dxVersion is 7 and the fvf needs conversion\n"); } else { - object->Flags |= VBFLAG_CREATEVBO; + object->flags |= WINED3D_BUFFER_CREATEBO; } return WINED3D_OK; } @@ -469,7 +552,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, for(i = 0; i < MAX_STREAMS; i++) { if(object->streamSource[i]) { - IWineD3DVertexBuffer_AddRef(object->streamSource[i]); + IWineD3DBuffer_AddRef(object->streamSource[i]); } } if(object->pIndexData) { @@ -602,7 +685,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, for(i = 0; i < MAX_STREAMS; i++) { if(object->streamSource[i]) { - IWineD3DVertexBuffer_AddRef(object->streamSource[i]); + IWineD3DBuffer_AddRef(object->streamSource[i]); } } if(object->vertexShader) { @@ -2741,9 +2824,11 @@ static UINT WINAPI IWineD3DDeviceImpl_GetAvailableTextureMem(IWineD3DDevice *ifa /***** * Get / Set Stream Source *****/ -static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, UINT StreamNumber,IWineD3DVertexBuffer* pStreamData, UINT OffsetInBytes, UINT Stride) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DVertexBuffer *oldSrc; +static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, UINT StreamNumber, + IWineD3DBuffer *pStreamData, UINT OffsetInBytes, UINT Stride) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DBuffer *oldSrc; if (StreamNumber >= MAX_STREAMS) { WARN("Stream out of range %d\n", StreamNumber); @@ -2774,19 +2859,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, /* Handle recording of state blocks */ if (This->isRecordingState) { TRACE("Recording... not performing anything\n"); - if(pStreamData) IWineD3DVertexBuffer_AddRef(pStreamData); - if(oldSrc) IWineD3DVertexBuffer_Release(oldSrc); + if (pStreamData) IWineD3DBuffer_AddRef(pStreamData); + if (oldSrc) IWineD3DBuffer_Release(oldSrc); return WINED3D_OK; } if (pStreamData != NULL) { - IWineD3DVertexBufferImpl *vbImpl = (IWineD3DVertexBufferImpl *) pStreamData; - InterlockedIncrement(&vbImpl->bindCount); - IWineD3DVertexBuffer_AddRef(pStreamData); + InterlockedIncrement(&((struct wined3d_buffer *)pStreamData)->bind_count); + IWineD3DBuffer_AddRef(pStreamData); } if (oldSrc != NULL) { - InterlockedDecrement(&((IWineD3DVertexBufferImpl *) oldSrc)->bindCount); - IWineD3DVertexBuffer_Release(oldSrc); + InterlockedDecrement(&((struct wined3d_buffer *)oldSrc)->bind_count); + IWineD3DBuffer_Release(oldSrc); } IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC); @@ -2794,7 +2878,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSource(IWineD3DDevice *iface, UINT StreamNumber,IWineD3DVertexBuffer** pStream, UINT *pOffset, UINT* pStride) { +static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSource(IWineD3DDevice *iface, + UINT StreamNumber, IWineD3DBuffer **pStream, UINT *pOffset, UINT *pStride) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("(%p) : StreamNo: %u, Stream (%p), Offset %u, Stride %u\n", This, StreamNumber, @@ -2813,7 +2899,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSource(IWineD3DDevice *iface, } if (*pStream != NULL) { - IWineD3DVertexBuffer_AddRef(*pStream); /* We have created a new reference to the VB */ + IWineD3DBuffer_AddRef(*pStream); /* We have created a new reference to the VB */ } return WINED3D_OK; } @@ -3973,7 +4059,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) { for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) { int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS; if (vshader_sampler_tokens[i]) { - if (This->texUnitMap[vsampler_idx] != -1) { + if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE) + { /* Already mapped somewhere */ continue; } @@ -4213,7 +4300,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF( #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount, - const WineDirect3DVertexStridedData *lpStrideData, IWineD3DVertexBufferImpl *dest, DWORD dwFlags) + const WineDirect3DVertexStridedData *lpStrideData, struct wined3d_buffer *dest, DWORD dwFlags) { char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL; unsigned int i; @@ -4245,9 +4332,10 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn ERR("Out of memory\n"); return E_OUTOFMEMORY; } - if(dest->vbo) { + if (dest->buffer_object) + { const void *src; - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->vbo)); + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object)); checkGLcall("glBindBufferARB"); src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB)); if(src) { @@ -4261,12 +4349,14 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn /* Get a pointer into the destination vbo(create one if none exists) and * write correct opengl data into it. It's cheap and allows us to run drawStridedFast */ - if(!dest->vbo && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) { - dest->Flags |= VBFLAG_CREATEVBO; - IWineD3DVertexBuffer_PreLoad((IWineD3DVertexBuffer *) dest); + if (!dest->buffer_object && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) + { + dest->flags |= WINED3D_BUFFER_CREATEBO; + IWineD3DBuffer_PreLoad((IWineD3DBuffer *)dest); } - if(dest->vbo) { + if (dest->buffer_object) + { unsigned char extrabytes = 0; /* If the destination vertex buffer has D3DFVF_XYZ position(non-rhw), native d3d writes RHW position, where the RHW * gets written into the 4 bytes after the Z position. In the case of a dest buffer that only has D3DFVF_XYZ data, @@ -4553,7 +4643,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn } if(dest_conv) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->vbo)); + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object)); checkGLcall("glBindBufferARB(GL_ARRAY_BUFFER_ARB)"); GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, dwDestIndex * get_flexible_vertex_size(DestFVF), dwCount * get_flexible_vertex_size(DestFVF), @@ -4568,7 +4658,9 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn } #undef copy_and_next -static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IWineD3DVertexBuffer* pDestBuffer, IWineD3DVertexDeclaration* pVertexDecl, DWORD Flags) { +static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, + UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; WineDirect3DVertexStridedData strided; BOOL vbo = FALSE, streamWasUP = This->stateBlock->streamIsUP; @@ -4598,12 +4690,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, */ #define FIXSRC(type) \ if(strided.u.s.type.VBO) { \ - IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[strided.u.s.type.streamNo]; \ + struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[strided.u.s.type.streamNo]; \ strided.u.s.type.VBO = 0; \ strided.u.s.type.lpData = (BYTE *) ((unsigned long) strided.u.s.type.lpData + (unsigned long) vb->resource.allocatedMemory); \ ENTER_GL(); \ - GL_EXTCALL(glDeleteBuffersARB(1, &vb->vbo)); \ - vb->vbo = 0; \ + GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); \ + vb->buffer_object = 0; \ LEAVE_GL(); \ } \ if(strided.u.s.type.lpData) { \ @@ -4630,7 +4722,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, #undef FIXSRC } - return process_vertices_strided(This, DestIndex, VertexCount, &strided, (IWineD3DVertexBufferImpl *) pDestBuffer, Flags); + return process_vertices_strided(This, DestIndex, VertexCount, &strided, + (struct wined3d_buffer *)pDestBuffer, Flags); } /***** @@ -5301,14 +5394,35 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun /***** * Drawing functions *****/ -static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, - UINT PrimitiveCount) { +static void WINAPI IWineD3DDeviceImpl_SetPrimitiveType(IWineD3DDevice *iface, + WINED3DPRIMITIVETYPE primitive_type) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType, - debug_d3dprimitivetype(PrimitiveType), - StartVertex, PrimitiveCount); + TRACE("iface %p, primitive_type %s\n", iface, debug_d3dprimitivetype(primitive_type)); + + This->updateStateBlock->changed.primitive_type = TRUE; + This->updateStateBlock->gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); +} + +static void WINAPI IWineD3DDeviceImpl_GetPrimitiveType(IWineD3DDevice *iface, + WINED3DPRIMITIVETYPE *primitive_type) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + + TRACE("iface %p, primitive_type %p\n", iface, primitive_type); + + *primitive_type = d3d_primitive_type_from_gl(This->stateBlock->gl_primitive_type); + + TRACE("Returning %s\n", debug_d3dprimitivetype(*primitive_type)); +} + +static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice *iface, UINT StartVertex, UINT vertex_count) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + + TRACE("(%p) : start %u, count %u\n", This, StartVertex, vertex_count); if(!This->stateBlock->vertexDecl) { WARN("(%p) : Called without a valid vertex declaration set\n", This); @@ -5326,16 +5440,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice *iface, WI IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC); } /* Account for the loading offset due to index buffers. Instead of reloading all sources correct it with the startvertex parameter */ - drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0/* NumVertices */, StartVertex /* start_idx */, + drawPrimitive(iface, vertex_count, 0/* NumVertices */, StartVertex /* start_idx */, 0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */); return WINED3D_OK; } -/* TODO: baseVIndex needs to be provided from This->stateBlock->baseVertexIndex when called from d3d8 */ -static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *iface, - WINED3DPRIMITIVETYPE PrimitiveType, - UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) { - +static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *iface, + UINT minIndex, UINT NumVertices, UINT startIndex, UINT index_count) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; UINT idxStride = 2; IWineD3DIndexBuffer *pIB; @@ -5363,9 +5475,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice * } vbo = ((IWineD3DIndexBufferImpl *) pIB)->vbo; - TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d\n", This, - PrimitiveType, debug_d3dprimitivetype(PrimitiveType), - minIndex, NumVertices, startIndex, primCount); + TRACE("(%p) : min %u, vertex count %u, startIdx %u, index count %u\n", + This, minIndex, NumVertices, startIndex, index_count); IWineD3DIndexBuffer_GetDesc(pIB, &IdxBufDsc); if (IdxBufDsc.Format == WINED3DFMT_R16_UINT) { @@ -5379,21 +5490,20 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice * IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC); } - drawPrimitive(iface, PrimitiveType, primCount, NumVertices, startIndex, - idxStride, vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex); + drawPrimitive(iface, index_count, NumVertices, startIndex, idxStride, + vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex); return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, - UINT PrimitiveCount, CONST void* pVertexStreamZeroData, - UINT VertexStreamZeroStride) { +static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface, UINT vertex_count, + const void *pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DVertexBuffer *vb; + IWineD3DBuffer *vb; - TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, - debug_d3dprimitivetype(PrimitiveType), - PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + TRACE("(%p) : vertex count %u, pVtxData %p, stride %u\n", + This, vertex_count, pVertexStreamZeroData, VertexStreamZeroStride); if(!This->stateBlock->vertexDecl) { WARN("(%p) : Called without a valid vertex declaration set\n", This); @@ -5402,8 +5512,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface, /* Note in the following, it's not this type, but that's the purpose of streamIsUP */ vb = This->stateBlock->streamSource[0]; - This->stateBlock->streamSource[0] = (IWineD3DVertexBuffer *)pVertexStreamZeroData; - if(vb) IWineD3DVertexBuffer_Release(vb); + This->stateBlock->streamSource[0] = (IWineD3DBuffer *)pVertexStreamZeroData; + if (vb) IWineD3DBuffer_Release(vb); This->stateBlock->streamOffset[0] = 0; This->stateBlock->streamStride[0] = VertexStreamZeroStride; This->stateBlock->streamIsUP = TRUE; @@ -5412,8 +5522,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface, /* TODO: Only mark dirty if drawing from a different UP address */ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC); - drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* NumVertices */, - 0 /* start_idx */, 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */); + drawPrimitive(iface, vertex_count, 0 /* NumVertices */, 0 /* start_idx */, + 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */); /* MSDN specifies stream zero settings must be set to NULL */ This->stateBlock->streamStride[0] = 0; @@ -5425,20 +5535,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface, return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, - UINT MinVertexIndex, UINT NumVertices, - UINT PrimitiveCount, CONST void* pIndexData, - WINED3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData, - UINT VertexStreamZeroStride) { +static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *iface, UINT MinVertexIndex, + UINT NumVertices, UINT index_count, const void *pIndexData, WINED3DFORMAT IndexDataFormat, + const void *pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ int idxStride; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DVertexBuffer *vb; + IWineD3DBuffer *vb; IWineD3DIndexBuffer *ib; - TRACE("(%p) : Type=(%d,%s), MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", - This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), - MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, - IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride); + TRACE("(%p) : MinVtxIdx %u, NumVIdx %u, index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u\n", + This, MinVertexIndex, NumVertices, index_count, pIndexData, + IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride); if(!This->stateBlock->vertexDecl) { WARN("(%p) : Called without a valid vertex declaration set\n", This); @@ -5453,8 +5561,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice * /* Note in the following, it's not this type, but that's the purpose of streamIsUP */ vb = This->stateBlock->streamSource[0]; - This->stateBlock->streamSource[0] = (IWineD3DVertexBuffer *)pVertexStreamZeroData; - if(vb) IWineD3DVertexBuffer_Release(vb); + This->stateBlock->streamSource[0] = (IWineD3DBuffer *)pVertexStreamZeroData; + if (vb) IWineD3DBuffer_Release(vb); This->stateBlock->streamIsUP = TRUE; This->stateBlock->streamOffset[0] = 0; This->stateBlock->streamStride[0] = VertexStreamZeroStride; @@ -5466,7 +5574,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice * IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); - drawPrimitive(iface, PrimitiveType, PrimitiveCount, NumVertices, 0 /* start_idx */, idxStride, pIndexData, MinVertexIndex); + drawPrimitive(iface, index_count, NumVertices, 0 /* start_idx */, + idxStride, pIndexData, MinVertexIndex); /* MSDN specifies stream zero settings and index buffer must be set to NULL */ This->stateBlock->streamSource[0] = NULL; @@ -5484,8 +5593,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice * } static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided(IWineD3DDevice *iface, - WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, - const WineDirect3DVertexStridedData *DrawPrimStrideData) + UINT vertex_count, const WineDirect3DVertexStridedData *DrawPrimStrideData) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; @@ -5497,15 +5605,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided(IWineD3DDevice *if IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); This->stateBlock->baseVertexIndex = 0; This->up_strided = DrawPrimStrideData; - drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, NULL, 0); + drawPrimitive(iface, vertex_count, 0, 0, 0, NULL, 0); This->up_strided = NULL; return WINED3D_OK; } static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDevice *iface, - WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, - const WineDirect3DVertexStridedData *DrawPrimStrideData, UINT NumVertices, const void *pIndexData, - WINED3DFORMAT IndexDataFormat) + UINT vertex_count, const WineDirect3DVertexStridedData *DrawPrimStrideData, + UINT NumVertices, const void *pIndexData, WINED3DFORMAT IndexDataFormat) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; DWORD idxSize = (IndexDataFormat == WINED3DFMT_R32_UINT ? 4 : 2); @@ -5519,7 +5626,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDev This->stateBlock->streamIsUP = TRUE; This->stateBlock->baseVertexIndex = 0; This->up_strided = DrawPrimStrideData; - drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* numindices */, 0 /* start_idx */, idxSize, pIndexData, 0 /* minindex */); + drawPrimitive(iface, vertex_count, 0 /* numindices */, 0 /* start_idx */, idxSize, pIndexData, 0 /* minindex */); This->up_strided = NULL; return WINED3D_OK; } @@ -6095,6 +6202,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_DrawRectPatch(IWineD3DDevice *iface, UINT Handle, CONST float* pNumSegs, CONST WINED3DRECTPATCH_INFO* pRectPatchInfo) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct WineD3DRectPatch *patch; + GLenum old_primitive_type; unsigned int i; struct list *e; BOOL found; @@ -6164,7 +6272,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawRectPatch(IWineD3DDevice *iface, UI } This->currentPatch = patch; - IWineD3DDevice_DrawPrimitiveStrided(iface, WINED3DPT_TRIANGLELIST, patch->numSegs[0] * patch->numSegs[1] * 2, &patch->strided); + old_primitive_type = This->stateBlock->gl_primitive_type; + This->stateBlock->gl_primitive_type = GL_TRIANGLES; + IWineD3DDevice_DrawPrimitiveStrided(iface, patch->numSegs[0] * patch->numSegs[1] * 2, &patch->strided); + This->stateBlock->gl_primitive_type = old_primitive_type; This->currentPatch = NULL; /* Destroy uncached patches */ @@ -7768,6 +7879,8 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_Clear, IWineD3DDeviceImpl_ClearRendertargetView, /*** Drawing ***/ + IWineD3DDeviceImpl_SetPrimitiveType, + IWineD3DDeviceImpl_GetPrimitiveType, IWineD3DDeviceImpl_DrawPrimitive, IWineD3DDeviceImpl_DrawIndexedPrimitive, IWineD3DDeviceImpl_DrawPrimitiveUP, diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 66eec6bf1b8..45fd633fd63 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -64,6 +64,7 @@ static const struct { {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS, 0 }, {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM, 0 }, {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER, 0 }, + {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4, 0 }, {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL, 0 }, {"GL_ARB_imaging", ARB_IMAGING, 0 }, {"GL_ARB_multisample", ARB_MULTISAMPLE, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */ diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 37f43b4a3b2..804e65bdd01 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -32,58 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); #include #include -/* Issues the glBegin call for gl given the primitive type and count */ -static DWORD primitiveToGl(WINED3DPRIMITIVETYPE PrimitiveType, - DWORD NumPrimitives, - GLenum *primType) -{ - DWORD NumVertexes = NumPrimitives; - - switch (PrimitiveType) { - case WINED3DPT_POINTLIST: - TRACE("POINTS\n"); - *primType = GL_POINTS; - NumVertexes = NumPrimitives; - break; - - case WINED3DPT_LINELIST: - TRACE("LINES\n"); - *primType = GL_LINES; - NumVertexes = NumPrimitives * 2; - break; - - case WINED3DPT_LINESTRIP: - TRACE("LINE_STRIP\n"); - *primType = GL_LINE_STRIP; - NumVertexes = NumPrimitives + 1; - break; - - case WINED3DPT_TRIANGLELIST: - TRACE("TRIANGLES\n"); - *primType = GL_TRIANGLES; - NumVertexes = NumPrimitives * 3; - break; - - case WINED3DPT_TRIANGLESTRIP: - TRACE("TRIANGLE_STRIP\n"); - *primType = GL_TRIANGLE_STRIP; - NumVertexes = NumPrimitives + 2; - break; - - case WINED3DPT_TRIANGLEFAN: - TRACE("TRIANGLE_FAN\n"); - *primType = GL_TRIANGLE_FAN; - NumVertexes = NumPrimitives + 2; - break; - - default: - FIXME("Unhandled primitive\n"); - *primType = GL_POINTS; - break; - } - return NumVertexes; -} - static BOOL fixed_get_input( BYTE usage, BYTE usage_idx, unsigned int* regnum) { @@ -160,7 +108,7 @@ void primitiveDeclarationConvertToStridedData( /* Translate the declaration into strided data */ strided->swizzle_map = 0; for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) { - GLint streamVBO = 0; + GLuint streamVBO = 0; BOOL stride_used; unsigned int idx; @@ -178,7 +126,7 @@ void primitiveDeclarationConvertToStridedData( data = (BYTE *)This->stateBlock->streamSource[element->Stream]; } else { TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); - data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO); + data = buffer_get_memory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO); /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory @@ -189,7 +137,7 @@ void primitiveDeclarationConvertToStridedData( if(This->stateBlock->loadBaseVertexIndex < 0) { WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); streamVBO = 0; - data = ((IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory; + data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory; if((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) { FIXME("System memory vertex data load offset is negative!\n"); } @@ -252,15 +200,15 @@ void primitiveDeclarationConvertToStridedData( * once in there. */ for(i=0; i < numPreloadStreams; i++) { - IWineD3DVertexBuffer *vb = This->stateBlock->streamSource[streams[i]]; + IWineD3DBuffer *vb = This->stateBlock->streamSource[streams[i]]; if(vb) { - IWineD3DVertexBuffer_PreLoad(vb); + IWineD3DBuffer_PreLoad(vb); } } } static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, - UINT min_vertex_idx, UINT max_vertex_idx, UINT count, short idx_size, + UINT min_vertex_idx, UINT max_vertex_idx, UINT count, UINT idx_size, const void *idx_data, UINT start_idx) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; @@ -296,12 +244,12 @@ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, */ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT NumVertexes, - GLenum glPrimType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) + GLenum glPrimType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { unsigned int textureNo = 0; const WORD *pIdxBufS = NULL; const DWORD *pIdxBufL = NULL; - ULONG vx_index; + UINT vx_index; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const UINT *streamOffset = This->stateBlock->streamOffset; long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; @@ -616,13 +564,13 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co } static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT numberOfVertices, - GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) + GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; const WORD *pIdxBufS = NULL; const DWORD *pIdxBufL = NULL; - ULONG vx_index; + UINT vx_index; int i; IWineD3DStateBlockImpl *stateblock = This->stateBlock; const BYTE *ptr; @@ -676,8 +624,8 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStr } static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, - UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex, - ULONG startIdx) + UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, + UINT startIdx) { UINT numInstances = 0, i; int numInstancedAttribs = 0, j; @@ -727,7 +675,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3 sd->u.input[instancedData[j]].dwStride * i + stateblock->streamOffset[sd->u.input[instancedData[j]].streamNo]; if(sd->u.input[instancedData[j]].VBO) { - IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[sd->u.input[instancedData[j]].streamNo]; + struct wined3d_buffer *vb = (struct wined3d_buffer *)stateblock->streamSource[sd->u.input[instancedData[j]].streamNo]; ptr += (long) vb->resource.allocatedMemory; } @@ -742,102 +690,102 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3 static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStridedData *s) { unsigned char i; - IWineD3DVertexBufferImpl *vb; + struct wined3d_buffer *vb; if(s->u.s.position.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.position.streamNo]; s->u.s.position.VBO = 0; s->u.s.position.lpData = (BYTE *) ((unsigned long) s->u.s.position.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.blendWeights.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendWeights.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.blendWeights.streamNo]; s->u.s.blendWeights.VBO = 0; s->u.s.blendWeights.lpData = (BYTE *) ((unsigned long) s->u.s.blendWeights.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.blendMatrixIndices.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendMatrixIndices.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.blendMatrixIndices.streamNo]; s->u.s.blendMatrixIndices.VBO = 0; s->u.s.blendMatrixIndices.lpData = (BYTE *) ((unsigned long) s->u.s.blendMatrixIndices.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.normal.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.normal.streamNo]; s->u.s.normal.VBO = 0; s->u.s.normal.lpData = (BYTE *) ((unsigned long) s->u.s.normal.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.pSize.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.pSize.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.pSize.streamNo]; s->u.s.pSize.VBO = 0; s->u.s.pSize.lpData = (BYTE *) ((unsigned long) s->u.s.pSize.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.diffuse.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.diffuse.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.diffuse.streamNo]; s->u.s.diffuse.VBO = 0; s->u.s.diffuse.lpData = (BYTE *) ((unsigned long) s->u.s.diffuse.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.specular.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.specular.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.specular.streamNo]; s->u.s.specular.VBO = 0; s->u.s.specular.lpData = (BYTE *) ((unsigned long) s->u.s.specular.lpData + (unsigned long) vb->resource.allocatedMemory); } for(i = 0; i < WINED3DDP_MAXTEXCOORD; i++) { if(s->u.s.texCoords[i].VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.texCoords[i].streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.texCoords[i].streamNo]; s->u.s.texCoords[i].VBO = 0; s->u.s.texCoords[i].lpData = (BYTE *) ((unsigned long) s->u.s.texCoords[i].lpData + (unsigned long) vb->resource.allocatedMemory); } } if(s->u.s.position2.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position2.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.position2.streamNo]; s->u.s.position2.VBO = 0; s->u.s.position2.lpData = (BYTE *) ((unsigned long) s->u.s.position2.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.normal2.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal2.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.normal2.streamNo]; s->u.s.normal2.VBO = 0; s->u.s.normal2.lpData = (BYTE *) ((unsigned long) s->u.s.normal2.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.tangent.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tangent.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.tangent.streamNo]; s->u.s.tangent.VBO = 0; s->u.s.tangent.lpData = (BYTE *) ((unsigned long) s->u.s.tangent.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.binormal.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.binormal.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.binormal.streamNo]; s->u.s.binormal.VBO = 0; s->u.s.binormal.lpData = (BYTE *) ((unsigned long) s->u.s.binormal.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.tessFactor.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tessFactor.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.tessFactor.streamNo]; s->u.s.tessFactor.VBO = 0; s->u.s.tessFactor.lpData = (BYTE *) ((unsigned long) s->u.s.tessFactor.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.fog.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.fog.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.fog.streamNo]; s->u.s.fog.VBO = 0; s->u.s.fog.lpData = (BYTE *) ((unsigned long) s->u.s.fog.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.depth.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.depth.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.depth.streamNo]; s->u.s.depth.VBO = 0; s->u.s.depth.lpData = (BYTE *) ((unsigned long) s->u.s.depth.lpData + (unsigned long) vb->resource.allocatedMemory); } if(s->u.s.sample.VBO) { - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.sample.streamNo]; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.sample.streamNo]; s->u.s.sample.VBO = 0; s->u.s.sample.lpData = (BYTE *) ((unsigned long) s->u.s.sample.lpData + (unsigned long) vb->resource.allocatedMemory); } } /* Routine common to the draw primitive and draw indexed primitive routines */ -void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives, - UINT numberOfVertices, long StartIdx, short idxSize, const void *idxData, int minIndex) +void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertices, + UINT StartIdx, UINT idxSize, const void *idxData, UINT minIndex) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DSurfaceImpl *target; unsigned int i; - if (NumPrimitives == 0) return; + if (!index_count) return; /* Invalidate the back buffer memory so LockRect will read it the next time */ for(i = 0; i < GL_LIMITS(buffers); i++) { @@ -864,15 +812,12 @@ void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives, /* Ok, we will be updating the screen from here onwards so grab the lock */ ENTER_GL(); { - GLenum glPrimType; + GLenum glPrimType = This->stateBlock->gl_primitive_type; BOOL emulation = FALSE; const WineDirect3DVertexStridedData *strided = &This->strided_streams; WineDirect3DVertexStridedData stridedlcl; - /* Ok, Work out which primitive is requested and how many vertexes that - will be */ - UINT calculatedNumberOfindices = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType); - if (numberOfVertices == 0 ) - numberOfVertices = calculatedNumberOfindices; + + if (!numberOfVertices) numberOfVertices = index_count; if (!use_vs(This->stateBlock)) { @@ -920,19 +865,17 @@ void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives, } else { TRACE("Using immediate mode with vertex shaders for half float emulation\n"); } - drawStridedSlowVs(iface, strided, calculatedNumberOfindices, - glPrimType, idxData, idxSize, minIndex, StartIdx); + drawStridedSlowVs(iface, strided, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx); } else { - drawStridedSlow(iface, strided, calculatedNumberOfindices, - glPrimType, idxData, idxSize, minIndex, StartIdx); + drawStridedSlow(iface, strided, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx); } } else if(This->instancedDraw) { /* Instancing emulation with mixing immediate mode and arrays */ - drawStridedInstanced(iface, &This->strided_streams, calculatedNumberOfindices, glPrimType, - idxData, idxSize, minIndex, StartIdx); + drawStridedInstanced(iface, &This->strided_streams, index_count, + glPrimType, idxData, idxSize, minIndex, StartIdx); } else { drawStridedFast(iface, glPrimType, minIndex, minIndex + numberOfVertices - 1, - calculatedNumberOfindices, idxSize, idxData, StartIdx); + index_count, idxSize, idxData, StartIdx); } } @@ -1032,8 +975,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, memset(&strided, 0, sizeof(strided)); primitiveDeclarationConvertToStridedData((IWineD3DDevice *) This, FALSE, &strided, NULL); if(strided.u.s.position.VBO) { - IWineD3DVertexBufferImpl *vb; - vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[strided.u.s.position.streamNo]; + struct wined3d_buffer *vb; + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[strided.u.s.position.streamNo]; strided.u.s.position.lpData = (BYTE *) ((unsigned long) strided.u.s.position.lpData + (unsigned long) vb->resource.allocatedMemory); } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 20e8df0eca3..88c78d25525 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -40,6 +40,10 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); #define GLINFO_LOCATION (*gl_info) +#define WINED3D_GLSL_SAMPLE_PROJECTED 0x1 +#define WINED3D_GLSL_SAMPLE_RECT 0x2 +#define WINED3D_GLSL_SAMPLE_LOD 0x4 + typedef struct { char reg_name[150]; char mask_str[6]; @@ -185,8 +189,9 @@ static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, IWineD3DS snprintf(sampler_name, sizeof(sampler_name), "Psampler%d", i); name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name)); if (name_loc != -1) { - int mapped_unit = stateBlock->wineD3DDevice->texUnitMap[i]; - if (mapped_unit != -1 && mapped_unit < GL_LIMITS(fragment_samplers)) { + DWORD mapped_unit = stateBlock->wineD3DDevice->texUnitMap[i]; + if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < GL_LIMITS(fragment_samplers)) + { TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit); GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit)); checkGLcall("glUniform1iARB"); @@ -208,8 +213,9 @@ static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, IWineD3DS snprintf(sampler_name, sizeof(sampler_name), "Vsampler%d", i); name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name)); if (name_loc != -1) { - int mapped_unit = stateBlock->wineD3DDevice->texUnitMap[MAX_FRAGMENT_SAMPLERS + i]; - if (mapped_unit != -1 && mapped_unit < GL_LIMITS(combined_samplers)) { + DWORD mapped_unit = stateBlock->wineD3DDevice->texUnitMap[MAX_FRAGMENT_SAMPLERS + i]; + if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < GL_LIMITS(combined_samplers)) + { TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit); GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit)); checkGLcall("glUniform1iARB"); @@ -1300,7 +1306,12 @@ static inline const char* shader_get_comp_op( } } -static void shader_glsl_get_sample_function(DWORD sampler_type, BOOL projected, BOOL texrect, BOOL lod, glsl_sample_function_t *sample_function) { +static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function) +{ + BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; + BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT; + BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD; + /* Note that there's no such thing as a projected cube texture. */ switch(sampler_type) { case WINED3DSTT_1D: @@ -2308,9 +2319,9 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; DWORD shader_version = arg->reg_maps->shader_version; glsl_sample_function_t sample_function; + DWORD sample_flags = 0; DWORD sampler_type; DWORD sampler_idx; - BOOL projected, texrect = FALSE; DWORD mask = 0, swizzle; /* 1.0-1.4: Use destination register as sampler source. @@ -2325,7 +2336,7 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ if (flags & WINED3DTTFF_PROJECTED && sampler_type != WINED3DSTT_CUBE) { - projected = TRUE; + sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; switch (flags & ~WINED3DTTFF_PROJECTED) { case WINED3DTTFF_COUNT1: FIXME("WINED3DTTFF_PROJECTED with WINED3DTTFF_COUNT1?\n"); break; case WINED3DTTFF_COUNT2: mask = WINED3DSP_WRITEMASK_1; break; @@ -2333,8 +2344,6 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) case WINED3DTTFF_COUNT4: case WINED3DTTFF_DISABLE: mask = WINED3DSP_WRITEMASK_3; break; } - } else { - projected = FALSE; } } else if (shader_version < WINED3DPS_VERSION(2,0)) @@ -2342,30 +2351,26 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg) DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK; if (src_mod == WINED3DSPSM_DZ) { - projected = TRUE; + sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; mask = WINED3DSP_WRITEMASK_2; } else if (src_mod == WINED3DSPSM_DW) { - projected = TRUE; + sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; mask = WINED3DSP_WRITEMASK_3; - } else { - projected = FALSE; } } else { if(arg->opcode_token & WINED3DSI_TEXLD_PROJECT) { - /* ps 2.0 texldp instruction always divides by the fourth component. */ - projected = TRUE; - mask = WINED3DSP_WRITEMASK_3; - } else { - projected = FALSE; + /* ps 2.0 texldp instruction always divides by the fourth component. */ + sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; + mask = WINED3DSP_WRITEMASK_3; } } if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { - texrect = TRUE; + sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(sampler_type, projected, texrect, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function); mask |= sample_function.coord_mask; if (shader_version < WINED3DPS_VERSION(2,0)) swizzle = WINED3DVS_NOSWIZZLE; @@ -2400,9 +2405,9 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg) IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; glsl_sample_function_t sample_function; glsl_src_param_t coord_param, lod_param; + DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD; DWORD sampler_type; DWORD sampler_idx; - BOOL texrect = FALSE; DWORD swizzle = arg->src[1] & WINED3DSP_SWIZZLE_MASK; shader_glsl_append_dst(arg->buffer, arg); @@ -2411,9 +2416,9 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg) sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { - texrect = TRUE; + sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(sampler_type, FALSE, texrect, TRUE, &sample_function); + shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param); @@ -2487,6 +2492,7 @@ static void pshader_glsl_texdp3tex(const SHADER_OPCODE_ARG *arg) DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; DWORD sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; + UINT mask_size; shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], src_mask, &src0_param); @@ -2495,9 +2501,11 @@ static void pshader_glsl_texdp3tex(const SHADER_OPCODE_ARG *arg) * * It is a dependent read - not valid with conditional NP2 textures */ - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); + mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask); - switch(count_bits(sample_function.coord_mask)) { + switch(mask_size) + { case 1: sprintf(coord_param, "dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str); @@ -2512,8 +2520,10 @@ static void pshader_glsl_texdp3tex(const SHADER_OPCODE_ARG *arg) sprintf(coord_param, "vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str); break; + default: - FIXME("Unexpected mask bitcount %d\n", count_bits(sample_function.coord_mask)); + FIXME("Unexpected mask size %u\n", mask_size); + break; } shader_glsl_gen_sample_code(arg, sampler_idx, coord_param, &sample_function, WINED3DVS_NOSWIZZLE, @@ -2616,7 +2626,7 @@ static void pshader_glsl_texm3x2tex(const SHADER_OPCODE_ARG *arg) shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], src_mask, &src0_param); shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(arg, reg, "tmp0.xy", @@ -2640,7 +2650,7 @@ static void pshader_glsl_texm3x3tex(const SHADER_OPCODE_ARG *arg) shader_addline(arg->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(arg, reg, "tmp0.xyz", @@ -2693,7 +2703,7 @@ static void pshader_glsl_texm3x3spec(const SHADER_OPCODE_ARG *arg) shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(stype, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(stype, 0, &sample_function); /* Sample the texture */ shader_glsl_gen_sample_code(arg, reg, "tmp0.xyz", @@ -2727,7 +2737,7 @@ static void pshader_glsl_texm3x3vspec(const SHADER_OPCODE_ARG *arg) shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n"); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(arg, reg, "tmp0.xyz", @@ -2759,7 +2769,7 @@ static void pshader_glsl_texbem(const SHADER_OPCODE_ARG *arg) sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); mask = sample_function.coord_mask; shader_glsl_get_write_mask(mask, coord_mask); @@ -2827,7 +2837,7 @@ static void pshader_glsl_texreg2ar(const SHADER_OPCODE_ARG *arg) shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); sprintf(src, "%s.wx", src0_param.reg_name); shader_glsl_gen_sample_code(arg, sampler_idx, src, &sample_function, WINED3DVS_NOSWIZZLE, @@ -2846,7 +2856,7 @@ static void pshader_glsl_texreg2gb(const SHADER_OPCODE_ARG *arg) shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); sprintf(src, "%s.yz", src0_param.reg_name); shader_glsl_gen_sample_code(arg, sampler_idx, src, &sample_function, WINED3DVS_NOSWIZZLE, @@ -2863,7 +2873,7 @@ static void pshader_glsl_texreg2rgb(const SHADER_OPCODE_ARG *arg) glsl_sample_function_t sample_function; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, 0, &sample_function); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &src0_param); shader_glsl_gen_sample_code(arg, sampler_idx, src0_param.param_str, diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index fc727d670a9..f7e331de3d4 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -462,7 +462,8 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage); - if (mapped_stage != -1) { + if (mapped_stage != WINED3D_UNMAPPED_STAGE) + { if (tex_used && mapped_stage >= GL_LIMITS(textures)) { FIXME("Attempt to enable unsupported stage!\n"); return; @@ -479,7 +480,8 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3 } if(stage >= stateblock->lowest_disabled_stage) { TRACE("Stage disabled\n"); - if (mapped_stage != -1) { + if (mapped_stage != WINED3D_UNMAPPED_STAGE) + { /* Disable everything here */ glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); @@ -548,7 +550,7 @@ static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop * will take care of this business */ - if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return; + if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return; if(sampler >= stateblock->lowest_disabled_stage) return; if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 6b36a3df168..c8f252f563f 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -2852,7 +2852,8 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage); - if (mapped_stage != -1) { + if (mapped_stage != WINED3D_UNMAPPED_STAGE) + { if (tex_used && mapped_stage >= GL_LIMITS(textures)) { FIXME("Attempt to enable unsupported stage!\n"); return; @@ -2863,7 +2864,8 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D if(stage >= stateblock->lowest_disabled_stage) { TRACE("Stage disabled\n"); - if (mapped_stage != -1) { + if (mapped_stage != WINED3D_UNMAPPED_STAGE) + { /* Disable everything here */ glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); @@ -2904,7 +2906,8 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext TRACE("Setting alpha op for stage %d\n", stage); /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */ - if (mapped_stage != -1) { + if (mapped_stage != WINED3D_UNMAPPED_STAGE) + { if (tex_used && mapped_stage >= GL_LIMITS(textures)) { FIXME("Attempt to enable unsupported stage!\n"); return; @@ -3008,7 +3011,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W return; } - if (mapped_stage == -1) return; + if (mapped_stage == WINED3D_UNMAPPED_STAGE) return; if(mapped_stage >= GL_LIMITS(textures)) { return; @@ -3047,7 +3050,7 @@ static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) { } } -static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3DVertexStridedData *sd, GLint *curVBO) +static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3DVertexStridedData *sd, GLuint *curVBO) { const UINT *offset = stateblock->streamOffset; unsigned int mapped_stage = 0; @@ -3057,7 +3060,7 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3D int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX]; mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo]; - if (mapped_stage == -1) continue; + if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; if (coordIdx < MAX_TEXTURES && (sd->u.s.texCoords[coordIdx].lpData || sd->u.s.texCoords[coordIdx].VBO)) { TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n", @@ -3101,7 +3104,8 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine static const GLfloat r_plane[] = { 0.0, 0.0, 1.0, 0.0 }; static const GLfloat q_plane[] = { 0.0, 0.0, 0.0, 1.0 }; - if (mapped_stage == -1) { + if (mapped_stage == WINED3D_UNMAPPED_STAGE) + { TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage); return; } @@ -3251,7 +3255,7 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine * and do all the things linked to it * TODO: Tidy that up to reload only the arrays of the changed unit */ - GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0; + GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0; unloadTexCoords(stateblock); loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO); @@ -3341,7 +3345,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont * only has to bind textures and set the per texture states */ - if (mapped_stage == -1) { + if (mapped_stage == WINED3D_UNMAPPED_STAGE) + { TRACE("No sampler mapped to stage %d. Returning.\n", sampler); return; } @@ -3839,10 +3844,10 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, Wine static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, const WineDirect3DVertexStridedData *strided, WineD3DContext *context) { - GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0; + GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0; int i; const UINT *offset = stateblock->streamOffset; - IWineD3DVertexBufferImpl *vb; + struct wined3d_buffer *vb; DWORD_PTR shift_index; /* Default to no instancing */ @@ -3870,27 +3875,28 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, checkGLcall("glBindBufferARB"); curVBO = strided->u.input[i].VBO; } - vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo]; + vb = (struct wined3d_buffer *)stateblock->streamSource[strided->u.input[i].streamNo]; /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no * vbo we won't be load converted attributes anyway */ - if(curVBO && vb->conv_shift) { + if (curVBO && vb->conversion_shift) + { TRACE("Loading attribute from shifted buffer\n"); - TRACE("Attrib %d has original stride %d, new stride %d\n", i, strided->u.input[i].dwStride, vb->conv_stride); - TRACE("Original offset %p, additional offset 0x%08x\n",strided->u.input[i].lpData, vb->conv_shift[(DWORD_PTR) strided->u.input[i].lpData]); + TRACE("Attrib %d has original stride %d, new stride %d\n", + i, strided->u.input[i].dwStride, vb->conversion_stride); + TRACE("Original offset %p, additional offset 0x%08x\n", + strided->u.input[i].lpData, vb->conversion_shift[(DWORD_PTR) strided->u.input[i].lpData]); TRACE("Opengl type %x\n", WINED3D_ATR_GLTYPE(strided->u.input[i].dwType)); shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]); shift_index = shift_index % strided->u.input[i].dwStride; - GL_EXTCALL(glVertexAttribPointerARB(i, - WINED3D_ATR_FORMAT(strided->u.input[i].dwType), - WINED3D_ATR_GLTYPE(strided->u.input[i].dwType), - WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType), - vb->conv_stride, - - strided->u.input[i].lpData + vb->conv_shift[shift_index] + - stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + - offset[strided->u.input[i].streamNo])); + GL_EXTCALL(glVertexAttribPointerARB(i, WINED3D_ATR_FORMAT(strided->u.input[i].dwType), + WINED3D_ATR_GLTYPE(strided->u.input[i].dwType), + WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType), + vb->conversion_stride, + strided->u.input[i].lpData + vb->conversion_shift[shift_index] + + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + + offset[strided->u.input[i].streamNo])); } else { GL_EXTCALL(glVertexAttribPointerARB(i, @@ -3915,7 +3921,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, */ const BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]; if(strided->u.input[i].VBO) { - vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo]; + vb = (struct wined3d_buffer *)stateblock->streamSource[strided->u.input[i].streamNo]; ptr += (long) vb->resource.allocatedMemory; } @@ -4013,7 +4019,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3DVertexStridedData *sd) { const UINT *offset = stateblock->streamOffset; - GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0; + GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0; TRACE("Using fast vertex array code\n"); diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index e1f1dd8eab3..cbf5f97bc8d 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -77,6 +77,7 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES * unsigned bsize = sizeof(BOOL); /* Single values */ + dest->primitive_type = source->primitive_type; dest->indices = source->indices; dest->material = source->material; dest->viewport = source->viewport; @@ -121,6 +122,7 @@ void stateblock_savedstates_set( unsigned bsize = sizeof(BOOL); /* Single values */ + states->primitive_type = value; states->indices = value; states->material = value; states->viewport = value; @@ -188,6 +190,7 @@ void stateblock_copy( stateblock_savedstates_copy(source, &Dest->changed, &This->changed); /* Single items */ + Dest->gl_primitive_type = This->gl_primitive_type; Dest->vertexDecl = This->vertexDecl; Dest->vertexShader = This->vertexShader; Dest->streamIsUP = This->streamIsUP; @@ -227,7 +230,7 @@ void stateblock_copy( memcpy(Dest->streamStride, This->streamStride, sizeof(UINT) * MAX_STREAMS); memcpy(Dest->streamOffset, This->streamOffset, sizeof(UINT) * MAX_STREAMS); - memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DVertexBuffer*) * MAX_STREAMS); + memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DBuffer *) * MAX_STREAMS); memcpy(Dest->streamFreq, This->streamFreq, sizeof(UINT) * MAX_STREAMS); memcpy(Dest->streamFlags, This->streamFlags, sizeof(UINT) * MAX_STREAMS); memcpy(Dest->transforms, This->transforms, sizeof(WINED3DMATRIX) * (HIGHEST_TRANSFORMSTATE + 1)); @@ -292,7 +295,8 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { for (counter = 0; counter < MAX_STREAMS; counter++) { if(This->streamSource[counter]) { - if(0 != IWineD3DVertexBuffer_Release(This->streamSource[counter])) { + if (IWineD3DBuffer_Release(This->streamSource[counter])) + { TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]); } } @@ -499,6 +503,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) targetStateBlock->transforms[This->contained_transform_states[i]]; } + if (This->changed.primitive_type) This->gl_primitive_type = targetStateBlock->gl_primitive_type; + if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData) || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) { TRACE("Updating pIndexData to %p, baseVertexIndex to %d\n", @@ -548,8 +554,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) TRACE("Updating stream source %u to %p, stride to %u\n", i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]); This->streamStride[i] = targetStateBlock->streamStride[i]; - if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]); - if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]); + if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]); + if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]); This->streamSource[i] = targetStateBlock->streamSource[i]; } } @@ -628,6 +634,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI)); memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF)); memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4); + This->gl_primitive_type = targetStateBlock->gl_primitive_type; memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride)); memcpy(This->streamOffset, targetStateBlock->streamOffset, sizeof(This->streamOffset)); memcpy(This->streamFreq, targetStateBlock->streamFreq, sizeof(This->streamFreq)); @@ -649,14 +656,14 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) This->scissorRect = targetStateBlock->scissorRect; if(targetStateBlock->pIndexData != This->pIndexData) { - if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData); - if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData); + if (targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData); + if (This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData); This->pIndexData = targetStateBlock->pIndexData; } for(i = 0; i < MAX_STREAMS; i++) { if(targetStateBlock->streamSource[i] != This->streamSource[i]) { - if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]); - if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]); + if(targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]); + if(This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]); This->streamSource[i] = targetStateBlock->streamSource[i]; } } @@ -690,8 +697,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) } for(i = 0; i < MAX_STREAMS; i++) { if(targetStateBlock->streamSource[i] != This->streamSource[i]) { - if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]); - if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]); + if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]); + if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]); This->streamSource[i] = targetStateBlock->streamSource[i]; } } @@ -827,6 +834,12 @@ should really perform a delta so that only the changes get updated*/ &This->transforms[This->contained_transform_states[i]]); } + if (This->changed.primitive_type) + { + This->wineD3DDevice->updateStateBlock->changed.primitive_type = TRUE; + This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type; + } + if (This->changed.indices) { IWineD3DDevice_SetIndices(pDevice, This->pIndexData); IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); @@ -1009,6 +1022,7 @@ should really perform a delta so that only the changes get updated*/ for(i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) { IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]); } + This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type; IWineD3DDevice_SetIndices(pDevice, This->pIndexData); IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl); diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 87bfac63162..6d19010332b 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -918,12 +918,17 @@ const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) { const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) { switch (PrimitiveType) { #define PRIM_TO_STR(prim) case prim: return #prim + PRIM_TO_STR(WINED3DPT_UNDEFINED); PRIM_TO_STR(WINED3DPT_POINTLIST); PRIM_TO_STR(WINED3DPT_LINELIST); PRIM_TO_STR(WINED3DPT_LINESTRIP); PRIM_TO_STR(WINED3DPT_TRIANGLELIST); PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP); PRIM_TO_STR(WINED3DPT_TRIANGLEFAN); + PRIM_TO_STR(WINED3DPT_LINELIST_ADJ); + PRIM_TO_STR(WINED3DPT_LINESTRIP_ADJ); + PRIM_TO_STR(WINED3DPT_TRIANGLELIST_ADJ); + PRIM_TO_STR(WINED3DPT_TRIANGLESTRIP_ADJ); #undef PRIM_TO_STR default: FIXME("Unrecognized %u WINED3DPRIMITIVETYPE!\n", PrimitiveType); @@ -2380,7 +2385,7 @@ void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop * will take care of this business */ - if(mapped_stage == -1 || mapped_stage >= GL_LIMITS(textures)) return; + if(mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= GL_LIMITS(textures)) return; if(sampler >= stateblock->lowest_disabled_stage) return; if(isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return; diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index dd3946ea9b7..d0529dfa8df 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -1550,6 +1550,37 @@ typedef void (WINE_GLAPI *PGLFNCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); #endif typedef void (WINE_GLAPI *PGLFNDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +/* GL_ARB_geometry_shader4 */ +#ifndef GL_ARB_geometry_shader4 +#define GL_GEOMETRY_SHADER_ARB 0x8dd9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8dda +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8ddb +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8ddc +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8c29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8ddd +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8dde +#define GL_MAX_VARYING_COMPONENTS_ARB 0x8b4b +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8ddf +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8de0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8de1 +#define GL_LINES_ADJACENCY_ARB 0x000a +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000b +#define GL_TRIANGLES_ADJACENCY_ARB 0x000c +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000d +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8da8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8da9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8da7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8cd4 +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#endif +typedef void (WINE_GLAPI *PGLFNPROGRAMPARAMETERIARBPROC)(GLuint program, GLenum pname, GLint value); +typedef void (WINE_GLAPI *PGLFNFRAMEBUFFERTEXTUREARBPROC)(GLenum target, GLenum attachment, + GLuint texture, GLint level); +typedef void (WINE_GLAPI *PGLFNFRAMEBUFFERTEXTURELAYERARBPROC)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLint layer); +typedef void (WINE_GLAPI *PGLFNFRAMEBUFFERTEXTUREFACEARBPROC)(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLenum face); + /* GL_ARB_imaging */ #ifndef GL_ARB_imaging #define GL_ARB_imaging 1 @@ -3335,6 +3366,7 @@ typedef enum _GL_SupportedExt { ARB_DRAW_BUFFERS, ARB_FRAGMENT_PROGRAM, ARB_FRAGMENT_SHADER, + ARB_GEOMETRY_SHADER4, ARB_IMAGING, ARB_MULTISAMPLE, ARB_MULTITEXTURE, @@ -3444,6 +3476,11 @@ typedef enum _GL_SupportedExt { USE_GL_FUNC(PGLFNCLAMPCOLORARBPROC, glClampColorARB, ARB_COLOR_BUFFER_FLOAT, NULL )\ /* GL_ARB_draw_buffers */ \ USE_GL_FUNC(PGLFNDRAWBUFFERSARBPROC, glDrawBuffersARB, ARB_DRAW_BUFFERS, NULL )\ + /* GL_ARB_geometry_shader4 */ \ + USE_GL_FUNC(PGLFNPROGRAMPARAMETERIARBPROC, glProgramParameteriARB, ARB_GEOMETRY_SHADER4, NULL ) \ + USE_GL_FUNC(PGLFNFRAMEBUFFERTEXTUREARBPROC, glFramebufferTextureARB, ARB_GEOMETRY_SHADER4, NULL ) \ + USE_GL_FUNC(PGLFNFRAMEBUFFERTEXTURELAYERARBPROC, glFramebufferTextureLayerARB, ARB_GEOMETRY_SHADER4, NULL ) \ + USE_GL_FUNC(PGLFNFRAMEBUFFERTEXTUREFACEARBPROC, glFramebufferTextureFaceARB, ARB_GEOMETRY_SHADER4, NULL ) \ /* GL_ARB_imaging, GL_EXT_blend_minmax */ \ USE_GL_FUNC(PGLFNBLENDCOLORPROC, glBlendColorEXT, EXT_BLEND_COLOR, NULL )\ USE_GL_FUNC(PGLFNBLENDEQUATIONPROC, glBlendEquationEXT, EXT_BLEND_MINMAX, NULL )\ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3c4e0ac3888..add283a9939 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -435,6 +435,8 @@ enum vertexprocessing_mode { pretransformed }; +#define WINED3D_CONST_NUM_UNUSED ~0U + struct stb_const_desc { char texunit; UINT const_num; @@ -653,8 +655,8 @@ extern LONG primCounter; */ /* Routine common to the draw primitive and draw indexed primitive routines */ -void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives, - UINT numberOfVertices, long start_idx, short idxBytes, const void *idxData, int minIndex); +void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertices, + UINT start_idx, UINT idxBytes, const void *idxData, UINT minIndex); void primitiveDeclarationConvertToStridedData( IWineD3DDevice *iface, @@ -1039,6 +1041,8 @@ void dumpResources(struct list *list); /***************************************************************************** * IWineD3DDevice implementation structure */ +#define WINED3D_UNMAPPED_STAGE ~0U + struct IWineD3DDeviceImpl { /* IUnknown fields */ @@ -1260,56 +1264,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, #define RESOURCE_ALIGNMENT 32 /***************************************************************************** - * IWineD3DVertexBuffer implementation structure (extends IWineD3DResourceImpl) - */ -enum vbo_conversion_type { - CONV_NONE = 0, - CONV_D3DCOLOR = 1, - CONV_POSITIONT = 2, - CONV_FLOAT16_2 = 3 /* Also handles FLOAT16_4 */ - - /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other - * fixed function semantics as D3DCOLOR or FLOAT16 - */ -}; - -typedef struct IWineD3DVertexBufferImpl -{ - /* IUnknown & WineD3DResource Information */ - const IWineD3DVertexBufferVtbl *lpVtbl; - IWineD3DResourceClass resource; - - /* WineD3DVertexBuffer specifics */ - DWORD fvf; - - /* Vertex buffer object support */ - GLuint vbo; - BYTE Flags; - LONG bindCount; - LONG vbo_size; - GLenum vbo_usage; - - UINT dirtystart, dirtyend; - LONG lockcount; - - LONG declChanges, draws; - /* Last description of the buffer */ - DWORD stride; /* 0 if no conversion */ - enum vbo_conversion_type *conv_map; /* NULL if no conversion */ - - /* Extra load offsets, for FLOAT16 conversion */ - DWORD *conv_shift; /* NULL if no shifted conversion */ - DWORD conv_stride; /* 0 if no shifted conversion */ -} IWineD3DVertexBufferImpl; - -extern const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl; - -#define VBFLAG_OPTIMIZED 0x01 /* Optimize has been called for the VB */ -#define VBFLAG_DIRTY 0x02 /* Buffer data has been modified */ -#define VBFLAG_HASDESC 0x04 /* A vertex description has been found */ -#define VBFLAG_CREATEVBO 0x08 /* Attempt to create a VBO next PreLoad */ - -/***************************************************************************** * IWineD3DIndexBuffer implementation structure (extends IWineD3DResourceImpl) */ typedef struct IWineD3DIndexBufferImpl @@ -1796,14 +1750,15 @@ typedef struct SAVEDSTATES { WORD vertexShaderConstantsB; /* MAX_CONST_B, 16 */ WORD vertexShaderConstantsI; /* MAX_CONST_I, 16 */ BOOL *vertexShaderConstantsF; - BYTE indices : 1; - BYTE material : 1; - BYTE viewport : 1; - BYTE vertexDecl : 1; - BYTE pixelShader : 1; - BYTE vertexShader : 1; - BYTE scissorRect : 1; - BYTE padding : 1; + WORD primitive_type : 1; + WORD indices : 1; + WORD material : 1; + WORD viewport : 1; + WORD vertexDecl : 1; + WORD pixelShader : 1; + WORD vertexShader : 1; + WORD scissorRect : 1; + WORD padding : 1; } SAVEDSTATES; struct StageState { @@ -1835,11 +1790,14 @@ struct IWineD3DStateBlockImpl INT vertexShaderConstantI[MAX_CONST_I * 4]; float *vertexShaderConstantF; + /* primitive type */ + GLenum gl_primitive_type; + /* Stream Source */ BOOL streamIsUP; UINT streamStride[MAX_STREAMS]; UINT streamOffset[MAX_STREAMS + 1 /* tesselated pseudo-stream */ ]; - IWineD3DVertexBuffer *streamSource[MAX_STREAMS]; + IWineD3DBuffer *streamSource[MAX_STREAMS]; UINT streamFreq[MAX_STREAMS + 1]; UINT streamFlags[MAX_STREAMS + 1]; /*0 | WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA */ @@ -1974,15 +1932,54 @@ typedef struct WineQueryEventData { } WineQueryEventData; /* IWineD3DBuffer */ + +/* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other + * fixed function semantics as D3DCOLOR or FLOAT16 */ +enum wined3d_buffer_conversion_type +{ + CONV_NONE, + CONV_D3DCOLOR, + CONV_POSITIONT, + CONV_FLOAT16_2, /* Also handles FLOAT16_4 */ +}; + +#define WINED3D_BUFFER_OPTIMIZED 0x01 /* Optimize has been called for the buffer */ +#define WINED3D_BUFFER_DIRTY 0x02 /* Buffer data has been modified */ +#define WINED3D_BUFFER_HASDESC 0x04 /* A vertex description has been found */ +#define WINED3D_BUFFER_CREATEBO 0x08 /* Attempt to create a buffer object next PreLoad */ + struct wined3d_buffer { const struct IWineD3DBufferVtbl *vtbl; IWineD3DResourceClass resource; struct wined3d_buffer_desc desc; + + GLuint buffer_object; + GLenum buffer_object_usage; + UINT buffer_object_size; + LONG bind_count; + DWORD flags; + + UINT dirty_start; + UINT dirty_end; + LONG lock_count; + + /* legacy vertex buffers */ + DWORD fvf; + + /* conversion stuff */ + UINT conversion_count; + UINT draw_count; + UINT stride; /* 0 if no conversion */ + UINT conversion_stride; /* 0 if no shifted conversion */ + enum wined3d_buffer_conversion_type *conversion_map; /* NULL if no conversion */ + /* Extra load offsets, for FLOAT16 conversion */ + UINT *conversion_shift; /* NULL if no shifted conversion */ }; extern const IWineD3DBufferVtbl wined3d_buffer_vtbl; +const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object); /* IWineD3DRendertargetView */ struct wined3d_rendertarget_view @@ -2102,18 +2099,8 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize /* Math utils */ void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2); -unsigned int count_bits(unsigned int mask); UINT wined3d_log2i(UINT32 x); -/***************************************************************************** - * To enable calling of inherited functions, requires prototypes - * - * Note: Only require classes which are subclassed, ie resource, basetexture, - */ - - /* IWineD3DVertexBuffer */ - extern const BYTE *IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer* iface, DWORD iOffset, GLint *vbo); - /* TODO: Make this dynamic, based on shader limits ? */ #define MAX_REG_ADDR 1 #define MAX_REG_TEMP 32 diff --git a/dlls/winedos/dosaspi.c b/dlls/winedos/dosaspi.c index 988e776a202..9125d53c03d 100644 --- a/dlls/winedos/dosaspi.c +++ b/dlls/winedos/dosaspi.c @@ -196,7 +196,7 @@ static void WINAPI ASPI_DOS_func(CONTEXT86 *context) */ void WINAPI DOSVM_ASPIHandler( CONTEXT86 *context ) { - FARPROC16 *p = (FARPROC16 *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); + FARPROC16 *p = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); TRACE("DOS ASPI opening\n"); if ((CX_reg(context) == 4) || (CX_reg(context) == 5)) { diff --git a/dlls/winedos/int10.c b/dlls/winedos/int10.c index d49eef1e058..a0b82ed75f7 100644 --- a/dlls/winedos/int10.c +++ b/dlls/winedos/int10.c @@ -1249,7 +1249,7 @@ void WINAPI DOSVM_Int10Handler( CONTEXT86 *context ) BYTE *pt; TRACE("Set Block of DAC registers\n"); - pt = (BYTE*)CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx); + pt = CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx); for (i=0;idta), - (DWORD)OFFSETOF(pTask->dta) ); + return CTX_SEG_OFF_TO_LIN( context, SELECTOROF(pTask->dta), + OFFSETOF(pTask->dta) ); } @@ -1978,9 +1978,8 @@ static void INT21_ExtendedCountryInformation( CONTEXT86 *context ) case 0xa1: /* CAPITALIZE COUNTED FILENAME STRING */ TRACE("Convert string to uppercase with length\n"); { - char *ptr = (char *)CTX_SEG_OFF_TO_LIN( context, - context->SegDs, - context->Edx ); + char *ptr = CTX_SEG_OFF_TO_LIN( context, context->SegDs, + context->Edx ); WORD len = CX_reg(context); while (len--) { *ptr = toupper(*ptr); ptr++; } } @@ -3117,9 +3116,8 @@ static void INT21_LongFilename( CONTEXT86 *context ) MultiByteToWideChar(CP_OEMCP, 0, pathA, -1, pathW, MAX_PATH); handle = FindFirstFileW(pathW, &dataW); - - dataA = (WIN32_FIND_DATAA *)CTX_SEG_OFF_TO_LIN(context, context->SegEs, - context->Edi); + + dataA = CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi); if (handle != INVALID_HANDLE_VALUE && (h16 = GlobalAlloc16(GMEM_MOVEABLE, sizeof(handle)))) { @@ -3148,8 +3146,7 @@ static void INT21_LongFilename( CONTEXT86 *context ) TRACE("LONG FILENAME - FIND NEXT MATCHING FILE for handle %d\n", BX_reg(context)); - dataA = (WIN32_FIND_DATAA *)CTX_SEG_OFF_TO_LIN(context, context->SegEs, - context->Edi); + dataA = CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi); if (h16 != INVALID_HANDLE_VALUE16 && (ptr = GlobalLock16( h16 ))) { @@ -3817,7 +3814,7 @@ static int INT21_FindFirst( CONTEXT86 *context ) WCHAR maskW[12], pathW[MAX_PATH]; static const WCHAR wildcardW[] = {'*','.','*',0}; - path = (const char *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); + path = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); MultiByteToWideChar(CP_OEMCP, 0, path, -1, pathW, MAX_PATH); p = strrchrW( pathW, '\\'); @@ -3987,7 +3984,7 @@ static int INT21_FindNext( CONTEXT86 *context ) */ static int INT21_FindFirstFCB( CONTEXT86 *context ) { - BYTE *fcb = (BYTE *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); + BYTE *fcb = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); FINDFILE_FCB *pFCB; int drive; WCHAR p[] = {' ',':',}; @@ -4011,7 +4008,7 @@ static int INT21_FindFirstFCB( CONTEXT86 *context ) */ static int INT21_FindNextFCB( CONTEXT86 *context ) { - BYTE *fcb = (BYTE *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); + BYTE *fcb = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx); FINDFILE_FCB *pFCB; LPBYTE pResult = INT21_GetCurrentDTA(context); DOS_DIRENTRY_LAYOUT *ddl; diff --git a/dlls/winedos/int31.c b/dlls/winedos/int31.c index a2d806aa4b7..e555e97c5a5 100644 --- a/dlls/winedos/int31.c +++ b/dlls/winedos/int31.c @@ -1004,9 +1004,8 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context ) case 0x000b: /* Get descriptor */ TRACE( "get descriptor (0x%04x)\n", BX_reg(context) ); { - LDT_ENTRY *entry = (LDT_ENTRY*)CTX_SEG_OFF_TO_LIN( context, - context->SegEs, - context->Edi ); + LDT_ENTRY *entry = CTX_SEG_OFF_TO_LIN( context, context->SegEs, + context->Edi ); wine_ldt_get_entry( BX_reg(context), entry ); } break; @@ -1014,9 +1013,8 @@ void WINAPI DOSVM_Int31Handler( CONTEXT86 *context ) case 0x000c: /* Set descriptor */ TRACE( "set descriptor (0x%04x)\n", BX_reg(context) ); { - LDT_ENTRY *entry = (LDT_ENTRY*)CTX_SEG_OFF_TO_LIN( context, - context->SegEs, - context->Edi ); + LDT_ENTRY *entry = CTX_SEG_OFF_TO_LIN( context, context->SegEs, + context->Edi ); wine_ldt_set_entry( BX_reg(context), entry ); } break; diff --git a/dlls/winedos/int33.c b/dlls/winedos/int33.c index 70bb478edb2..d72f0d881f4 100644 --- a/dlls/winedos/int33.c +++ b/dlls/winedos/int33.c @@ -201,7 +201,7 @@ typedef struct { static void MouseRelay(CONTEXT86 *context,void *mdata) { - MCALLDATA *data = (MCALLDATA *)mdata; + MCALLDATA *data = mdata; CONTEXT86 ctx = *context; if (!ISV86(&ctx)) diff --git a/dlls/winedos/interrupts.c b/dlls/winedos/interrupts.c index 580bee9553d..db0f17e1eda 100644 --- a/dlls/winedos/interrupts.c +++ b/dlls/winedos/interrupts.c @@ -262,7 +262,7 @@ BOOL WINAPI DOSVM_EmulateInterruptPM( CONTEXT86 *context, BYTE intnum ) { TRACE_(relay)("Call DOS int 0x%02x ret=%04x:%08x\n" " eax=%08x ebx=%08x ecx=%08x edx=%08x\n" - " esi=%08x edi=%08x ebp=%08x esp=%08x \n" + " esi=%08x edi=%08x ebp=%08x esp=%08x\n" " ds=%04x es=%04x fs=%04x gs=%04x ss=%04x flags=%08x\n", intnum, context->SegCs, context->Eip, context->Eax, context->Ebx, context->Ecx, context->Edx, @@ -449,7 +449,7 @@ BOOL WINAPI DOSVM_EmulateInterruptRM( CONTEXT86 *context, BYTE intnum ) { TRACE_(relay)("Call DOS int 0x%02x ret=%04x:%08x\n" " eax=%08x ebx=%08x ecx=%08x edx=%08x\n" - " esi=%08x edi=%08x ebp=%08x esp=%08x \n" + " esi=%08x edi=%08x ebp=%08x esp=%08x\n" " ds=%04x es=%04x fs=%04x gs=%04x ss=%04x flags=%08x\n", intnum, context->SegCs, context->Eip, context->Eax, context->Ebx, context->Ecx, context->Edx, diff --git a/dlls/winedos/module.c b/dlls/winedos/module.c index 0aa389f3934..a88aa0cbb6a 100644 --- a/dlls/winedos/module.c +++ b/dlls/winedos/module.c @@ -460,7 +460,7 @@ BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID para WORD fullCmdLength; LPBYTE psp_start = (LPBYTE)((DWORD)DOSVM_psp << 4); PDB16 *psp = (PDB16 *)psp_start; - ExecBlock *blk = (ExecBlock *)paramblk; + ExecBlock *blk = paramblk; LPBYTE cmdline = PTR_REAL_TO_LIN(SELECTOROF(blk->cmdline),OFFSETOF(blk->cmdline)); LPBYTE envblock = PTR_REAL_TO_LIN(psp->environment, 0); int cmdLength = cmdline[0]; @@ -530,7 +530,7 @@ BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID para /* MZ_LoadImage created a new PSP and loaded new values into it, * let's work on the new values now */ LPBYTE psp_start = (LPBYTE)((DWORD)DOSVM_psp << 4); - ExecBlock *blk = (ExecBlock *)paramblk; + ExecBlock *blk = paramblk; LPBYTE cmdline = PTR_REAL_TO_LIN(SELECTOROF(blk->cmdline),OFFSETOF(blk->cmdline)); /* First character contains the length of the command line. */ @@ -547,7 +547,7 @@ BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID para */ LPBYTE stack; init_sp -= 2; - stack = (LPBYTE) CTX_SEG_OFF_TO_LIN(context, init_ss, init_sp); + stack = CTX_SEG_OFF_TO_LIN(context, init_ss, init_sp); /* FIXME: push AX correctly */ stack[0] = 0x00; /* push AL */ stack[1] = 0x00; /* push AH */ @@ -570,7 +570,7 @@ BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID para break; case 3: /* load overlay */ { - OverlayBlock *blk = (OverlayBlock *)paramblk; + OverlayBlock *blk = paramblk; ret = MZ_DoLoadImage( hFile, filename, blk, 0); } break; diff --git a/dlls/winedos/relay.c b/dlls/winedos/relay.c index 9f6692c026b..39978fa907b 100644 --- a/dlls/winedos/relay.c +++ b/dlls/winedos/relay.c @@ -108,7 +108,7 @@ static void __stdcall RELAY_RelayStub( DOSRELAY proc, { if (proc) { - CONTEXT86 *context = (CONTEXT86*)ctx86; + CONTEXT86 *context = ctx86; RELAY_Stack16 *stack = RELAY_GetPointer( context->Esp ); DWORD old_seg_cs = context->SegCs; diff --git a/dlls/winedos/xms.c b/dlls/winedos/xms.c index a19ea26d3b5..0b39ca658d9 100644 --- a/dlls/winedos/xms.c +++ b/dlls/winedos/xms.c @@ -53,7 +53,7 @@ typedef struct { static BYTE * XMS_Offset( MOVEOFS *ofs ) { if (ofs->Handle) return (BYTE*)GlobalLock16(ofs->Handle)+ofs->Offset; - else return (BYTE*)PTR_REAL_TO_LIN(SELECTOROF(ofs->Offset),OFFSETOF(ofs->Offset)); + else return PTR_REAL_TO_LIN(SELECTOROF(ofs->Offset),OFFSETOF(ofs->Offset)); } /********************************************************************** diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 201a1cb50d3..79e67890298 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -103,11 +103,11 @@ MAKE_FUNCPTR( SSL_get_peer_certificate ); MAKE_FUNCPTR( SSL_CTX_get_timeout ); MAKE_FUNCPTR( SSL_CTX_set_timeout ); MAKE_FUNCPTR( SSL_CTX_set_default_verify_paths ); -MAKE_FUNCPTR( i2d_X509 ); MAKE_FUNCPTR( BIO_new_fp ); MAKE_FUNCPTR( ERR_get_error ); MAKE_FUNCPTR( ERR_error_string ); +MAKE_FUNCPTR( i2d_X509 ); #undef MAKE_FUNCPTR #endif @@ -221,7 +221,6 @@ BOOL netconn_init( netconn_t *conn, BOOL secure ) LOAD_FUNCPTR( SSL_CTX_get_timeout ); LOAD_FUNCPTR( SSL_CTX_set_timeout ); LOAD_FUNCPTR( SSL_CTX_set_default_verify_paths ); - LOAD_FUNCPTR( i2d_X509 ); #undef LOAD_FUNCPTR #define LOAD_FUNCPTR(x) \ @@ -234,6 +233,7 @@ BOOL netconn_init( netconn_t *conn, BOOL secure ) LOAD_FUNCPTR( BIO_new_fp ); LOAD_FUNCPTR( ERR_get_error ); LOAD_FUNCPTR( ERR_error_string ); + LOAD_FUNCPTR( i2d_X509 ); #undef LOAD_FUNCPTR pSSL_library_init(); diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index 01a81059f95..ef1eef10962 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -1092,8 +1092,6 @@ static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr) TRACE("\n"); - WININET_Release(&lpwh->lpFtpSession->hdr); - if (!lpwh->session_deleted) lpwfs->download_in_progress = NULL; @@ -1103,6 +1101,8 @@ static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr) nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext); if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n"); + WININET_Release(&lpwh->lpFtpSession->hdr); + HeapFree(GetProcessHeap(), 0, lpwh); } diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 3a42d677357..7b260705c55 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -3833,17 +3833,12 @@ static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear) do { /* - * HACK peek at the buffer - */ - buflen = MAX_REPLY_LEN; - NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc); - - /* * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code. */ - memset(buffer, 0, MAX_REPLY_LEN); + buflen = MAX_REPLY_LEN; if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) goto lend; + rc += buflen; MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); /* split the version from the status code */ @@ -3898,6 +3893,13 @@ static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear) LPWSTR * pFieldAndValue; TRACE("got line %s, now interpreting\n", debugstr_a(bufferA)); + + if (!bufferA[0]) break; + if (!strchr(bufferA, ':')) + { + WARN("invalid header\n"); + continue; + } MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); while (cchRawHeaders + buflen + strlenW(szCrLf) > cchMaxRawHeaders) diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index a14a158974e..785a1ef4b01 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -186,7 +186,8 @@ BOOL WININET_Release( LPWININETHANDLEHEADER info ) info->vtbl->CloseConnection( info ); } /* Don't send a callback if this is a session handle created with InternetOpenUrl */ - if (info->htype != WH_HHTTPSESSION || !(info->dwInternalFlags & INET_OPENURL)) + if ((info->htype != WH_HHTTPSESSION && info->htype != WH_HFTPSESSION) + || !(info->dwInternalFlags & INET_OPENURL)) { INTERNET_SendCallback(info, info->dwContext, INTERNET_STATUS_HANDLE_CLOSING, &info->hInternet, diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c index ccf2928902b..3c55528e7cc 100644 --- a/dlls/wininet/netconnection.c +++ b/dlls/wininet/netconnection.c @@ -124,12 +124,12 @@ MAKE_FUNCPTR(SSL_get_peer_certificate); MAKE_FUNCPTR(SSL_CTX_get_timeout); MAKE_FUNCPTR(SSL_CTX_set_timeout); MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths); -MAKE_FUNCPTR(i2d_X509); /* OpenSSL's libcrypto functions that we use */ MAKE_FUNCPTR(BIO_new_fp); MAKE_FUNCPTR(ERR_get_error); MAKE_FUNCPTR(ERR_error_string); +MAKE_FUNCPTR(i2d_X509); #undef MAKE_FUNCPTR #endif @@ -188,7 +188,6 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) DYNSSL(SSL_CTX_get_timeout); DYNSSL(SSL_CTX_set_timeout); DYNSSL(SSL_CTX_set_default_verify_paths); - DYNSSL(i2d_X509); #undef DYNSSL #define DYNCRYPTO(x) \ @@ -202,6 +201,7 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) DYNCRYPTO(BIO_new_fp); DYNCRYPTO(ERR_get_error); DYNCRYPTO(ERR_error_string); + DYNCRYPTO(i2d_X509); #undef DYNCRYPTO pSSL_library_init(); diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 5fd45d5d069..193c446b818 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -1305,6 +1305,12 @@ static const char noauthmsg[] = "WWW-Authenticate: Basic realm=\"placebo\"\r\n" "\r\n"; +static const char noauthmsg2[] = +"HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed\r\n" +"HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed" +"\0d`0|6\n" +"Server: winetest\r\n"; + static const char proxymsg[] = "HTTP/1.1 407 Proxy Authentication Required\r\n" "Server: winetest\r\n" @@ -1488,6 +1494,10 @@ static DWORD CALLBACK server_thread(LPVOID param) { send(c, okmsg2, sizeof okmsg2-1, 0); } + if (strstr(buffer, "/testE")) + { + send(c, noauthmsg2, sizeof noauthmsg2-1, 0); + } if (strstr(buffer, "GET /quit")) { send(c, okmsg, sizeof okmsg-1, 0); @@ -1917,6 +1927,49 @@ static void test_basic_authentication(int port) InternetCloseHandle(session); } +static void test_invalid_response_headers(int port) +{ + HINTERNET session, connect, request; + DWORD size, status; + BOOL ret; + char buffer[256]; + + session = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(session != NULL, "InternetOpen failed\n"); + + connect = InternetConnect(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(connect != NULL, "InternetConnect failed\n"); + + request = HttpOpenRequest(connect, NULL, "/testE", NULL, NULL, NULL, 0, 0); + ok(request != NULL, "HttpOpenRequest failed\n"); + + ret = HttpSendRequest(request, NULL, 0, NULL, 0); + ok(ret, "HttpSendRequest failed %u\n", GetLastError()); + + status = 0; + size = sizeof(status); + ret = HttpQueryInfo( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL ); + ok(ret, "HttpQueryInfo failed\n"); + ok(status == 401, "unexpected status %u\n", status); + + buffer[0] = 0; + size = sizeof(buffer); + ret = HttpQueryInfo( request, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL); + ok(ret, "HttpQueryInfo failed\n"); + ok(!strcmp(buffer, "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"), + "headers wrong \"%s\"\n", buffer); + + buffer[0] = 0; + size = sizeof(buffer); + ret = HttpQueryInfo( request, HTTP_QUERY_SERVER, buffer, &size, NULL); + ok(ret, "HttpQueryInfo failed\n"); + ok(!strcmp(buffer, "winetest"), "server wrong \"%s\"\n", buffer); + + InternetCloseHandle(request); + InternetCloseHandle(connect); + InternetCloseHandle(session); +} + static void test_HttpQueryInfo(int port) { HINTERNET hi, hc, hr; @@ -2050,6 +2103,7 @@ static void test_http_connection(void) test_http1_1(si.port); test_cookie_header(si.port); test_basic_authentication(si.port); + test_invalid_response_headers(si.port); test_HttpQueryInfo(si.port); test_HttpSendRequestW(si.port); diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index fe3f4778f3a..56a604b176a 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -27,6 +27,8 @@ #include "wine/test.h" +static BOOL (WINAPI *pCreateUrlCacheContainerA)(DWORD, DWORD, DWORD, DWORD, + DWORD, DWORD, DWORD, DWORD); static BOOL (WINAPI *pInternetTimeFromSystemTimeA)(CONST SYSTEMTIME *,DWORD ,LPSTR ,DWORD); static BOOL (WINAPI *pInternetTimeFromSystemTimeW)(CONST SYSTEMTIME *,DWORD ,LPWSTR ,DWORD); static BOOL (WINAPI *pInternetTimeToSystemTimeA)(LPCSTR ,SYSTEMTIME *,DWORD); @@ -643,7 +645,7 @@ static void test_IsDomainLegalCookieDomainW(void) ret = pIsDomainLegalCookieDomainW(NULL, NULL); error = GetLastError(); ok(!ret || - broken(ret), /* Win98, NT4, W2K, XP (some) */ + broken(ret), /* IE6 */ "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_PARAMETER, "got %u expected ERROR_INVALID_PARAMETER\n", error); @@ -664,7 +666,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == ERROR_INVALID_PARAMETER), /* Win98, NT4, W2K, XP (some) */ + broken(error == ERROR_INVALID_PARAMETER), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); SetLastError(0xdeadbeef); @@ -672,7 +674,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == ERROR_INVALID_PARAMETER), /* Win98, NT4, W2K, XP (some) */ + broken(error == ERROR_INVALID_PARAMETER), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); SetLastError(0xdeadbeef); @@ -680,7 +682,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == 0xdeadbeef), /* Win98, NT4, W2K, XP (some) */ + broken(error == 0xdeadbeef), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); SetLastError(0xdeadbeef); @@ -688,7 +690,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == 0xdeadbeef), /* Win98, NT4, W2K, XP (some) */ + broken(error == 0xdeadbeef), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); SetLastError(0xdeadbeef); @@ -702,7 +704,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == 0xdeadbeef), /* Win98, NT4, W2K, XP (some) */ + broken(error == 0xdeadbeef), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); SetLastError(0xdeadbeef); @@ -710,7 +712,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == 0xdeadbeef), /* Win98, NT4, W2K, XP (some) */ + broken(error == 0xdeadbeef), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); SetLastError(0xdeadbeef); @@ -745,7 +747,7 @@ static void test_IsDomainLegalCookieDomainW(void) error = GetLastError(); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); ok(error == ERROR_INVALID_NAME || - broken(error == 0xdeadbeef), /* Win98, NT4, W2K, XP (some) */ + broken(error == 0xdeadbeef), /* IE6 */ "got %u expected ERROR_INVALID_NAME\n", error); ret = pIsDomainLegalCookieDomainW(gmail_com, mail_gmail_com); @@ -770,6 +772,7 @@ START_TEST(internet) { HMODULE hdll; hdll = GetModuleHandleA("wininet.dll"); + pCreateUrlCacheContainerA = (void*)GetProcAddress(hdll, "CreateUrlCacheContainerA"); pInternetTimeFromSystemTimeA = (void*)GetProcAddress(hdll, "InternetTimeFromSystemTimeA"); pInternetTimeFromSystemTimeW = (void*)GetProcAddress(hdll, "InternetTimeFromSystemTimeW"); pInternetTimeToSystemTimeA = (void*)GetProcAddress(hdll, "InternetTimeToSystemTimeA"); @@ -784,7 +787,7 @@ START_TEST(internet) test_null(); if (!pInternetTimeFromSystemTimeA) - skip("skipping the InternetTime tests\n"); + win_skip("skipping the InternetTime tests\n"); else { InternetTimeFromSystemTimeA_test(); @@ -792,8 +795,10 @@ START_TEST(internet) InternetTimeToSystemTimeA_test(); InternetTimeToSystemTimeW_test(); } - if (!pIsDomainLegalCookieDomainW) - skip("skipping IsDomainLegalCookieDomainW tests\n"); + if (pIsDomainLegalCookieDomainW && (void*)pIsDomainLegalCookieDomainW == (void*)pCreateUrlCacheContainerA) + win_skip("IsDomainLegalCookieDomainW is not available on systems with IE5\n"); + else if (!pIsDomainLegalCookieDomainW) + win_skip("IsDomainLegalCookieDomainW (or ordinal 117) is not available\n"); else test_IsDomainLegalCookieDomainW(); } diff --git a/dlls/wininet/tests/url.c b/dlls/wininet/tests/url.c index c848f6bc90d..39c02863351 100644 --- a/dlls/wininet/tests/url.c +++ b/dlls/wininet/tests/url.c @@ -299,14 +299,25 @@ static void InternetCrackUrlW_test(void) SetLastError(0xdeadbeef); r = InternetCrackUrlW(NULL, 0, 0, &comp ); error = GetLastError(); + if (!r && error == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("InternetCrackUrlW is not implemented\n"); + return; + } ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); - ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); - - SetLastError(0xdeadbeef); - r = InternetCrackUrlW(url, 0, 0, NULL ); - error = GetLastError(); - ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); - ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); + ok( error == ERROR_INVALID_PARAMETER || + broken(error == ERROR_INTERNET_UNRECOGNIZED_SCHEME), /* IE5 */ + "expected ERROR_INVALID_PARAMETER got %u\n", error); + + if (error == ERROR_INVALID_PARAMETER) + { + /* Crashes on IE5 */ + SetLastError(0xdeadbeef); + r = InternetCrackUrlW(url, 0, 0, NULL ); + error = GetLastError(); + ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); + ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); + } r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c index c22883d9e47..bf67fecec03 100644 --- a/dlls/wininet/urlcache.c +++ b/dlls/wininet/urlcache.c @@ -3626,3 +3626,12 @@ DWORD WINAPI GetDiskInfoA(void *p0, void *p1, void *p2, void *p3) FIXME("(%p, %p, %p, %p)\n", p0, p1, p2, p3); return 0; } + +/*********************************************************************** + * RegisterUrlCacheNotification (WININET.@) + */ +DWORD WINAPI RegisterUrlCacheNotification(LPVOID a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f) +{ + FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f); + return 0; +} diff --git a/dlls/wininet/wininet.spec b/dlls/wininet/wininet.spec index 8db462cd967..78b98cc1ac1 100644 --- a/dlls/wininet/wininet.spec +++ b/dlls/wininet/wininet.spec @@ -216,7 +216,7 @@ @ stub PrivacyGetZonePreferenceW # (long long ptr ptr ptr) @ stub PrivacySetZonePreferenceW # (long long long wstr) @ stdcall ReadUrlCacheEntryStream(ptr long ptr ptr long) -@ stub RegisterUrlCacheNotification +@ stdcall RegisterUrlCacheNotification(ptr long long long long long) @ stdcall ResumeSuspendedDownload(long long) @ stdcall RetrieveUrlCacheEntryFileA(str ptr ptr long) @ stdcall RetrieveUrlCacheEntryFileW(wstr ptr ptr long) diff --git a/include/config.h.in b/include/config.h.in index 575bb8ee3b0..f3bd7757dee 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -273,6 +273,9 @@ /* Define to 1 if you have the `kqueue' function. */ #undef HAVE_KQUEUE +/* Define to 1 if you have the header file. */ +#undef HAVE_KSTAT_H + /* Define to 1 if you have the header file. */ #undef HAVE_LBER_H @@ -324,6 +327,9 @@ /* Define to 1 if you have the `i386' library (-li386). */ #undef HAVE_LIBI386 +/* Define to 1 if you have the `kstat' library (-lkstat). */ +#undef HAVE_LIBKSTAT + /* Define to 1 if you have the `ossaudio' library (-lossaudio). */ #undef HAVE_LIBOSSAUDIO diff --git a/include/d3dx9.h b/include/d3dx9.h index 6b3bdf6c19d..47d283095af 100644 --- a/include/d3dx9.h +++ b/include/d3dx9.h @@ -21,6 +21,12 @@ #include +#define D3DX_DEFAULT ((UINT)-1) +#define D3DX_DEFAULT_NONPOW2 ((UINT)-2) +#define D3DX_DEFAULT_FLOAT FLT_MAX +#define D3DX_FROM_FILE ((UINT)-3) +#define D3DFMT_FROM_FILE ((D3DFORMAT)-3) + #include "d3d9.h" #include "d3dx9math.h" #include "d3dx9core.h" diff --git a/include/d3dx9core.h b/include/d3dx9core.h index 9a108fa7e55..b33d8ff6fa0 100644 --- a/include/d3dx9core.h +++ b/include/d3dx9core.h @@ -16,11 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #ifndef __WINE_D3DX9CORE_H #define __WINE_D3DX9CORE_H -#include - /********************************************** ***************** Definitions **************** **********************************************/ diff --git a/include/d3dx9mesh.h b/include/d3dx9mesh.h index a85f80de58b..39ad28a5d89 100644 --- a/include/d3dx9mesh.h +++ b/include/d3dx9mesh.h @@ -16,11 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #ifndef __WINE_D3DX9MESH_H #define __WINE_D3DX9MESH_H -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/include/d3dx9shader.h b/include/d3dx9shader.h index a50b72aceaf..899077e2156 100644 --- a/include/d3dx9shader.h +++ b/include/d3dx9shader.h @@ -16,11 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "d3dx9.h" + #ifndef __D3DX9SHADER_H__ #define __D3DX9SHADER_H__ -#include "d3dx9.h" - typedef LPCSTR D3DXHANDLE; typedef enum D3DXPARAMETER_CLASS diff --git a/include/dbghelp.h b/include/dbghelp.h index a67daf38905..6f9e8807f36 100644 --- a/include/dbghelp.h +++ b/include/dbghelp.h @@ -25,6 +25,12 @@ extern "C" { #endif /* defined(__cplusplus) */ +#ifdef _WIN64 +#ifndef _IMAGEHLP64 +#define _IMAGEHLP64 +#endif +#endif + #define IMAGEAPI WINAPI #define DBHLPAPI IMAGEAPI @@ -58,12 +64,17 @@ typedef enum AddrModeFlat } ADDRESS_MODE; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define ADDRESS ADDRESS64 +#define LPADDRESS LPADDRESS64 +#else typedef struct _tagADDRESS { DWORD Offset; WORD Segment; ADDRESS_MODE Mode; } ADDRESS, *LPADDRESS; +#endif typedef struct _tagADDRESS64 { @@ -102,6 +113,10 @@ typedef enum NumSymTypes } SYM_TYPE; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64 +#define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64 +#else typedef struct _IMAGEHLP_SYMBOL { DWORD SizeOfStruct; @@ -111,6 +126,7 @@ typedef struct _IMAGEHLP_SYMBOL DWORD MaxNameLength; CHAR Name[1]; } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL; +#endif typedef struct _IMAGEHLP_SYMBOL64 { @@ -132,6 +148,12 @@ typedef struct _IMAGEHLP_SYMBOLW64 WCHAR Name[1]; } IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_MODULE IMAGEHLP_MODULE64 +#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64 +#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64 +#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64 +#else typedef struct _IMAGEHLP_MODULE { DWORD SizeOfStruct; @@ -159,6 +181,7 @@ typedef struct _IMAGEHLP_MODULEW WCHAR ImageName[256]; WCHAR LoadedImageName[256]; } IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW; +#endif typedef struct _IMAGEHLP_MODULE64 { @@ -214,6 +237,12 @@ typedef struct _IMAGEHLP_MODULEW64 BOOL Publics; } IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_LINE IMAGEHLP_LINE64 +#define PIMAGEHLP_LINE PIMAGEHLP_LINE64 +#define IMAGEHLP_LINEW IMAGEHLP_LINEW64 +#define PIMAGEHLP_LINEW PIMAGEHLP_LINEW64 +#else typedef struct _IMAGEHLP_LINE { DWORD SizeOfStruct; @@ -231,6 +260,7 @@ typedef struct _IMAGEHLP_LINEW PWSTR FileName; DWORD Address; } IMAGEHLP_LINEW, *PIMAGEHLP_LINEW; +#endif typedef struct _IMAGEHLP_LINE64 { @@ -311,6 +341,10 @@ typedef struct _IMAGEHLP_CBA_EVENTW PVOID object; } IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#else typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD { DWORD SizeOfStruct; @@ -321,6 +355,7 @@ typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD BOOLEAN Reparse; HANDLE hFile; } IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD; +#endif typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 { @@ -346,6 +381,10 @@ typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 DWORD Flags; } IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64 +#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64 +#else typedef struct _IMAGEHLP_DUPLICATE_SYMBOL { DWORD SizeOfStruct; @@ -353,6 +392,7 @@ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_SYMBOL Symbol; DWORD SelectedSymbol; } IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL; +#endif typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 { @@ -1176,6 +1216,10 @@ BOOL WINAPI SymSetContext(HANDLE, PIMAGEHLP_STACK_FRAME, PIMAGEHLP_CONTEXT); * Stack management * *************************/ +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define KDHELP KDHELP64 +#define PKDHELP PKDHELP64 +#else typedef struct _KDHELP { DWORD Thread; @@ -1186,6 +1230,7 @@ typedef struct _KDHELP DWORD KeUserCallbackDispatcher; DWORD SystemRangeStart; } KDHELP, *PKDHELP; +#endif typedef struct _KDHELP64 { @@ -1200,6 +1245,10 @@ typedef struct _KDHELP64 DWORD64 Reserved[8]; } KDHELP64, *PKDHELP64; +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define STACKFRAME STACKFRAME64 +#define LPSTACKFRAME LPSTACKFRAME64 +#else typedef struct _STACKFRAME { ADDRESS AddrPC; @@ -1214,6 +1263,7 @@ typedef struct _STACKFRAME KDHELP KdHelp; ADDRESS AddrBStore; } STACKFRAME, *LPSTACKFRAME; +#endif typedef struct _STACKFRAME64 { diff --git a/include/shlguid.h b/include/shlguid.h index 1692dec8be8..88d70ce633f 100644 --- a/include/shlguid.h +++ b/include/shlguid.h @@ -123,6 +123,8 @@ DEFINE_GUID(CLSID_FolderShortcut, 0x0AFACED1, 0xE828, 0x11D1, 0x91, 0x87, 0xB5, DEFINE_GUID(IID_IQueryAssociations, 0xc46ca590, 0x3c3f, 0x11d2, 0xbe, 0xe6, 0x00, 0x00, 0xf8, 0x05, 0xca, 0x57); +DEFINE_GUID(CLSID_QueryAssociations, 0xa07034fd, 0x6caa, 0x4954, 0xac, 0x3f, 0x97, 0xa2, 0x72, 0x16, 0xf9, 0x8a); + DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); DEFINE_GUID(CLSID_AutoComplete, 0x00bb2763, 0x6a77, 0x11d0, 0xa5, 0x35, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index f924cbe65d0..b2ecfa0b5f5 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -97,12 +97,17 @@ typedef enum _WINED3DLIGHTTYPE typedef enum _WINED3DPRIMITIVETYPE { + WINED3DPT_UNDEFINED = 0, WINED3DPT_POINTLIST = 1, WINED3DPT_LINELIST = 2, WINED3DPT_LINESTRIP = 3, WINED3DPT_TRIANGLELIST = 4, WINED3DPT_TRIANGLESTRIP = 5, WINED3DPT_TRIANGLEFAN = 6, + WINED3DPT_LINELIST_ADJ = 10, + WINED3DPT_LINESTRIP_ADJ = 11, + WINED3DPT_TRIANGLELIST_ADJ = 12, + WINED3DPT_TRIANGLESTRIP_ADJ = 13, WINED3DPT_FORCE_DWORD = 0x7fffffff } WINED3DPRIMITIVETYPE; @@ -1916,7 +1921,7 @@ typedef struct WineDirect3DStridedData const BYTE *lpData; /* Pointer to start of data */ DWORD dwStride; /* Stride between occurrences of this data */ DWORD dwType; /* Type (as in D3DVSDT_TYPE) */ - int VBO; /* Vertex buffer object this data is in */ + unsigned int VBO; /* Vertex buffer object this data is in */ UINT streamNo; /* D3D stream number */ } WineDirect3DStridedData; @@ -2408,26 +2413,6 @@ interface IWineD3DRendertargetView : IWineD3DBase [ object, local, - uuid(217f671e-6f30-11d9-c687-00046142c14f) -] -interface IWineD3DVertexBuffer : IWineD3DResource -{ - HRESULT Lock( - [in] UINT offset, - [in] UINT size, - [out] BYTE **data, - [in] DWORD flags - ); - HRESULT Unlock( - ); - HRESULT GetDesc( - [out] WINED3DVERTEXBUFFER_DESC *desc - ); -} - -[ - object, - local, uuid(3a02a54e-6f30-11d9-c687-00046142c14f) ] interface IWineD3DIndexBuffer : IWineD3DResource @@ -2918,6 +2903,17 @@ interface IWineD3DSwapChain : IWineD3DBase ] interface IWineD3DBuffer : IWineD3DResource { + HRESULT Map( + [in] UINT offset, + [in] UINT size, + [out] BYTE **data, + [in] DWORD flags + ); + HRESULT Unmap( + ); + HRESULT GetDesc( + [out] WINED3DVERTEXBUFFER_DESC *desc + ); } [ @@ -2989,7 +2985,7 @@ interface IWineD3DDevice : IWineD3DBase [in] DWORD usage, [in] DWORD fvf, [in] WINED3DPOOL pool, - [out] IWineD3DVertexBuffer **vertex_buffer, + [out] IWineD3DBuffer **vertex_buffer, [in] HANDLE *shared_handle, [in] IUnknown *parent ); @@ -3346,13 +3342,13 @@ interface IWineD3DDevice : IWineD3DBase ); HRESULT SetStreamSource( [in] UINT stream_idx, - [in] IWineD3DVertexBuffer *vertex_buffer, + [in] IWineD3DBuffer *buffer, [in] UINT offset, [in] UINT stride ); HRESULT GetStreamSource( [in] UINT stream_idx, - [out] IWineD3DVertexBuffer **vertex_buffer, + [out] IWineD3DBuffer **buffer, [out] UINT *offset, [out] UINT *stride ); @@ -3449,7 +3445,7 @@ interface IWineD3DDevice : IWineD3DBase [in] UINT src_start_idx, [in] UINT dst_idx, [in] UINT vertex_count, - [in] IWineD3DVertexBuffer *dest_buffer, + [in] IWineD3DBuffer *dest_buffer, [in] IWineD3DVertexDeclaration *declaration, [in] DWORD flags ); @@ -3480,42 +3476,42 @@ interface IWineD3DDevice : IWineD3DBase [in] IWineD3DRendertargetView *rendertarget_view, [in] const float color[4] ); + void SetPrimitiveType( + [in] WINED3DPRIMITIVETYPE primitive_topology + ); + void GetPrimitiveType( + [out] WINED3DPRIMITIVETYPE *primitive_topology + ); HRESULT DrawPrimitive( - [in] WINED3DPRIMITIVETYPE primitive_type, [in] UINT start_vertex, - [in] UINT primitive_count + [in] UINT vertex_count ); HRESULT DrawIndexedPrimitive( - [in] WINED3DPRIMITIVETYPE primitive_type, [in] UINT min_vertex_idx, [in] UINT vertex_count, [in] UINT start_idx, - [in] UINT primitive_count + [in] UINT index_count ); HRESULT DrawPrimitiveUP( - [in] WINED3DPRIMITIVETYPE primitive_type, - [in] UINT primitive_count, + [in] UINT vertex_count, [in] const void *stream_data, [in] UINT stream_stride ); HRESULT DrawIndexedPrimitiveUP( - [in] WINED3DPRIMITIVETYPE primitive_type, [in] UINT min_vertex_idx, [in] UINT vertex_count, - [in] UINT primitive_count, + [in] UINT index_count, [in] const void *index_data, [in] WINED3DFORMAT index_data_format, [in] const void *stream_data, [in] UINT stream_stride ); HRESULT DrawPrimitiveStrided( - [in] WINED3DPRIMITIVETYPE primitive_type, - [in] UINT primitive_count, + [in] UINT vertex_count, [in] const WineDirect3DVertexStridedData *strided_data ); HRESULT DrawIndexedPrimitiveStrided( - [in] WINED3DPRIMITIVETYPE primitive_type, - [in] UINT primitive_count, + [in] UINT index_count, [in] const WineDirect3DVertexStridedData *strided_data, [in] UINT vertex_count, [in] const void *index_data, diff --git a/include/winnt.h b/include/winnt.h index 69c4b10edf7..abcc50205a1 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -3603,7 +3603,21 @@ typedef enum _TOKEN_INFORMATION_CLASS { TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, - TokenSandBoxInert + TokenSandBoxInert, + TokenAuditPolicy, + TokenOrigin, + TokenElevationType, + TokenLinkedToken, + TokenElevation, + TokenHasRestrictions, + TokenAccessInformation, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + TokenIntegrityLevel, + TokenUIAccess, + TokenMandatoryPolicy, + TokenLogonSid, + MaxTokenInfoClass } TOKEN_INFORMATION_CLASS; #define TOKEN_TOKEN_ADJUST_DEFAULT 0x0080 diff --git a/libs/port/interlocked.c b/libs/port/interlocked.c index 12b326f3bf8..fc40fe5970c 100644 --- a/libs/port/interlocked.c +++ b/libs/port/interlocked.c @@ -242,7 +242,7 @@ void* interlocked_xchg_ptr( void** dest, void* val ) __asm__ __volatile__( "0: lwarx %0,0,%1\n" " stwcx. %2,0,%1\n" - " bne- 0b \n" + " bne- 0b\n" " isync\n" : "=&r"(ret) : "r"(dest), "r"(val) diff --git a/libs/wine/mmap.c b/libs/wine/mmap.c index ff117cccdfb..d107fc7a08f 100644 --- a/libs/wine/mmap.c +++ b/libs/wine/mmap.c @@ -243,7 +243,7 @@ static inline int mmap_reserve( void *addr, size_t size ) * * Reserve as much memory as possible in the given area. */ -#if defined(__i386__) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) /* commented out until FreeBSD gets fixed */ +#ifdef __i386__ static void reserve_area( void *addr, void *end ) { size_t size = (char *)end - (char *)addr; @@ -343,7 +343,7 @@ void mmap_init(void) { struct reserved_area *area; struct list *ptr; -#if defined(__i386__) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) /* commented out until FreeBSD gets fixed */ +#ifdef __i386__ char stack; char * const stack_ptr = &stack; char *user_space_limit = (char *)0x7ffe0000; @@ -369,8 +369,8 @@ void mmap_init(void) char *base = stack_ptr - ((unsigned int)stack_ptr & granularity_mask) - (granularity_mask + 1); if (base > user_space_limit) reserve_area( user_space_limit, base ); base = stack_ptr - ((unsigned int)stack_ptr & granularity_mask) + (granularity_mask + 1); -#ifdef linux - /* Linux heuristic: assume the stack is near the end of the address */ +#if defined(linux) || defined(__FreeBSD__) + /* Heuristic: assume the stack is near the end of the address */ /* space, this avoids a lot of futile allocation attempts */ end = (char *)(((unsigned long)base + 0x0fffffff) & 0xf0000000); #endif diff --git a/programs/Makeprog.rules.in b/programs/Makeprog.rules.in index 1f9fe7841c4..add239f59cf 100644 --- a/programs/Makeprog.rules.in +++ b/programs/Makeprog.rules.in @@ -31,7 +31,7 @@ $(MODULE): $(OBJS) $(RCOBJS) Makefile.in # Rules for testing -check test:: $(SUBDIRS:%=%/__test__) +check test:: $(SUBDIRS:%=%/__test__) dummy $(TESTRESULTS): $(MODULE)$(DLLEXT) diff --git a/programs/cmd/Cs.rc b/programs/cmd/Cs.rc index 4f6a3855d34..15ece453dcc 100644 --- a/programs/cmd/Cs.rc +++ b/programs/cmd/Cs.rc @@ -276,4 +276,5 @@ Zadejte HELP

for further information on any of the above commands\n" WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Es.rc b/programs/cmd/Es.rc index c80748354dd..f27906a28e7 100644 --- a/programs/cmd/Es.rc +++ b/programs/cmd/Es.rc @@ -289,4 +289,5 @@ Introduzca HELP para m WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Fr.rc b/programs/cmd/Fr.rc index 4be49bccfd9..7551c766dc8 100644 --- a/programs/cmd/Fr.rc +++ b/programs/cmd/Fr.rc @@ -270,4 +270,5 @@ Entrez HELP pour plus d'informations sur les commandes ci-dessus\n" WCMD_CONSTITLE,"Invite de commande Wine" WCMD_VERSION,"CMD version %s\n\n" WCMD_MOREPROMPT, "Plus ? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Ja.rc b/programs/cmd/Ja.rc index aa7ef9e787e..20273ec9a95 100644 --- a/programs/cmd/Ja.rc +++ b/programs/cmd/Ja.rc @@ -277,6 +277,7 @@ EXIT\t\tCMDを終了\n\n\ WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } #pragma code_page(default) diff --git a/programs/cmd/Ko.rc b/programs/cmd/Ko.rc index c4a29618c2f..e2831f51bd7 100644 --- a/programs/cmd/Ko.rc +++ b/programs/cmd/Ko.rc @@ -257,11 +257,12 @@ HELP < WCMD_VERIFYPROMPT, "°ËÁõ(Verify)Àº %s\n" WCMD_VERIFYERR, "°ËÁõ(Verify)Àº ¹Ýµå½Ã ON À̳ª OFF°¡ µÇ¾î¾ß ÇÕ´Ï´Ù.\n"; WCMD_ARGERR, "¸Å°³º¯¼ö ¿¡·¯\n" - WCMD_VOLUMEDETAIL, "%c µå¶óÀ̺êÀÇ ”ª·ýÀº %s\n”ª·ý ½Ã¸®¾ó ¹øÈ£´Â %04x-%04x\n\n" + WCMD_VOLUMEDETAIL, "%c µå¶óÀ̺êÀÇ º¼·ýÀº %s\n º¼·ý ½Ã¸®¾ó ¹øÈ£´Â %04x-%04x\n\n" WCMD_VOLUMEPROMPT, "º¼·ý ¶óº§ (11 ±ÛÀÚ, ENTER´Â ¾øÀ½°ú °°À½)?" WCMD_NOPATH, "PATH¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù\n" WCMD_ANYKEY,"¸®ÅÏ Å°¸¦ ´©¸£¸é °è¼Ó: " WCMD_CONSTITLE,"Wine ¸í·É ÀԷ´ë±â" WCMD_VERSION,"CMD ¹öÁ¯ %s\n\n" WCMD_MOREPROMPT, " ´õ? " + WCMD_LINETOOLONG, "ÀÌ Ãâ·Â ÁÙÀº ³Ê¹« ±é´Ï´Ù.\n" } diff --git a/programs/cmd/Nl.rc b/programs/cmd/Nl.rc index b1b7e5705b0..6863b00969b 100644 --- a/programs/cmd/Nl.rc +++ b/programs/cmd/Nl.rc @@ -272,4 +272,5 @@ type HELP voor meer informatie over bovengenoemde opdrachten\n" WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Versie %s\n\n" WCMD_MOREPROMPT, "Meer? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/No.rc b/programs/cmd/No.rc index 394d28e201c..71a694b9af5 100644 --- a/programs/cmd/No.rc +++ b/programs/cmd/No.rc @@ -270,4 +270,5 @@ Skriv WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Pl.rc b/programs/cmd/Pl.rc index 70ac98245c2..7951843c3b2 100644 --- a/programs/cmd/Pl.rc +++ b/programs/cmd/Pl.rc @@ -267,4 +267,5 @@ Wpisz HELP dla dok WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Pt.rc b/programs/cmd/Pt.rc index dd8069fd678..65e0a6b8833 100644 --- a/programs/cmd/Pt.rc +++ b/programs/cmd/Pt.rc @@ -499,4 +499,5 @@ Digite HELP para mais informa WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Ru.rc b/programs/cmd/Ru.rc index a97c190d0ff..5bd2a05098a 100644 --- a/programs/cmd/Ru.rc +++ b/programs/cmd/Ru.rc @@ -278,4 +278,5 @@ EXIT\t\t WCMD_CONSTITLE,"Ïðèãëàøåíèå êîìàíäíîé ñòðîêè Wine" WCMD_VERSION,"Âåðñèÿ CMD %s\n\n" WCMD_MOREPROMPT, "Åù¸? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/Si.rc b/programs/cmd/Si.rc index 4bbfdce3df4..9a18741367c 100644 --- a/programs/cmd/Si.rc +++ b/programs/cmd/Si.rc @@ -270,6 +270,7 @@ Uporabite HELP za več informacijo o kateremkoli od zgoraj navedenih ukaz WCMD_CONSTITLE,"Wine ukazni poziv" WCMD_VERSION,"CMD različica %s\n\n" WCMD_MOREPROMPT, "Več? " + WCMD_LINETOOLONG, "The input line is too long.\n" } #pragma code_page(default) diff --git a/programs/cmd/Tr.rc b/programs/cmd/Tr.rc index 204fc17ee5a..656a5831685 100644 --- a/programs/cmd/Tr.rc +++ b/programs/cmd/Tr.rc @@ -274,4 +274,5 @@ Yukar WCMD_CONSTITLE,"Wine Command Prompt" WCMD_VERSION,"CMD Version %s\n\n" WCMD_MOREPROMPT, "More? " + WCMD_LINETOOLONG, "The input line is too long.\n" } diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index a31b0113475..67aab421efc 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -243,6 +243,7 @@ extern WCHAR version_string[]; #define WCMD_CONSTITLE 1032 #define WCMD_VERSION 1033 #define WCMD_MOREPROMPT 1034 +#define WCMD_LINETOOLONG 1035 /* msdn specified max for Win XP */ #define MAXSTRING 8192 diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 4bbd72e3f3a..f90ca8c8a2f 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -88,7 +88,7 @@ static const WCHAR equalsW[] = {'=','\0'}; static const WCHAR closeBW[] = {')','\0'}; WCHAR anykey[100]; WCHAR version_string[100]; -WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH]; +WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING]; BATCH_CONTEXT *context = NULL; extern struct env_stack *pushd_directories; static const WCHAR *pagedMessage = NULL; @@ -972,7 +972,8 @@ void WCMD_run_program (WCHAR *command, int called) { WCHAR temp[MAX_PATH]; WCHAR pathtosearch[MAXSTRING]; WCHAR *pathposn; - WCHAR stemofsearch[MAX_PATH]; + WCHAR stemofsearch[MAX_PATH]; /* maximum allowed executable name is + MAX_PATH, including null character */ WCHAR *lastSlash; WCHAR pathext[MAXSTRING]; BOOL extensionsupplied = FALSE; @@ -998,6 +999,12 @@ void WCMD_run_program (WCHAR *command, int called) { strcpyW (pathtosearch, curDir); } if (strchrW(param1, '.') != NULL) extensionsupplied = TRUE; + if (strlenW(param1) >= MAX_PATH) + { + WCMD_output_asis(WCMD_LoadMessage(WCMD_LINETOOLONG)); + return; + } + strcpyW(stemofsearch, param1); } else { @@ -1584,22 +1591,17 @@ WCHAR *WCMD_LoadMessage(UINT id) { * Dumps out the parsed command line to ensure syntax is correct */ static void WCMD_DumpCommands(CMD_LIST *commands) { - WCHAR buffer[MAXSTRING]; CMD_LIST *thisCmd = commands; - const WCHAR fmt[] = {'%','p',' ','%','d',' ','%','2','.','2','d',' ', - '%','p',' ','%','s',' ','R','e','d','i','r',':', - '%','s','\0'}; WINE_TRACE("Parsed line:\n"); while (thisCmd != NULL) { - sprintfW(buffer, fmt, + WINE_TRACE("%p %d %2.2d %p %s Redir:%s\n", thisCmd, thisCmd->prevDelim, thisCmd->bracketDepth, thisCmd->nextcommand, - thisCmd->command, - thisCmd->redirects); - WINE_TRACE("%s\n", wine_dbgstr_w(buffer)); + wine_dbgstr_w(thisCmd->command), + wine_dbgstr_w(thisCmd->redirects)); thisCmd = thisCmd->nextcommand; } } diff --git a/programs/expand/expand.c b/programs/expand/expand.c index 1118f085929..9c78f969451 100644 --- a/programs/expand/expand.c +++ b/programs/expand/expand.c @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) { fprintf( stderr, "Usage:\n" ); fprintf( stderr, "\t%s infile outfile\n", argv[0] ); - fprintf( stderr, "\t%s /r infile \n", argv[0] ); + fprintf( stderr, "\t%s /r infile\n", argv[0] ); return 1; } diff --git a/programs/regedit/framewnd.c b/programs/regedit/framewnd.c index 6c8745ea41a..d88ef0ef075 100644 --- a/programs/regedit/framewnd.c +++ b/programs/regedit/framewnd.c @@ -87,7 +87,7 @@ static void OnEnterMenuLoop(HWND hWnd) /* Update the status bar pane sizes */ nParts = -1; - SendMessageW(hStatusBar, SB_SETPARTS, 1, (long)&nParts); + SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts); bInMenuLoop = TRUE; SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)&empty); } diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index 47f98328ea1..55b0d5fbdc7 100644 --- a/programs/regedit/regproc.c +++ b/programs/regedit/regproc.c @@ -732,12 +732,14 @@ static void processRegLinesW(FILE *in) ULONG lineSize = REG_VAL_BUF_SIZE; size_t CharsInBuf = -1; - WCHAR* s; /* The pointer into line for where the current fgets should read */ + WCHAR* s; /* The pointer into buf for where the current fgets should read */ + WCHAR* line; /* The start of the current line */ buf = HeapAlloc(GetProcessHeap(), 0, lineSize * sizeof(WCHAR)); CHECK_ENOUGH_MEMORY(buf); s = buf; + line = buf; while(!feof(in)) { size_t size_remaining; @@ -757,6 +759,7 @@ static void processRegLinesW(FILE *in) new_buffer = NULL; CHECK_ENOUGH_MEMORY(new_buffer); buf = new_buffer; + line = buf; s = buf + lineSize - size_remaining; lineSize = new_size; size_remaining = lineSize - (s-buf); @@ -787,14 +790,21 @@ static void processRegLinesW(FILE *in) /* If we didn't read the eol nor the eof go around for the rest */ while(1) { - s_eol = strchrW(s, '\n'); - - if(!s_eol) + s_eol = strchrW(line, '\n'); + + if(!s_eol) { + /* Move the stub of the line to the start of the buffer so + * we get the maximum space to read into, and so we don't + * have to recalculate 'line' if the buffer expands */ + MoveMemory(buf, line, (strlenW(line)+1) * sizeof(WCHAR)); + line = buf; + s = strchrW(line, '\0'); break; + } /* If it is a comment line then discard it and go around again */ - if (*s == '#') { - s = s_eol + 1; + if (*line == '#') { + line = s_eol + 1; continue; } @@ -811,7 +821,7 @@ static void processRegLinesW(FILE *in) if(*(s_eol-1) == '\r') s_eol--; - MoveMemory(s_eol - 1, NextLine, (CharsInBuf - (NextLine - buf) + 1)*sizeof(WCHAR)); + MoveMemory(s_eol - 1, NextLine, (CharsInBuf - (NextLine - s) + 1)*sizeof(WCHAR)); CharsInBuf -= NextLine - s_eol + 1; s_eol = 0; continue; @@ -827,8 +837,8 @@ static void processRegLinesW(FILE *in) if(!s_eol) break; - processRegEntry(s, TRUE); - s = s_eol + 1; + processRegEntry(line, TRUE); + line = s_eol + 1; s_eol = 0; continue; /* That is the full virtual line */ } diff --git a/programs/taskmgr/taskmgr.c b/programs/taskmgr/taskmgr.c index 8ba832e9028..b30ed8ed4c5 100644 --- a/programs/taskmgr/taskmgr.c +++ b/programs/taskmgr/taskmgr.c @@ -151,7 +151,7 @@ static BOOL OnCreate(HWND hWnd) nParts[0] = 100; nParts[1] = 210; nParts[2] = 400; - SendMessageW(hStatusWnd, SB_SETPARTS, 3, (long)nParts); + SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM)nParts); /* Create tab pages */ hTabWnd = GetDlgItem(hWnd, IDC_TAB); @@ -518,7 +518,7 @@ static void TaskManager_OnEnterMenuLoop(HWND hWnd) /* Update the status bar pane sizes */ nParts = -1; - SendMessageW(hStatusWnd, SB_SETPARTS, 1, (long)&nParts); + SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM)&nParts); bInMenuLoop = TRUE; SendMessageW(hStatusWnd, SB_SETTEXTW, 0, 0); } @@ -538,7 +538,7 @@ static void TaskManager_OnExitMenuLoop(HWND hWnd) nParts[0] = 100; nParts[1] = 210; nParts[2] = rc.right; - SendMessageW(hStatusWnd, SB_SETPARTS, 3, (long)nParts); + SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM)nParts); SendMessageW(hStatusWnd, SB_SETTEXT, 0, 0); wsprintfW(text, wszCPU_Usage, PerfDataGetProcessorUsage()); SendMessageW(hStatusWnd, SB_SETTEXTW, 1, (LPARAM)text); diff --git a/programs/uninstaller/Makefile.in b/programs/uninstaller/Makefile.in index 3b151a7de16..0f7e0e462e5 100644 --- a/programs/uninstaller/Makefile.in +++ b/programs/uninstaller/Makefile.in @@ -5,7 +5,8 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = uninstaller.exe APPMODE = -mconsole -municode -IMPORTS = shlwapi shell32 user32 gdi32 advapi32 kernel32 +IMPORTS = advapi32 kernel32 +DELAYIMPORTS = shlwapi shell32 user32 gdi32 C_SRCS = \ main.c diff --git a/programs/uninstaller/main.c b/programs/uninstaller/main.c index 1eaa3f30bf4..302d834ad03 100644 --- a/programs/uninstaller/main.c +++ b/programs/uninstaller/main.c @@ -45,8 +45,6 @@ static unsigned int numentries = 0; static int list_need_update = 1; static int oldsel = -1; static WCHAR *sFilter; -static WCHAR sAppName[MAX_STRING_LEN]; -static WCHAR sUninstallFailed[MAX_STRING_LEN]; static int FetchUninstallInformation(void); static void UninstallProgram(void); @@ -123,7 +121,6 @@ static void RemoveSpecificProgram(WCHAR *nameW) int wmain(int argc, WCHAR *argv[]) { LPCWSTR token = NULL; - HINSTANCE hInst = GetModuleHandleW(0); static const WCHAR listW[] = { '-','-','l','i','s','t',0 }; static const WCHAR removeW[] = { '-','-','r','e','m','o','v','e',0 }; int i = 1; @@ -156,10 +153,6 @@ int wmain(int argc, WCHAR *argv[]) } } - /* Load MessageBox's strings */ - LoadStringW(hInst, IDS_APPNAME, sAppName, sizeof(sAppName)/sizeof(WCHAR)); - LoadStringW(hInst, IDS_UNINSTALLFAILED, sUninstallFailed, sizeof(sUninstallFailed)/sizeof(WCHAR)); - /* Start the GUI control panel */ Control_RunDLL(GetDesktopWindow(), 0, "appwiz.cpl", SW_SHOW); return 1; @@ -267,6 +260,12 @@ static void UninstallProgram(void) } else { + WCHAR sAppName[MAX_STRING_LEN]; + WCHAR sUninstallFailed[MAX_STRING_LEN]; + HINSTANCE hInst = GetModuleHandleW(0); + + LoadStringW(hInst, IDS_APPNAME, sAppName, sizeof(sAppName)/sizeof(WCHAR)); + LoadStringW(hInst, IDS_UNINSTALLFAILED, sUninstallFailed, sizeof(sUninstallFailed)/sizeof(WCHAR)); wsprintfW(errormsg, sUninstallFailed, entries[i].command); if(MessageBoxW(0, errormsg, sAppName, MB_YESNO | MB_ICONQUESTION)==IDYES) { diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c index 0d6d05860fa..3638463374a 100644 --- a/programs/winedbg/be_i386.c +++ b/programs/winedbg/be_i386.c @@ -173,10 +173,11 @@ static void be_i386_all_print_context(HANDLE hThread, const CONTEXT* ctx) dbg_printf(")\n"); /* Here are the rest of the registers */ - dbg_printf(" FLES:%08x ", (unsigned int) ctx->FloatSave.ErrorSelector); - dbg_printf(" FLDO:%08x ", (unsigned int) ctx->FloatSave.DataOffset); - dbg_printf(" FLDS:%08x ", (unsigned int) ctx->FloatSave.DataSelector); - dbg_printf(" FLCNS:%08x \n", (unsigned int) ctx->FloatSave.Cr0NpxState); + dbg_printf(" FLES:%08x FLDO:%08x FLDS:%08x FLCNS:%08x\n", + ctx->FloatSave.ErrorSelector, + ctx->FloatSave.DataOffset, + ctx->FloatSave.DataSelector, + ctx->FloatSave.Cr0NpxState); /* Now for the floating point registers */ dbg_printf("Floating Point Registers:\n"); diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c index be6e6c53e31..ddb75a2d188 100644 --- a/programs/winedbg/break.c +++ b/programs/winedbg/break.c @@ -918,7 +918,7 @@ void break_restart_execution(int count) if (mode == dbg_exec_step_into_line && symbol_get_function_line_status(&addr) == dbg_no_line_info) { - dbg_printf("Single stepping until exit from function, \n" + dbg_printf("Single stepping until exit from function,\n" "which has no line number information.\n"); ret_mode = mode = dbg_exec_finish; } diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index 9f19b630937..ef5469f199b 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -562,7 +562,7 @@ static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx) struct dbg_type type; type.module = sym->ModBase; type.id = sym->TypeIndex; - dbg_printf("Mod: %08x ID: %08lx \n", type.module, type.id); + dbg_printf("Mod: %08x ID: %08lx\n", type.module, type.id); types_print_type(&type, TRUE); dbg_printf("\n"); return TRUE; diff --git a/programs/winetest/main.c b/programs/winetest/main.c index 2df81fa61ee..a07e3d96fe7 100644 --- a/programs/winetest/main.c +++ b/programs/winetest/main.c @@ -564,6 +564,7 @@ extract_test_proc (HMODULE hModule, LPCTSTR lpszType, *strstr(dllname, testexe) = 0; wine_tests[nr_of_files].maindllpath = NULL; + strcpy(filename, dllname); dll = LoadLibraryExA(dllname, NULL, LOAD_LIBRARY_AS_DATAFILE); if (!dll && pLoadLibraryShim) { @@ -580,6 +581,7 @@ extract_test_proc (HMODULE hModule, LPCTSTR lpszType, * the tests for this dll. */ GetModuleFileNameA(dll, dllpath, MAX_PATH); + strcpy(filename, dllpath); *strrchr(dllpath, '\\') = '\0'; wine_tests[nr_of_files].maindllpath = xstrdup( dllpath ); } @@ -594,7 +596,6 @@ extract_test_proc (HMODULE hModule, LPCTSTR lpszType, xprintf (" %s=load error Gecko is not installed\n", dllname); return TRUE; } - GetModuleFileNameA(dll, filename, MAX_PATH); FreeLibrary(dll); if (!(err = get_subtests( tempdir, &wine_tests[nr_of_files], lpszName ))) diff --git a/programs/winhlp32/winhelp.c b/programs/winhlp32/winhelp.c index 02529eebd80..d62649ffa85 100644 --- a/programs/winhlp32/winhelp.c +++ b/programs/winhlp32/winhelp.c @@ -1263,8 +1263,7 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, { WINHELP_WINDOW *win; WINHELP_BUTTON *button; - RECT rect; - INT curPos, min, max, dy, keyDelta; + INT keyDelta; HWND hTextWnd; LRESULT ret; @@ -1379,42 +1378,23 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, case WM_KEYDOWN: keyDelta = 0; + win = (WINHELP_WINDOW*) GetWindowLongPtr(hWnd, 0); + hTextWnd = GetDlgItem(win->hMainWnd, CTL_ID_TEXT); switch (wParam) { case VK_UP: + SendMessage(hTextWnd, EM_SCROLL, SB_LINEUP, 0); + return 0; case VK_DOWN: - keyDelta = GetSystemMetrics(SM_CXVSCROLL); - if (wParam == VK_UP) - keyDelta = -keyDelta; - + SendMessage(hTextWnd, EM_SCROLL, SB_LINEDOWN, 0); + return 0; case VK_PRIOR: + SendMessage(hTextWnd, EM_SCROLL, SB_PAGEUP, 0); + return 0; case VK_NEXT: - win = (WINHELP_WINDOW*) GetWindowLongPtr(hWnd, 0); - hTextWnd = GetDlgItem(win->hMainWnd, CTL_ID_TEXT); - curPos = GetScrollPos(hTextWnd, SB_VERT); - GetScrollRange(hTextWnd, SB_VERT, &min, &max); - - if (keyDelta == 0) - { - GetClientRect(hTextWnd, &rect); - keyDelta = (rect.bottom - rect.top) / 2; - if (wParam == VK_PRIOR) - keyDelta = -keyDelta; - } - - curPos += keyDelta; - if (curPos > max) - curPos = max; - else if (curPos < min) - curPos = min; - - dy = GetScrollPos(hTextWnd, SB_VERT) - curPos; - SetScrollPos(hTextWnd, SB_VERT, curPos, TRUE); - ScrollWindow(hTextWnd, 0, dy, NULL, NULL); - UpdateWindow(hTextWnd); + SendMessage(hTextWnd, EM_SCROLL, SB_PAGEDOWN, 0); return 0; - case VK_ESCAPE: MACRO_Exit(); return 0; diff --git a/server/async.c b/server/async.c index 0a69f7ae5ee..91f0c44403e 100644 --- a/server/async.c +++ b/server/async.c @@ -214,7 +214,7 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co async->timeout = NULL; async->queue = (struct async_queue *)grab_object( queue ); async->completion = NULL; - if (queue->fd) fd_assign_completion( queue->fd, &async->completion, &async->comp_key ); + if (queue->fd) async->completion = fd_get_completion( queue->fd, &async->comp_key ); list_add_tail( &queue->queue, &async->queue_entry ); grab_object( async ); diff --git a/server/fd.c b/server/fd.c index c8b6f7aa702..d9688e1e0d9 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1940,10 +1940,16 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl return fd; } -void fd_assign_completion( struct fd *fd, struct completion **p_port, apc_param_t *p_key ) +struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key ) { *p_key = fd->comp_key; - *p_port = fd->completion ? (struct completion *)grab_object( fd->completion ) : NULL; + return fd->completion ? (struct completion *)grab_object( fd->completion ) : NULL; +} + +void fd_copy_completion( struct fd *src, struct fd *dst ) +{ + assert( !dst->completion ); + dst->completion = fd_get_completion( src, &dst->comp_key ); } /* flush a file buffers */ diff --git a/server/file.h b/server/file.h index 0eac537ac96..1aaa2847f1b 100644 --- a/server/file.h +++ b/server/file.h @@ -143,7 +143,8 @@ extern void async_set_result( struct object *obj, unsigned int status, extern int async_waiting( struct async_queue *queue ); extern void async_terminate( struct async *async, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status ); -extern void fd_assign_completion( struct fd *fd, struct completion **p_port, apc_param_t *p_key ); +extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key ); +extern void fd_copy_completion( struct fd *src, struct fd *dst ); /* access rights that require Unix read permission */ #define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA) diff --git a/server/named_pipe.c b/server/named_pipe.c index 1651a67ff46..539509e1c2a 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -605,7 +605,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a { case ps_idle_server: case ps_wait_connect: - if (blocking) + if (blocking && !is_overlapped( get_fd_options(fd) )) { async_data_t new_data = *async_data; if (!(wait_handle = alloc_wait_event( current->process ))) break; @@ -830,6 +830,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc server->fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->obj, server->options ); if (client->fd && server->fd) { + fd_copy_completion( server->ioctl_fd, server->fd ); if (server->state == ps_wait_open) fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS ); set_server_state( server, ps_connected_server ); diff --git a/tools/fnt2bdf.c b/tools/fnt2bdf.c index e6a53fa75cc..277764b4ef4 100644 --- a/tools/fnt2bdf.c +++ b/tools/fnt2bdf.c @@ -226,13 +226,13 @@ static int dump_bdf( fnt_fontS* cpe_font_struct, unsigned char* file_buffer) l_span = (int) (cpe_font_struct->dfCharTable[ic].charWidth-1)/8; - fprintf(fp, "STARTCHAR %d \n", ic); + fprintf(fp, "STARTCHAR %d\n", ic); fprintf(fp, "ENCODING %d\n", l_fchar); - fprintf(fp, "SWIDTH %d %d \n", + fprintf(fp, "SWIDTH %d %d\n", cpe_font_struct->dfCharTable[ic].charWidth*1000, 0); - fprintf(fp, "DWIDTH %d %d \n", + fprintf(fp, "DWIDTH %d %d\n", cpe_font_struct->dfCharTable[ic].charWidth, 0); fprintf(fp, "BBX %d %d %d %d\n", diff --git a/tools/widl/expr.c b/tools/widl/expr.c index 58d7a5b60ca..405b5def1b6 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -290,20 +290,18 @@ static int is_integer_type(const type_t *type) case TYPE_ENUM: return TRUE; case TYPE_BASIC: - switch (type_basic_get_fc(type)) + switch (type_basic_get_type(type)) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_INT3264: - case RPC_FC_UINT3264: - case RPC_FC_HYPER: + case TYPE_BASIC_INT8: + case TYPE_BASIC_INT16: + case TYPE_BASIC_INT32: + case TYPE_BASIC_INT64: + case TYPE_BASIC_INT: + case TYPE_BASIC_CHAR: + case TYPE_BASIC_HYPER: + case TYPE_BASIC_BYTE: + case TYPE_BASIC_WCHAR: + case TYPE_BASIC_ERROR_STATUS_T: return TRUE; default: return FALSE; @@ -316,8 +314,8 @@ static int is_integer_type(const type_t *type) static int is_float_type(const type_t *type) { return (type_get_type(type) == TYPE_BASIC && - (type_basic_get_fc(type) == RPC_FC_FLOAT || - type_basic_get_fc(type) == RPC_FC_DOUBLE)); + (type_basic_get_type(type) == TYPE_BASIC_FLOAT || + type_basic_get_type(type) == TYPE_BASIC_DOUBLE)); } static void check_scalar_type(const struct expr_loc *expr_loc, @@ -434,22 +432,22 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc case EXPR_TRUEFALSE: result.is_variable = FALSE; result.is_temporary = FALSE; - result.type = find_type("int", 0); + result.type = type_new_int(TYPE_BASIC_INT, 0); break; case EXPR_STRLIT: result.is_variable = FALSE; result.is_temporary = TRUE; - result.type = make_type(RPC_FC_RP, find_type("char", 0)); + result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL); break; case EXPR_WSTRLIT: result.is_variable = FALSE; result.is_temporary = TRUE; - result.type = make_type(RPC_FC_RP, find_type("wchar_t", 0)); + result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL); break; case EXPR_DOUBLE: result.is_variable = FALSE; - result.is_temporary = FALSE; - result.type = find_type("double", 0); + result.is_temporary = TRUE; + result.type = type_new_basic(TYPE_BASIC_DOUBLE); break; case EXPR_IDENTIFIER: { @@ -470,7 +468,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc check_scalar_type(expr_loc, cont_type, result.type); result.is_variable = FALSE; result.is_temporary = FALSE; - result.type = find_type("int", 0); + result.type = type_new_int(TYPE_BASIC_INT, 0); break; case EXPR_NOT: result = resolve_expression(expr_loc, cont_type, e->ref); @@ -491,14 +489,14 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc expr_loc->attr ? expr_loc->attr : ""); result.is_variable = FALSE; result.is_temporary = TRUE; - result.type = make_type(RPC_FC_RP, result.type); + result.type = type_new_pointer(RPC_FC_UP, result.type, NULL); break; case EXPR_PPTR: result = resolve_expression(expr_loc, cont_type, e->ref); if (result.type && is_ptr(result.type)) result.type = type_pointer_get_ref(result.type); else if(result.type && is_array(result.type) - && !result.type->declarray) + && type_array_is_decl_as_ptr(result.type)) result.type = type_array_get_element(result.type); else error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n", @@ -512,7 +510,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc case EXPR_SIZEOF: result.is_variable = FALSE; result.is_temporary = FALSE; - result.type = find_type("int", 0); + result.type = type_new_int(TYPE_BASIC_INT, 0); break; case EXPR_SHL: case EXPR_SHR: @@ -550,7 +548,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc check_scalar_type(expr_loc, cont_type, result_right.type); result.is_variable = FALSE; result.is_temporary = FALSE; - result.type = find_type("int", 0); + result.type = type_new_int(TYPE_BASIC_INT, 0); break; } case EXPR_MEMBER: diff --git a/tools/widl/header.c b/tools/widl/header.c index 4a8929faf86..9b6167e1913 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -183,7 +183,7 @@ static void write_enums(FILE *h, var_list_t *enums) int needs_space_after(type_t *t) { return (type_is_alias(t) || - (!is_ptr(t) && (!is_conformant_array(t) || t->declarray || (is_array(t) && t->name)))); + (!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name))); } void write_type_left(FILE *h, type_t *t, int declonly) @@ -191,11 +191,10 @@ void write_type_left(FILE *h, type_t *t, int declonly) if (!h) return; if (is_attr(t->attrs, ATTR_CONST) && - (type_is_alias(t) || t->declarray || !is_ptr(t))) + (type_is_alias(t) || !is_ptr(t))) fprintf(h, "const "); if (type_is_alias(t)) fprintf(h, "%s", t->name); - else if (t->declarray) write_type_left(h, type_array_get_element(t), declonly); else { switch (type_get_type_detect_alias(t)) { case TYPE_ENUM: @@ -244,24 +243,51 @@ void write_type_left(FILE *h, type_t *t, int declonly) if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const "); break; case TYPE_ARRAY: - if (t->name) + if (t->name && type_array_is_decl_as_ptr(t)) fprintf(h, "%s", t->name); else { write_type_left(h, type_array_get_element(t), declonly); - fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : ""); + if (type_array_is_decl_as_ptr(t)) + fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : ""); } break; case TYPE_BASIC: - if (t->sign > 0) fprintf(h, "signed "); - else if (t->sign < 0) fprintf(h, "unsigned "); - /* fall through */ + if (type_basic_get_type(t) != TYPE_BASIC_HYPER) + { + if (type_basic_get_sign(t) < 0) fprintf(h, "signed "); + else if (type_basic_get_sign(t) > 0) fprintf(h, "unsigned "); + } + switch (type_basic_get_type(t)) + { + case TYPE_BASIC_INT8: fprintf(h, "small"); break; + case TYPE_BASIC_INT16: fprintf(h, "short"); break; + case TYPE_BASIC_INT32: fprintf(h, "long"); break; + case TYPE_BASIC_INT: fprintf(h, "int"); break; + case TYPE_BASIC_INT64: fprintf(h, "__int64"); break; + case TYPE_BASIC_BYTE: fprintf(h, "byte"); break; + case TYPE_BASIC_CHAR: fprintf(h, "char"); break; + case TYPE_BASIC_WCHAR: fprintf(h, "wchar_t"); break; + case TYPE_BASIC_FLOAT: fprintf(h, "float"); break; + case TYPE_BASIC_DOUBLE: fprintf(h, "double"); break; + case TYPE_BASIC_ERROR_STATUS_T: fprintf(h, "error_status_t"); break; + case TYPE_BASIC_HANDLE: fprintf(h, "handle_t"); break; + case TYPE_BASIC_HYPER: + if (type_basic_get_sign(t) > 0) + fprintf(h, "MIDL_uhyper"); + else + fprintf(h, "hyper"); + break; + } + break; case TYPE_INTERFACE: case TYPE_MODULE: case TYPE_COCLASS: - case TYPE_VOID: fprintf(h, "%s", t->name); break; + case TYPE_VOID: + fprintf(h, "void"); + break; case TYPE_ALIAS: case TYPE_FUNCTION: /* handled elsewhere */ @@ -275,12 +301,14 @@ void write_type_right(FILE *h, type_t *t, int is_field) { if (!h) return; - if (t->declarray) { + if (type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t)) { if (is_conformant_array(t)) { fprintf(h, "[%s]", is_field ? "1" : ""); t = type_array_get_element(t); } - for ( ; t->declarray; t = type_array_get_element(t)) + for ( ; + type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t); + t = type_array_get_element(t)) fprintf(h, "[%u]", type_array_get_dim(t)); } } @@ -388,7 +416,7 @@ void check_for_additional_prototype_types(const var_list_t *list) break; } if ((type_get_type(type) != TYPE_BASIC || - type_basic_get_fc(type) != RPC_FC_BIND_PRIMITIVE) && + type_basic_get_type(type) != TYPE_BASIC_HANDLE) && is_attr(type->attrs, ATTR_HANDLE)) { if (!generic_handle_registered(name)) { @@ -546,8 +574,11 @@ const var_t* get_explicit_handle_var(const var_t *func) return NULL; LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - if (var->type->type == RPC_FC_BIND_PRIMITIVE) + { + const type_t *type = var->type; + if (type_get_type(type) == TYPE_BASIC && type_basic_get_type(type) == TYPE_BASIC_HANDLE) return var; + } return NULL; } @@ -555,8 +586,11 @@ const var_t* get_explicit_handle_var(const var_t *func) const type_t* get_explicit_generic_handle_type(const var_t* var) { const type_t *t; - for (t = var->type; is_ptr(t); t = type_pointer_get_ref(t)) - if (t->type != RPC_FC_BIND_PRIMITIVE && is_attr(t->attrs, ATTR_HANDLE)) + for (t = var->type; + is_ptr(t) || type_is_alias(t); + t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t)) + if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) && + is_attr(t->attrs, ATTR_HANDLE)) return t; return NULL; } diff --git a/tools/widl/header.h b/tools/widl/header.h index 0c0c0a43ff4..d4b3b88f32e 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -75,7 +75,9 @@ static inline int is_string_type(const attr_list_t *attrs, const type_t *type) static inline int is_context_handle(const type_t *type) { const type_t *t; - for (t = type; is_ptr(t); t = type_pointer_get_ref(t)) + for (t = type; + is_ptr(t) || type_is_alias(t); + t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t)) if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) return 1; return 0; diff --git a/tools/widl/parser.l b/tools/widl/parser.l index dba27ea7387..55a73c75be1 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -341,7 +341,6 @@ static const struct keyword attr_keywords[] = {"requestedit", tREQUESTEDIT}, {"restricted", tRESTRICTED}, {"retval", tRETVAL}, - {"single", tSINGLE}, {"size_is", tSIZEIS}, {"source", tSOURCE}, {"strict_context_handle", tSTRICTCONTEXTHANDLE}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index fb7dcaaeb23..fe3db868fd3 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -65,7 +65,7 @@ #define YYERROR_VERBOSE -unsigned char pointer_default = RPC_FC_UP; +static unsigned char pointer_default = RPC_FC_UP; static int is_object_interface = FALSE; typedef struct list typelist_t; @@ -89,7 +89,6 @@ typedef struct _decl_spec_t typelist_t incomplete_types = LIST_INIT(incomplete_types); -static void add_incomplete(type_t *t); static void fix_incomplete(void); static void fix_incomplete_types(type_t *complete_type); @@ -106,30 +105,18 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); -static var_list_t *append_var(var_list_t *list, var_t *var); static var_list_t *append_var_list(var_list_t *list, var_list_t *vars); -static var_t *make_var(char *name); static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p); static declarator_t *make_declarator(var_t *var); static func_list_t *append_func(func_list_t *list, func_t *func); static func_t *make_func(var_t *def); -static type_t *make_class(char *name); static type_t *make_safearray(type_t *type); -static type_t *make_builtin(char *name); -static type_t *make_int(int sign); static typelib_t *make_library(const char *name, const attr_list_t *attrs); static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type); -static type_t *type_new_enum(char *name, var_list_t *enums); -static type_t *type_new_struct(char *name, int defined, var_list_t *fields); -static type_t *type_new_nonencapsulated_union(char *name, var_list_t *fields); -static type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases); - -static type_t *reg_type(type_t *type, const char *name, int t); static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs); static type_t *find_type_or_error(const char *name, int t); static type_t *find_type_or_error2(char *name, int t); -static type_t *get_type(unsigned char type, char *name, int t); static var_t *reg_const(var_t *var); @@ -165,10 +152,6 @@ static statement_t *make_statement_import(const char *str); static statement_t *make_statement_typedef(var_list_t *names); static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt); -#define tsENUM 1 -#define tsSTRUCT 2 -#define tsUNION 3 - %} %union { attr_t *attr; @@ -271,7 +254,6 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s %token tSAFEARRAY %token tSHORT %token tSIGNED -%token tSINGLE %token tSIZEIS tSIZEOF %token tSMALL %token tSOURCE @@ -611,14 +593,14 @@ enum_list: enum { if (!$1->eval) enum: ident '=' expr_int_const { $$ = reg_const($1); $$->eval = $3; - $$->type = make_int(0); + $$->type = type_new_int(TYPE_BASIC_INT, 0); } | ident { $$ = reg_const($1); - $$->type = make_int(0); + $$->type = type_new_int(TYPE_BASIC_INT, 0); } ; -enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, $4); } +enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, TRUE, $4); } ; m_exprs: m_expr { $$ = append_expr( NULL, $1 ); } @@ -769,49 +751,33 @@ ident: aIDENTIFIER { $$ = make_var($1); } | aKNOWNTYPE { $$ = make_var($1); } ; -base_type: tBYTE { $$ = make_builtin($1); } - | tWCHAR { $$ = make_builtin($1); } +base_type: tBYTE { $$ = find_type_or_error($1, 0); } + | tWCHAR { $$ = find_type_or_error($1, 0); } | int_std - | tSIGNED int_std { $$ = $2; $$->sign = 1; } - | tUNSIGNED int_std { $$ = $2; $$->sign = -1; - switch ($$->type) { - case RPC_FC_CHAR: break; - case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break; - case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break; - case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break; - case RPC_FC_HYPER: - if ($$->name[0] == 'h') /* hyper, as opposed to __int64 */ - { - $$ = type_new_alias($$, "MIDL_uhyper"); - $$->sign = 0; - } - break; - default: break; - } - } - | tUNSIGNED { $$ = make_int(-1); } - | tFLOAT { $$ = make_builtin($1); } - | tSINGLE { $$ = find_type("float", 0); } - | tDOUBLE { $$ = make_builtin($1); } - | tBOOLEAN { $$ = make_builtin($1); } - | tERRORSTATUST { $$ = make_builtin($1); } - | tHANDLET { $$ = make_builtin($1); } + | tSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), -1); } + | tUNSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), 1); } + | tUNSIGNED { $$ = type_new_int(TYPE_BASIC_INT, 1); } + | tFLOAT { $$ = find_type_or_error($1, 0); } + | tDOUBLE { $$ = find_type_or_error($1, 0); } + | tBOOLEAN { $$ = find_type_or_error($1, 0); } + | tERRORSTATUST { $$ = find_type_or_error($1, 0); } + | tHANDLET { $$ = find_type_or_error($1, 0); } ; m_int: | tINT ; -int_std: tINT { $$ = make_builtin($1); } - | tSHORT m_int { $$ = make_builtin($1); } - | tSMALL { $$ = make_builtin($1); } - | tLONG m_int { $$ = make_builtin($1); } - | tHYPER m_int { $$ = make_builtin($1); } - | tINT64 { $$ = make_builtin($1); } - | tCHAR { $$ = make_builtin($1); } +int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); } + | tSHORT m_int { $$ = type_new_int(TYPE_BASIC_INT16, 0); } + | tSMALL { $$ = type_new_int(TYPE_BASIC_INT8, 0); } + | tLONG m_int { $$ = type_new_int(TYPE_BASIC_INT32, 0); } + | tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); } + | tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); } + | tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); } ; -coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } +coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); } | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0); if (type_get_type_detect_alias($$) != TYPE_COCLASS) error_loc("%s was not declared a coclass at %s:%d\n", @@ -838,8 +804,8 @@ coclass_int: m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } ; -dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); } - | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); } +dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, 0); } + | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, 0); } ; dispinterfacehdr: attributes dispinterface { attr_t *attrs; @@ -876,8 +842,8 @@ inherit: { $$ = NULL; } | ':' aKNOWNTYPE { $$ = find_type_or_error2($2, 0); } ; -interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); } - | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); } +interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, 0); } + | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, 0); } ; interfacehdr: attributes interface { $$.interface = $2; @@ -962,7 +928,7 @@ decl_spec_no_type: declarator: '*' m_type_qual_list declarator %prec PPTR - { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(NULL, $2)); } + { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } | callconv declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } | direct_declarator ; @@ -996,15 +962,15 @@ pointer_type: structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, TRUE, $4); } ; -type: tVOID { $$ = find_type_or_error("void", 0); } +type: tVOID { $$ = type_new_void(); } | aKNOWNTYPE { $$ = find_type_or_error($1, 0); } | base_type { $$ = $1; } | enumdef { $$ = $1; } - | tENUM aIDENTIFIER { $$ = find_type_or_error2($2, tsENUM); } + | tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); } | structdef { $$ = $1; } | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); } | uniondef { $$ = $1; } - | tUNION aIDENTIFIER { $$ = find_type_or_error2($2, tsUNION); } + | tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, FALSE, NULL); } | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); } ; @@ -1015,7 +981,7 @@ typedef: tTYPEDEF m_attributes decl_spec declarator_list ; uniondef: tUNION t_ident '{' ne_union_fields '}' - { $$ = type_new_nonencapsulated_union($2, $4); } + { $$ = type_new_nonencapsulated_union($2, TRUE, $4); } | tUNION t_ident tSWITCH '(' s_field ')' m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9); } @@ -1028,49 +994,26 @@ version: %% -static void decl_builtin(const char *name, unsigned char type) +static void decl_builtin_basic(const char *name, enum type_basic_type type) { - type_t *t = make_type(type, NULL); - t->name = xstrdup(name); + type_t *t = type_new_basic(type); reg_type(t, name, 0); } -static type_t *make_builtin(char *name) -{ - /* NAME is strdup'd in the lexer */ - type_t *t = duptype(find_type_or_error(name, 0), 0); - t->name = name; - return t; -} - -static type_t *make_int(int sign) +static void decl_builtin_alias(const char *name, type_t *t) { - type_t *t = duptype(find_type_or_error("int", 0), 1); - - t->sign = sign; - if (sign < 0) - t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; - - return t; + reg_type(type_new_alias(t, name), name, 0); } void init_types(void) { - decl_builtin("void", 0); - decl_builtin("byte", RPC_FC_BYTE); - decl_builtin("wchar_t", RPC_FC_WCHAR); - decl_builtin("int", RPC_FC_LONG); /* win32 */ - decl_builtin("short", RPC_FC_SHORT); - decl_builtin("small", RPC_FC_SMALL); - decl_builtin("long", RPC_FC_LONG); - decl_builtin("hyper", RPC_FC_HYPER); - decl_builtin("__int64", RPC_FC_HYPER); - decl_builtin("char", RPC_FC_CHAR); - decl_builtin("float", RPC_FC_FLOAT); - decl_builtin("double", RPC_FC_DOUBLE); - decl_builtin("boolean", RPC_FC_BYTE); - decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); - decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); + decl_builtin_basic("byte", TYPE_BASIC_BYTE); + decl_builtin_basic("wchar_t", TYPE_BASIC_WCHAR); + decl_builtin_basic("float", TYPE_BASIC_FLOAT); + decl_builtin_basic("double", TYPE_BASIC_DOUBLE); + decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T); + decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE); + decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE)); } static str_list_t *append_str(str_list_t *list, char *str) @@ -1283,98 +1226,6 @@ void clear_all_offsets(void) node->data.typestring_offset = node->data.ptrdesc = 0; } -type_t *make_type(unsigned char type, type_t *ref) -{ - type_t *t = alloc_type(); - t->name = NULL; - t->type = type; - t->ref = ref; - t->attrs = NULL; - t->orig = NULL; - memset(&t->details, 0, sizeof(t->details)); - t->typestring_offset = 0; - t->ptrdesc = 0; - t->declarray = FALSE; - t->ignore = (parse_only != 0); - t->sign = 0; - t->defined = FALSE; - t->written = FALSE; - t->user_types_registered = FALSE; - t->tfswrite = FALSE; - t->checked = FALSE; - t->is_alias = FALSE; - t->typelib_idx = -1; - init_loc_info(&t->loc_info); - return t; -} - -static type_t *type_new_enum(char *name, var_list_t *enums) -{ - type_t *t = get_type(RPC_FC_ENUM16, name, tsENUM); - if (enums) - { - t->details.enumeration = xmalloc(sizeof(*t->details.enumeration)); - t->details.enumeration->enums = enums; - } - else - t->details.enumeration = NULL; - t->defined = TRUE; - return t; -} - -static type_t *type_new_struct(char *name, int defined, var_list_t *fields) -{ - type_t *tag_type = name ? find_type(name, tsSTRUCT) : NULL; - type_t *t = make_type(RPC_FC_STRUCT, NULL); - t->name = name; - if (defined || (tag_type && tag_type->details.structure)) - { - if (tag_type && tag_type->details.structure) - { - t->details.structure = tag_type->details.structure; - t->type = tag_type->type; - } - else if (defined) - { - t->details.structure = xmalloc(sizeof(*t->details.structure)); - t->details.structure->fields = fields; - t->defined = TRUE; - } - } - if (name) - { - if (fields) - reg_type(t, name, tsSTRUCT); - else - add_incomplete(t); - } - return t; -} - -static type_t *type_new_nonencapsulated_union(char *name, var_list_t *fields) -{ - type_t *t = get_type(RPC_FC_NON_ENCAPSULATED_UNION, name, tsUNION); - t->details.structure = xmalloc(sizeof(*t->details.structure)); - t->details.structure->fields = fields; - t->defined = TRUE; - return t; -} - -static type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases) -{ - type_t *t = get_type(RPC_FC_ENCAPSULATED_UNION, name, tsUNION); - if (!union_field) union_field = make_var( xstrdup("tagged_union") ); - union_field->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); - union_field->type->details.structure = xmalloc(sizeof(*union_field->type->details.structure)); - union_field->type->details.structure->fields = cases; - union_field->type->defined = TRUE; - t->details.structure = xmalloc(sizeof(*t->details.structure)); - t->details.structure->fields = append_var( NULL, switch_field ); - t->details.structure->fields = append_var( t->details.structure->fields, union_field ); - t->defined = TRUE; - return t; -} - static void type_function_add_head_arg(type_t *type, var_t *arg) { if (!type->details.function->args) @@ -1390,9 +1241,10 @@ static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type) type_t *ptrchain_type; if (!ptrchain) return type; - for (ptrchain_type = ptrchain; ptrchain_type->ref; ptrchain_type = ptrchain_type->ref) + for (ptrchain_type = ptrchain; type_pointer_get_ref(ptrchain_type); ptrchain_type = type_pointer_get_ref(ptrchain_type)) ; - ptrchain_type->ref = type; + assert(ptrchain_type->type_type == TYPE_POINTER); + ptrchain_type->details.pointer.ref = type; return ptrchain; } @@ -1426,9 +1278,8 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, v->type = append_ptrchain_type(decl ? decl->type : NULL, type); v->stgclass = decl_spec->stgclass; - /* the highest level of pointer specified should default to the var's ptr attr - * or (RPC_FC_RP if not specified and it's a top level ptr), not - * pointer_default so we need to fix that up here */ + /* check for pointer attribute being applied to non-pointer, non-array + * type */ if (!arr) { int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); @@ -1444,25 +1295,20 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, else break; } - if (ptr && is_ptr(ptr) && (ptr_attr || top)) + if (is_ptr(ptr)) { if (ptr_attr && ptr_attr != RPC_FC_UP && type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE) warning_loc_info(&v->loc_info, "%s: pointer attribute applied to interface " "pointer type has no effect\n", v->name); - if (top && !ptr_attr) - ptr_attr = RPC_FC_RP; - if (ptr_attr != (*pt)->type) + if (!ptr_attr && top && (*pt)->details.pointer.def_fc != RPC_FC_RP) { - /* create new type to avoid changing original type */ - /* FIXME: this is a horrible hack - we might be changing the pointer - * type of an alias here, so we also need corresponding hacks in - * get_pointer_fc to handle this. The type of pointer that the type - * ends up having is context sensitive and so we shouldn't be - * setting it here, but rather determining it when it is used. */ + /* FIXME: this is a horrible hack to cope with the issue that we + * store an offset to the typeformat string in the type object, but + * two typeformat strings may be written depending on whether the + * pointer is a toplevel parameter or not */ *pt = duptype(*pt, 1); - (*pt)->type = ptr_attr; } } else if (ptr_attr) @@ -1475,9 +1321,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, if (is_attr(v->attrs, ATTR_V1ENUM)) { - if (type_get_type_detect_alias(v->type) == TYPE_ENUM) - v->type->type = RPC_FC_ENUM32; - else + if (type_get_type_detect_alias(v->type) != TYPE_ENUM) error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name); } @@ -1506,9 +1350,10 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, else sizeless = TRUE; - *ptype = type_new_array(NULL, *ptype, TRUE, + *ptype = type_new_array(NULL, *ptype, FALSE, dim->is_const ? dim->cval : 0, - dim->is_const ? NULL : dim, NULL); + dim->is_const ? NULL : dim, NULL, + pointer_default); } ptype = &v->type; @@ -1522,18 +1367,21 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, error_loc("%s: cannot specify size_is for a fixed sized array\n", v->name); else *ptype = type_new_array((*ptype)->name, - type_array_get_element(*ptype), TRUE, - 0, dim, NULL); + type_array_get_element(*ptype), FALSE, + 0, dim, NULL, 0); } else if (is_ptr(*ptype)) - *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), FALSE, - 0, dim, NULL); + *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE, + 0, dim, NULL, pointer_default); else error_loc("%s: size_is attribute applied to illegal type\n", v->name); } - ptype = &(*ptype)->ref; - if (*ptype == NULL) + if (is_ptr(*ptype)) + ptype = &(*ptype)->details.pointer.ref; + else if (is_array(*ptype)) + ptype = &(*ptype)->details.array.elem; + else error_loc("%s: too many expressions in size_is attribute\n", v->name); } @@ -1546,17 +1394,20 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, { *ptype = type_new_array((*ptype)->name, type_array_get_element(*ptype), - (*ptype)->declarray, + type_array_is_decl_as_ptr(*ptype), type_array_get_dim(*ptype), type_array_get_conformance(*ptype), - dim); + dim, type_array_get_ptr_default_fc(*ptype)); } else error_loc("%s: length_is attribute applied to illegal type\n", v->name); } - ptype = &(*ptype)->ref; - if (*ptype == NULL) + if (is_ptr(*ptype)) + ptype = &(*ptype)->details.pointer.ref; + else if (is_array(*ptype)) + ptype = &(*ptype)->details.array.elem; + else error_loc("%s: too many expressions in length_is attribute\n", v->name); } @@ -1571,7 +1422,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft)) ; assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION); - ft->ref = return_type; + ft->details.function->rettype = return_type; /* move calling convention attribute, if present, from pointer nodes to * function node */ for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t)) @@ -1629,7 +1480,7 @@ static ifref_t *make_ifref(type_t *iface) return l; } -static var_list_t *append_var(var_list_t *list, var_t *var) +var_list_t *append_var(var_list_t *list, var_t *var) { if (!var) return list; if (!list) @@ -1653,7 +1504,7 @@ static var_list_t *append_var_list(var_list_t *list, var_list_t *vars) return list; } -static var_t *make_var(char *name) +var_t *make_var(char *name) { var_t *v = xmalloc(sizeof(var_t)); v->name = name; @@ -1705,18 +1556,10 @@ static func_t *make_func(var_t *def) return f; } -static type_t *make_class(char *name) -{ - type_t *c = make_type(RPC_FC_COCLASS, NULL); - c->name = name; - return c; -} - static type_t *make_safearray(type_t *type) { - type_t *sa = find_type_or_error("SAFEARRAY", 0); - sa->ref = type; - return make_type(pointer_default, sa); + return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0, + NULL, NULL, RPC_FC_RP); } static typelib_t *make_library(const char *name, const attr_list_t *attrs) @@ -1754,7 +1597,7 @@ struct rtype { struct rtype *type_hash[HASHMAX]; -static type_t *reg_type(type_t *type, const char *name, int t) +type_t *reg_type(type_t *type, const char *name, int t) { struct rtype *nt; int hash; @@ -1782,7 +1625,7 @@ static int is_incomplete(const type_t *t) type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION); } -static void add_incomplete(type_t *t) +void add_incomplete(type_t *t) { struct typenode *tn = xmalloc(sizeof *tn); tn->type = t; @@ -1842,9 +1685,9 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at t = type_pointer_get_ref(t); if (type_get_type(t) != TYPE_BASIC && - (type_basic_get_fc(t) != RPC_FC_CHAR && - type_basic_get_fc(t) != RPC_FC_BYTE && - type_basic_get_fc(t) != RPC_FC_WCHAR)) + (get_basic_fc(t) != RPC_FC_CHAR && + get_basic_fc(t) != RPC_FC_BYTE && + get_basic_fc(t) != RPC_FC_WCHAR)) { decl = LIST_ENTRY( list_head( decls ), const declarator_t, entry ); error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", @@ -1925,7 +1768,7 @@ int is_type(const char *name) return find_type(name, 0) != NULL; } -static type_t *get_type(unsigned char type, char *name, int t) +type_t *get_type(enum type_type type, char *name, int t) { type_t *tp; if (name) { @@ -1935,7 +1778,7 @@ static type_t *get_type(unsigned char type, char *name, int t) return tp; } } - tp = make_type(type, NULL); + tp = make_type(type); tp->name = name; if (!name) return tp; return reg_type(tp, name, t); @@ -2275,18 +2118,18 @@ static int is_allowed_conf_type(const type_t *type) case TYPE_ENUM: return TRUE; case TYPE_BASIC: - switch (type_basic_get_fc(type)) + switch (type_basic_get_type(type)) { - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_BYTE: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ERROR_STATUS_T: + case TYPE_BASIC_INT8: + case TYPE_BASIC_INT16: + case TYPE_BASIC_INT32: + case TYPE_BASIC_INT64: + case TYPE_BASIC_INT: + case TYPE_BASIC_CHAR: + case TYPE_BASIC_HYPER: + case TYPE_BASIC_BYTE: + case TYPE_BASIC_WCHAR: + case TYPE_BASIC_ERROR_STATUS_T: return TRUE; default: return FALSE; diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 2999b3f5c54..b8ccdaccd08 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -156,10 +156,8 @@ int cant_be_null(const var_t *v) switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS)) { case TGT_ARRAY: - /* FIXME: work out pointer type */ - return 0; case TGT_POINTER: - return (get_pointer_fc(v->type) == RPC_FC_RP); + return (get_pointer_fc(v->type, v->attrs, TRUE) == RPC_FC_RP); case TGT_CTXT_HANDLE_POINTER: return TRUE; default: @@ -248,7 +246,7 @@ static void free_variable( const var_t *arg, const char *local_var_prefix ) } /* fall through */ case TGT_POINTER: - if (get_pointer_fc(type) == RPC_FC_FP) + if (get_pointer_fc(type, arg->attrs, TRUE) == RPC_FC_FP) { print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, "); fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); @@ -468,7 +466,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas, if (type_get_function_args(func->type)) { LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) - fprintf(proxy, ", %s__frame->%s", arg->type->declarray ? "*" : "", arg->name); + fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name); } fprintf(proxy, ");\n"); fprintf(proxy, "\n"); diff --git a/tools/widl/server.c b/tools/widl/server.c index 6f79cdb0b17..fd648993913 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -80,6 +80,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) indent++; write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE); + if (!is_void(type_function_get_rettype(func->type))) + write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE); + if (has_full_pointer) write_full_pointer_free(server, indent, func); @@ -185,7 +188,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) } else { - print_server("%s__frame->%s", var->type->declarray ? "*" : "", var->name); + print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name); } } fprintf(server, ");\n"); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index dead790a3e0..ce4d3d7da80 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -65,7 +65,7 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty const char *name, int write_ptr, unsigned int *tfsoff); static const var_t *find_array_or_string_in_struct(const type_t *type); static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, - type_t *type, + type_t *type, int toplevel_param, const char *name, unsigned int *typestring_offset); const char *string_of_type(unsigned char type) @@ -120,13 +120,52 @@ const char *string_of_type(unsigned char type) } } -unsigned char get_pointer_fc(const type_t *type) +unsigned char get_basic_fc(const type_t *type) { - assert(is_ptr(type)); - /* FIXME: see corresponding hack in set_type - we shouldn't be getting - * the pointer type from an alias, rather determining it from the - * position */ - return type->type; + int sign = type_basic_get_sign(type); + switch (type_basic_get_type(type)) + { + case TYPE_BASIC_INT8: return (sign <= 0 ? RPC_FC_SMALL : RPC_FC_USMALL); + case TYPE_BASIC_INT16: return (sign <= 0 ? RPC_FC_SHORT : RPC_FC_USHORT); + case TYPE_BASIC_INT32: return (sign <= 0 ? RPC_FC_LONG : RPC_FC_ULONG); + case TYPE_BASIC_INT64: return RPC_FC_HYPER; + case TYPE_BASIC_INT: return (sign <= 0 ? RPC_FC_LONG : RPC_FC_ULONG); + case TYPE_BASIC_BYTE: return RPC_FC_BYTE; + case TYPE_BASIC_CHAR: return RPC_FC_CHAR; + case TYPE_BASIC_WCHAR: return RPC_FC_WCHAR; + case TYPE_BASIC_HYPER: return RPC_FC_HYPER; + case TYPE_BASIC_FLOAT: return RPC_FC_FLOAT; + case TYPE_BASIC_DOUBLE: return RPC_FC_DOUBLE; + case TYPE_BASIC_ERROR_STATUS_T: return RPC_FC_ERROR_STATUS_T; + case TYPE_BASIC_HANDLE: return RPC_FC_BIND_PRIMITIVE; + default: return 0; + } +} + +unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param) +{ + const type_t *t; + int pointer_type; + + assert(is_ptr(type) || is_array(type)); + + pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); + if (pointer_type) + return pointer_type; + + for (t = type; type_is_alias(t); t = type_alias_get_aliasee(t)) + { + pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE); + if (pointer_type) + return pointer_type; + } + + if (toplevel_param) + return RPC_FC_RP; + else if (is_ptr(type)) + return type_pointer_get_default_fc(type); + else + return type_array_get_ptr_default_fc(type); } static unsigned char get_enum_fc(const type_t *type) @@ -201,7 +240,7 @@ unsigned char get_struct_fc(const type_t *type) typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS); - if (typegen_type == TGT_ARRAY && t->declarray) + if (typegen_type == TGT_ARRAY && !type_array_is_decl_as_ptr(t)) { if (is_string_type(field->attrs, field->type)) { @@ -240,20 +279,11 @@ unsigned char get_struct_fc(const type_t *type) return RPC_FC_BOGUS_STRUCT; break; case TGT_POINTER: - if (get_pointer_fc(t) == RPC_FC_RP || pointer_size != 4) - return RPC_FC_BOGUS_STRUCT; - has_pointer = 1; - break; case TGT_ARRAY: - { - unsigned int ptr_type = get_attrv(field->attrs, ATTR_POINTERTYPE); - if (!ptr_type || ptr_type == RPC_FC_RP) - return RPC_FC_BOGUS_STRUCT; - else if (pointer_size != 4) + if (get_pointer_fc(t, field->attrs, FALSE) == RPC_FC_RP || pointer_size != 4) return RPC_FC_BOGUS_STRUCT; has_pointer = 1; break; - } case TGT_UNION: return RPC_FC_BOGUS_STRUCT; case TGT_STRUCT: @@ -383,7 +413,7 @@ unsigned char get_array_fc(const type_t *type) /* ref pointers cannot just be block copied. unique pointers to * interfaces need special treatment. either case means the array is * complex */ - if (get_pointer_fc(elem_type) == RPC_FC_RP) + if (get_pointer_fc(elem_type, NULL, FALSE) == RPC_FC_RP) fc = RPC_FC_BOGUS_ARRAY; break; case TGT_BASIC: @@ -468,27 +498,30 @@ static int type_has_pointers(const type_t *type) return FALSE; } -static int type_has_full_pointer(const type_t *type) +static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs, + int toplevel_param) { switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS)) { case TGT_USER_TYPE: return FALSE; case TGT_POINTER: - if (get_pointer_fc(type) == RPC_FC_FP) + if (get_pointer_fc(type, attrs, toplevel_param) == RPC_FC_FP) return TRUE; else return FALSE; case TGT_ARRAY: - /* FIXME: array can be full pointer */ - return type_has_full_pointer(type_array_get_element(type)); + if (get_pointer_fc(type, attrs, toplevel_param) == RPC_FC_FP) + return TRUE; + else + return type_has_full_pointer(type_array_get_element(type), NULL, FALSE); case TGT_STRUCT: { var_list_t *fields = type_struct_get_fields(type); const var_t *field; if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) { - if (type_has_full_pointer(field->type)) + if (type_has_full_pointer(field->type, field->attrs, FALSE)) return TRUE; } break; @@ -500,7 +533,7 @@ static int type_has_full_pointer(const type_t *type) fields = type_union_get_cases(type); if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) { - if (field->type && type_has_full_pointer(field->type)) + if (field->type && type_has_full_pointer(field->type, field->attrs, FALSE)) return TRUE; } break; @@ -725,7 +758,7 @@ static unsigned int write_procformatstring_type(FILE *file, int indent, } else { - fc = type_basic_get_fc(type); + fc = get_basic_fc(type); if (fc == RPC_FC_BIND_PRIMITIVE) fc = RPC_FC_IGNORE; @@ -816,7 +849,7 @@ static int write_base_type(FILE *file, const type_t *type, int convert_to_signed unsigned char fc; if (type_get_type(type) == TYPE_BASIC) - fc = type_basic_get_fc(type); + fc = get_basic_fc(type); else if (type_get_type(type) == TYPE_ENUM) fc = get_enum_fc(type); else @@ -885,7 +918,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure, return 4; } - if (is_ptr(type) || (is_array(type) && !type->declarray)) + if (is_ptr(type) || (is_array(type) && type_array_is_decl_as_ptr(type))) { conftype = RPC_FC_POINTER_CONFORMANCE; conftype_string = "field pointer, "; @@ -964,7 +997,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure, if (type_get_type(correlation_variable) == TYPE_BASIC) { - switch (type_basic_get_fc(correlation_variable)) + switch (get_basic_fc(correlation_variable)) { case RPC_FC_CHAR: case RPC_FC_SMALL: @@ -989,7 +1022,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure, break; default: error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n", - type_basic_get_fc(correlation_variable)); + get_basic_fc(correlation_variable)); } } else if (type_get_type(correlation_variable) == TYPE_ENUM) @@ -1122,7 +1155,7 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) switch (type_get_type(t)) { case TYPE_BASIC: - switch (type_basic_get_fc(t)) + switch (get_basic_fc(t)) { case RPC_FC_BYTE: case RPC_FC_CHAR: @@ -1150,7 +1183,7 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) if (size > *align) *align = size; break; default: - error("type_memsize: Unknown type 0x%x\n", type_basic_get_fc(t)); + error("type_memsize: Unknown type 0x%x\n", get_basic_fc(t)); size = 0; } break; @@ -1185,7 +1218,7 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) if (size > *align) *align = size; break; case TYPE_ARRAY: - if (t->declarray) + if (!type_array_is_decl_as_ptr(t)) { if (is_conformant_array(t)) { @@ -1222,12 +1255,12 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) int is_full_pointer_function(const var_t *func) { const var_t *var; - if (type_has_full_pointer(type_function_get_rettype(func->type))) + if (type_has_full_pointer(type_function_get_rettype(func->type), func->attrs, TRUE)) return TRUE; if (!type_get_function_args(func->type)) return FALSE; LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - if (type_has_full_pointer( var->type )) + if (type_has_full_pointer( var->type, var->attrs, TRUE )) return TRUE; return FALSE; } @@ -1245,21 +1278,50 @@ void write_full_pointer_free(FILE *file, int indent, const var_t *func) fprintf(file, "\n"); } -static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, unsigned int offset) +static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs, + const type_t *type, + int toplevel_param, + unsigned int offset, + unsigned int *typeformat_offset) { - short absoff = type_pointer_get_ref(type)->typestring_offset; - short reloff = absoff - (offset + 2); - int ptr_attr = is_ptr(type_pointer_get_ref(type)) ? 0x10 : 0x0; - unsigned char pointer_fc = get_pointer_fc(type); + unsigned int start_offset = *typeformat_offset; + short reloff = offset - (*typeformat_offset + 2); + int in_attr, out_attr; + int pointer_type; + unsigned char flags = 0; - print_file(file, 2, "0x%02x, 0x%x,\t/* %s */\n", - pointer_fc, ptr_attr, string_of_type(pointer_fc)); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%hd) */\n", - reloff, reloff, absoff); - return 4; + pointer_type = get_pointer_fc(type, attrs, toplevel_param); + + in_attr = is_attr(attrs, ATTR_IN); + out_attr = is_attr(attrs, ATTR_OUT); + if (!in_attr && !out_attr) in_attr = 1; + + if (out_attr && !in_attr && pointer_type == RPC_FC_RP) + flags |= RPC_FC_P_ONSTACK; + + if (is_ptr(type) && !last_ptr(type)) + flags |= RPC_FC_P_DEREF; + + print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", + pointer_type, + flags, + string_of_type(pointer_type)); + if (file) + { + if (flags & RPC_FC_P_ONSTACK) + fprintf(file, " [allocated_on_stack]"); + if (flags & RPC_FC_P_DEREF) + fprintf(file, " [pointer_deref]"); + fprintf(file, " */\n"); + } + + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", reloff, reloff, offset); + *typeformat_offset += 4; + + return start_offset; } -static unsigned int write_simple_pointer(FILE *file, const type_t *type) +static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs, const type_t *type, int toplevel_param) { unsigned char fc; unsigned char pointer_fc; @@ -1267,19 +1329,19 @@ static unsigned int write_simple_pointer(FILE *file, const type_t *type) /* for historical reasons, write_simple_pointer also handled string types, * but no longer does. catch bad uses of the function with this check */ - if (is_string_type(type->attrs, type)) + if (is_string_type(attrs, type)) error("write_simple_pointer: can't handle type %s which is a string type\n", type->name); - pointer_fc = get_pointer_fc(type); + pointer_fc = get_pointer_fc(type, attrs, toplevel_param); ref = type_pointer_get_ref(type); if (type_get_type(ref) == TYPE_ENUM) fc = get_enum_fc(ref); else - fc = type_basic_get_fc(ref); + fc = get_basic_fc(ref); - print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n", - pointer_fc, string_of_type(pointer_fc)); + print_file(file, 2, "0x%02x, 0x%x,\t/* %s [simple_pointer] */\n", + pointer_fc, RPC_FC_P_SIMPLEPOINTER, string_of_type(pointer_fc)); print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc)); print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); return 4; @@ -1292,7 +1354,9 @@ static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff) print_file(file, 0, ") */\n"); } -static unsigned int write_pointer_tfs(FILE *file, type_t *type, unsigned int *typestring_offset) +static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs, + type_t *type, int toplevel_param, + unsigned int *typestring_offset) { unsigned int offset = *typestring_offset; type_t *ref = type_pointer_get_ref(type); @@ -1301,10 +1365,14 @@ static unsigned int write_pointer_tfs(FILE *file, type_t *type, unsigned int *ty update_tfsoff(type, offset, file); if (ref->typestring_offset) - *typestring_offset += write_nonsimple_pointer(file, type, offset); + write_nonsimple_pointer(file, attrs, type, + toplevel_param, + type_pointer_get_ref(type)->typestring_offset, + typestring_offset); else if (type_get_type(ref) == TYPE_BASIC || type_get_type(ref) == TYPE_ENUM) - *typestring_offset += write_simple_pointer(file, type); + *typestring_offset += write_simple_pointer(file, attrs, type, + toplevel_param); return offset; } @@ -1355,7 +1423,7 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) if (type_get_type(utype) == TYPE_ENUM) fc = get_enum_fc(utype); else - fc = type_basic_get_fc(utype); + fc = get_basic_fc(utype); absoff = *tfsoff; print_start_tfs_comment(file, utype, absoff); @@ -1370,9 +1438,9 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) absoff = utype->typestring_offset; } - if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype) == RPC_FC_RP) + if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype, NULL, FALSE) == RPC_FC_RP) flags = 0x40; - else if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype) == RPC_FC_UP) + else if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype, NULL, FALSE) == RPC_FC_UP) flags = 0x80; else flags = 0; @@ -1471,14 +1539,15 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) } static int write_no_repeat_pointer_descriptions( - FILE *file, type_t *type, + FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset) { int written = 0; unsigned int align; - if (is_ptr(type) || (!type->declarray && is_conformant_array(type))) + if (is_ptr(type) || + (is_conformant_array(type) && type_array_is_decl_as_ptr(type))) { unsigned int memsize; @@ -1492,20 +1561,19 @@ static int write_no_repeat_pointer_descriptions( if (is_ptr(type)) { - if (is_string_type(type->attrs, type)) - write_string_tfs(file, NULL, type, NULL, typestring_offset); + if (is_string_type(attrs, type)) + write_string_tfs(file, attrs, type, FALSE, NULL, typestring_offset); else - write_pointer_tfs(file, type, typestring_offset); + write_pointer_tfs(file, attrs, type, FALSE, typestring_offset); } else { - unsigned absoff = type->typestring_offset; - short reloff = absoff - (*typestring_offset + 2); - /* FIXME: get pointer attributes from field */ - print_file(file, 2, "0x%02x, 0x0,\t/* %s */\n", RPC_FC_UP, "FC_UP"); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *typestring_offset += 4; + unsigned int offset = type->typestring_offset; + /* skip over the pointer that is written for strings, since a + * pointer has to be written in-place here */ + if (is_string_type(attrs, type)) + offset += 4; + write_nonsimple_pointer(file, attrs, type, FALSE, offset, typestring_offset); } align = 0; @@ -1533,7 +1601,7 @@ static int write_no_repeat_pointer_descriptions( *offset_in_buffer += padding; } written += write_no_repeat_pointer_descriptions( - file, v->type, + file, v->attrs, v->type, offset_in_memory, offset_in_buffer, typestring_offset); } } @@ -1582,9 +1650,9 @@ static int write_pointer_description_offsets( *typestring_offset += 4; if (is_string_type(attrs, type)) - write_string_tfs(file, NULL, type, NULL, typestring_offset); + write_string_tfs(file, attrs, type, FALSE, NULL, typestring_offset); else if (processed(ref) || type_get_type(ref) == TYPE_BASIC || type_get_type(ref) == TYPE_ENUM) - write_pointer_tfs(file, type, typestring_offset); + write_pointer_tfs(file, attrs, type, FALSE, typestring_offset); else error("write_pointer_description_offsets: type format string unknown\n"); @@ -1851,7 +1919,7 @@ static void write_pointer_description(FILE *file, type_t *type, offset_in_memory = 0; offset_in_buffer = 0; write_no_repeat_pointer_descriptions( - file, type, + file, NULL, type, &offset_in_memory, &offset_in_buffer, typestring_offset); } @@ -1864,7 +1932,8 @@ static void write_pointer_description(FILE *file, type_t *type, /* pass 3: search for pointers in conformant only arrays (but don't descend * into conformant varying or varying arrays) */ - if ((!type->declarray || !current_structure) && is_conformant_array(type)) + if (is_conformant_array(type) && + (type_array_is_decl_as_ptr(type) || !current_structure)) write_conformant_array_pointer_descriptions( file, NULL, type, 0, typestring_offset); else if (type_get_type(type) == TYPE_STRUCT && @@ -1888,21 +1957,24 @@ static void write_pointer_description(FILE *file, type_t *type, int is_declptr(const type_t *t) { - return is_ptr(t) || (is_conformant_array(t) && !t->declarray); + return is_ptr(t) || (type_get_type(t) == TYPE_ARRAY && type_array_is_decl_as_ptr(t)); } static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, - type_t *type, + type_t *type, int toplevel_param, const char *name, unsigned int *typestring_offset) { unsigned int start_offset; unsigned char rtype; type_t *elem_type; + start_offset = *typestring_offset; + update_tfsoff(type, start_offset, file); + if (is_declptr(type)) { unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER; - int pointer_type = is_ptr(type) ? get_pointer_fc(type) : get_attrv(attrs, ATTR_POINTERTYPE); + int pointer_type = get_pointer_fc(type, attrs, toplevel_param); if (!pointer_type) pointer_type = RPC_FC_RP; print_start_tfs_comment(file, type, *typestring_offset); @@ -1917,9 +1989,6 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, } } - start_offset = *typestring_offset; - update_tfsoff(type, start_offset, file); - if (is_array(type)) elem_type = type_array_get_element(type); else @@ -1931,14 +2000,14 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, return start_offset; } - rtype = type_basic_get_fc(elem_type); + rtype = get_basic_fc(elem_type); if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR)) { error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", rtype, name); return start_offset; } - if (type->declarray && !is_conformant_array(type)) + if (type_get_type(type) == TYPE_ARRAY && !type_array_has_conformance(type)) { unsigned int dim = type_array_get_dim(type); @@ -1972,7 +2041,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, *typestring_offset += write_conf_or_var_desc( file, current_structure, - (type->declarray && current_structure + (!type_array_is_decl_as_ptr(type) && current_structure ? type_memsize(current_structure, &align) : 0), type, type_array_get_conformance(type)); @@ -2004,7 +2073,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t int has_pointer; int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); unsigned int baseoff - = type->declarray && current_structure + = !type_array_is_decl_as_ptr(type) && current_structure ? type_memsize(current_structure, &align) : 0; @@ -2072,7 +2141,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t += write_conf_or_var_desc(file, current_structure, baseoff, type, length_is); - if (has_pointer && (!type->declarray || !current_structure)) + if (has_pointer && (type_array_is_decl_as_ptr(type) || !current_structure)) { print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); @@ -2115,7 +2184,7 @@ static const var_t *find_array_or_string_in_struct(const type_t *type) last_field = LIST_ENTRY( list_tail(fields), const var_t, entry ); ft = last_field->type; - if (ft->declarray && is_conformant_array(ft)) + if (is_conformant_array(ft) && !type_array_is_decl_as_ptr(ft)) return last_field; if (type_get_type(ft) == TYPE_STRUCT) @@ -2137,7 +2206,7 @@ static void write_struct_members(FILE *file, const type_t *type, if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) { type_t *ft = field->type; - if (!ft->declarray || !is_conformant_array(ft)) + if (!is_conformant_array(ft) || type_array_is_decl_as_ptr(ft)) { unsigned int align = 0; unsigned int size = type_memsize(ft, &align); @@ -2211,7 +2280,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type, if (array && !processed(array->type)) array_offset = is_string_type(array->attrs, array->type) - ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff) + ? write_string_tfs(file, array->attrs, array->type, FALSE, array->name, tfsoff) : write_array_tfs(file, array->attrs, array->type, array->name, tfsoff); corroff = *tfsoff; @@ -2278,25 +2347,22 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type, if (is_ptr(ft)) { if (is_string_type(f->attrs, ft)) - write_string_tfs(file, f->attrs, ft, f->name, tfsoff); + write_string_tfs(file, f->attrs, ft, FALSE, f->name, tfsoff); else - write_pointer_tfs(file, ft, tfsoff); + write_pointer_tfs(file, f->attrs, ft, FALSE, tfsoff); } - else if (!ft->declarray && is_conformant_array(ft)) + else if (type_get_type(ft) == TYPE_ARRAY && type_array_is_decl_as_ptr(ft)) { - unsigned int absoff = ft->typestring_offset; - short reloff = absoff - (*tfsoff + 2); - int ptr_type = get_attrv(f->attrs, ATTR_POINTERTYPE); - /* FIXME: We need to store pointer attributes for arrays - so we don't lose pointer_default info. */ - if (ptr_type == 0) - ptr_type = RPC_FC_UP; + unsigned int offset; + print_file(file, 0, "/* %d */\n", *tfsoff); - print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, - string_of_type(ptr_type)); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *tfsoff += 4; + + offset = ft->typestring_offset; + /* skip over the pointer that is written for strings, since a + * pointer has to be written in-place here */ + if (is_string_type(f->attrs, ft)) + offset += 4; + write_nonsimple_pointer(file, f->attrs, ft, FALSE, offset, tfsoff); } } if (type_get_real_type(type)->ptrdesc == *tfsoff) @@ -2307,39 +2373,6 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type, return start_offset; } -static unsigned int write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int pointer_type, - unsigned char flags, unsigned int offset, - unsigned int *typeformat_offset) -{ - unsigned int start_offset = *typeformat_offset; - short reloff = offset - (*typeformat_offset + 2); - int in_attr, out_attr; - in_attr = is_attr(attrs, ATTR_IN); - out_attr = is_attr(attrs, ATTR_OUT); - if (!in_attr && !out_attr) in_attr = 1; - - if (out_attr && !in_attr && pointer_type == RPC_FC_RP) - flags |= 0x04; - - print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", - pointer_type, - flags, - string_of_type(pointer_type)); - if (file) - { - if (flags & 0x04) - fprintf(file, " [allocated_on_stack]"); - if (flags & 0x10) - fprintf(file, " [pointer_deref]"); - fprintf(file, " */\n"); - } - - print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", reloff, offset); - *typeformat_offset += 4; - - return start_offset; -} - static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) { if (t == NULL) @@ -2352,7 +2385,7 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) { unsigned char fc; if (type_get_type(t) == TYPE_BASIC) - fc = type_basic_get_fc(t); + fc = get_basic_fc(t); else fc = get_enum_fc(t); print_file(file, 2, "NdrFcShort(0x80%02x),\t/* Simple arm type: %s */\n", @@ -2409,7 +2442,7 @@ static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfso if (type_get_type(st) == TYPE_BASIC) { - switch (type_basic_get_fc(st)) + switch (get_basic_fc(st)) { case RPC_FC_CHAR: case RPC_FC_SMALL: @@ -2420,7 +2453,7 @@ static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfso case RPC_FC_USHORT: case RPC_FC_LONG: case RPC_FC_ULONG: - fc = type_basic_get_fc(st); + fc = get_basic_fc(st); break; default: fc = 0; @@ -2445,7 +2478,7 @@ static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfso if (type_get_type(st) == TYPE_BASIC) { - switch (type_basic_get_fc(st)) + switch (get_basic_fc(st)) { case RPC_FC_CHAR: case RPC_FC_SMALL: @@ -2456,7 +2489,7 @@ static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfso case RPC_FC_ULONG: case RPC_FC_ENUM16: case RPC_FC_ENUM32: - fc = type_basic_get_fc(st); + fc = get_basic_fc(st); break; default: fc = 0; @@ -2615,6 +2648,7 @@ static unsigned int write_contexthandle_tfs(FILE *file, const type_t *type, static unsigned int write_typeformatstring_var(FILE *file, int indent, const var_t *func, type_t *type, const var_t *var, + int toplevel_param, unsigned int *typeformat_offset) { unsigned int offset; @@ -2628,22 +2662,14 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var write_user_tfs(file, type, typeformat_offset); return type->typestring_offset; case TGT_STRING: - return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset); + return write_string_tfs(file, var->attrs, type, toplevel_param, var->name, typeformat_offset); case TGT_ARRAY: { int ptr_type; unsigned int off; off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset); - ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - /* Top level pointers to conformant arrays may be handled specially - since we can bypass the pointer, but if the array is buried - beneath another pointer (e.g., "[size_is(,n)] int **p" then we - always need to write the pointer. */ - if (!ptr_type && var->type != type) - /* FIXME: This should use pointer_default, but the information - isn't kept around for arrays. */ - ptr_type = RPC_FC_UP; - if (ptr_type && ptr_type != RPC_FC_RP) + ptr_type = get_pointer_fc(type, var->attrs, toplevel_param); + if (ptr_type != RPC_FC_RP) { unsigned int absoff = type->typestring_offset; short reloff = absoff - (*typeformat_offset + 2); @@ -2688,12 +2714,12 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var if (type_get_type(ref) == TYPE_ENUM) fc = get_enum_fc(ref); else - fc = type_basic_get_fc(ref); + fc = get_basic_fc(ref); print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", - get_pointer_fc(type), + get_pointer_fc(type, var->attrs, toplevel_param), (!in_attr && out_attr) ? 0x0C : 0x08, - string_of_type(get_pointer_fc(type)), + string_of_type(get_pointer_fc(type, var->attrs, toplevel_param)), (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); print_file(file, indent, "0x%02x, /* %s */\n", fc, string_of_type(fc)); @@ -2708,12 +2734,12 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var offset = write_typeformatstring_var(file, indent, func, type_pointer_get_ref(type), var, - typeformat_offset); + FALSE, typeformat_offset); if (file) fprintf(file, "/* %2u */\n", *typeformat_offset); - return write_pointer_only_tfs(file, var->attrs, get_pointer_fc(type), - !last_ptr(type) ? 0x10 : 0, - offset, typeformat_offset); + return write_nonsimple_pointer(file, var->attrs, type, + toplevel_param, + offset, typeformat_offset); case TGT_INVALID: break; } @@ -2732,7 +2758,7 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty write_user_tfs(file, type, tfsoff); break; case TGT_STRING: - write_string_tfs(file, attrs, type, name, tfsoff); + write_string_tfs(file, attrs, type, FALSE, name, tfsoff); break; case TGT_IFACE_POINTER: write_ip_tfs(file, attrs, type, tfsoff); @@ -2745,14 +2771,14 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff); if (write_ptr) - write_pointer_tfs(file, type, tfsoff); + write_pointer_tfs(file, attrs, type, FALSE, tfsoff); retmask |= 1; break; } case TGT_ARRAY: /* conformant arrays and strings are handled specially */ - if (!type->declarray || !is_conformant_array(type)) + if (!is_conformant_array(type) || type_array_is_decl_as_ptr(type) ) { write_array_tfs(file, attrs, type, name, tfsoff); if (is_conformant_array(type)) @@ -2818,7 +2844,7 @@ static unsigned int process_tfs_stmts(FILE *file, const statement_list_t *stmts, write_typeformatstring_var( file, 2, NULL, type_function_get_rettype(func->type), - &v, typeformat_offset), + &v, TRUE, typeformat_offset), file); } @@ -2829,7 +2855,7 @@ static unsigned int process_tfs_stmts(FILE *file, const statement_list_t *stmts, var->type, write_typeformatstring_var( file, 2, func, var->type, var, - typeformat_offset), + TRUE, typeformat_offset), file); } } @@ -2869,7 +2895,7 @@ void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred } static unsigned int get_required_buffer_size_type( - const type_t *type, const char *name, unsigned int *alignment) + const type_t *type, const char *name, const attr_list_t *attrs, int toplevel_param, unsigned int *alignment) { *alignment = 0; switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS)) @@ -2878,10 +2904,10 @@ static unsigned int get_required_buffer_size_type( { const char *uname; const type_t *utype = get_user_type(type, &uname); - return get_required_buffer_size_type(utype, uname, alignment); + return get_required_buffer_size_type(utype, uname, NULL, FALSE, alignment); } case TGT_BASIC: - switch (type_basic_get_fc(type)) + switch (get_basic_fc(type)) { case RPC_FC_BYTE: case RPC_FC_CHAR: @@ -2914,7 +2940,7 @@ static unsigned int get_required_buffer_size_type( default: error("get_required_buffer_size: unknown basic type 0x%02x\n", - type_basic_get_fc(type)); + get_basic_fc(type)); return 0; } break; @@ -2940,17 +2966,17 @@ static unsigned int get_required_buffer_size_type( break; case TGT_POINTER: - if (get_pointer_fc(type) == RPC_FC_RP) + if (get_pointer_fc(type, attrs, toplevel_param) == RPC_FC_RP) { const type_t *ref = type_pointer_get_ref(type); switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES)) { case TGT_BASIC: case TGT_ENUM: - return get_required_buffer_size_type( ref, name, alignment ); + return get_required_buffer_size_type( ref, name, NULL, FALSE, alignment ); case TGT_STRUCT: if (get_struct_fc(ref) == RPC_FC_STRUCT) - return get_required_buffer_size_type( ref, name, alignment ); + return get_required_buffer_size_type( ref, name, NULL, FALSE, alignment ); break; case TGT_USER_TYPE: case TGT_CTXT_HANDLE: @@ -2969,7 +2995,7 @@ static unsigned int get_required_buffer_size_type( case TGT_ARRAY: /* FIXME: depends on pointer type */ return type_array_get_dim(type) * - get_required_buffer_size_type(type_array_get_element(type), name, alignment); + get_required_buffer_size_type(type_array_get_element(type), name, NULL, FALSE, alignment); default: break; @@ -2998,7 +3024,7 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali if (!is_string_type(var->attrs, var->type)) return get_required_buffer_size_type(var->type, var->name, - alignment); + var->attrs, TRUE, alignment); } return 0; } @@ -3096,7 +3122,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, } else { - switch (type_basic_get_fc(ref)) + switch (get_basic_fc(ref)) { case RPC_FC_BYTE: case RPC_FC_CHAR: @@ -3134,7 +3160,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, default: error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", - var->name, type_basic_get_fc(ref)); + var->name, get_basic_fc(ref)); size = 0; } } @@ -3273,9 +3299,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const const type_t *type = var->type; unsigned int start_offset = type->typestring_offset; - pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; + if (is_ptr(type) || is_array(type)) + pointer_type = get_pointer_fc(type, var->attrs, pass != PASS_RETURN); + else + pointer_type = 0; in_attr = is_attr(var->attrs, ATTR_IN); out_attr = is_attr(var->attrs, ATTR_OUT); @@ -3349,19 +3376,30 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const if (phase == PHASE_FREE || pass == PASS_RETURN || pointer_type != RPC_FC_RP) { - unsigned int ptr_start_offset = (start_offset - (is_conformant_array(type) ? 4 : 2)); - print_phase_function(file, indent, "Pointer", local_var_prefix, - phase, var, ptr_start_offset); + /* strings returned are assumed to be global and hence don't + * need freeing */ + if (phase != PHASE_FREE || pass != PASS_RETURN) + print_phase_function(file, indent, "Pointer", local_var_prefix, + phase, var, start_offset); } else { + unsigned int real_start_offset = start_offset; + /* skip over pointer description straight to string description */ + if (is_declptr(type)) + { + if (is_conformant_array(type)) + real_start_offset += 4; + else + real_start_offset += 2; + } if (is_array(type) && !is_conformant_array(type)) print_phase_function(file, indent, "NonConformantString", local_var_prefix, phase, var, - start_offset); + real_start_offset); else print_phase_function(file, indent, "ConformantString", local_var_prefix, - phase, var, start_offset); + phase, var, real_start_offset); } break; case TGT_ARRAY: @@ -3466,7 +3504,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const case TGT_POINTER: { const type_t *ref = type_pointer_get_ref(type); - if (get_pointer_fc(type) == RPC_FC_RP && !is_user_type(ref)) switch (type_get_type(ref)) + if (pointer_type == RPC_FC_RP && !is_user_type(ref)) switch (type_get_type(ref)) { case TYPE_BASIC: /* base types have known sizes, so don't need a sizing pass @@ -3493,6 +3531,13 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const * need a freeing pass */ if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) struct_type = "SimpleStruct"; + else if (phase == PHASE_FREE && pass == PASS_RETURN) + { + print_file(file, indent, "if (%s%s)\n", local_var_prefix, var->name); + indent++; + print_file(file, indent, "__frame->_StubMsg.pfnFree(%s%s);\n", local_var_prefix, var->name); + indent--; + } break; case RPC_FC_PSTRUCT: struct_type = "SimpleStruct"; @@ -3695,7 +3740,8 @@ void declare_stub_args( FILE *file, int indent, const var_t *func ) type_t *type_to_print; char name[16]; print_file(file, indent, "%s", ""); - if (var->type->declarray) + if (type_get_type(var->type) == TYPE_ARRAY && + !type_array_is_decl_as_ptr(var->type)) type_to_print = var->type; else type_to_print = type_pointer_get_ref(var->type); @@ -3707,7 +3753,8 @@ void declare_stub_args( FILE *file, int indent, const var_t *func ) print_file(file, indent, "%s", ""); write_type_decl_left(file, var->type); fprintf(file, " "); - if (var->type->declarray) { + if (type_get_type(var->type) == TYPE_ARRAY && + !type_array_is_decl_as_ptr(var->type)) { fprintf(file, "(*%s)", var->name); } else fprintf(file, "%s", var->name); diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h index c45c154ca39..8c8ba11da64 100644 --- a/tools/widl/typegen.h +++ b/tools/widl/typegen.h @@ -88,6 +88,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name); int is_full_pointer_function(const var_t *func); void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server); void write_full_pointer_free(FILE *file, int indent, const var_t *func); -unsigned char get_pointer_fc(const type_t *type); +unsigned char get_basic_fc(const type_t *type); +unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param); unsigned char get_struct_fc(const type_t *type); enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags); diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index d6a2e2eb4a1..d675ea951cf 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -116,10 +116,10 @@ static unsigned short builtin_vt(const type_t *t) elem_type = type_pointer_get_ref(t); if (type_get_type(elem_type) == TYPE_BASIC) { - switch (type_basic_get_fc(elem_type)) + switch (type_basic_get_type(elem_type)) { - case RPC_FC_CHAR: return VT_LPSTR; - case RPC_FC_WCHAR: return VT_LPWSTR; + case TYPE_BASIC_CHAR: return VT_LPSTR; + case TYPE_BASIC_WCHAR: return VT_LPWSTR; default: break; } } @@ -148,45 +148,58 @@ unsigned short get_type_vt(type_t *t) switch (type_get_type(t)) { case TYPE_BASIC: - switch (type_basic_get_fc(t)) { - case RPC_FC_BYTE: - case RPC_FC_USMALL: + switch (type_basic_get_type(t)) { + case TYPE_BASIC_BYTE: return VT_UI1; - case RPC_FC_CHAR: - case RPC_FC_SMALL: - return VT_I1; - case RPC_FC_WCHAR: + case TYPE_BASIC_CHAR: + case TYPE_BASIC_INT8: + if (type_basic_get_sign(t) > 0) + return VT_UI1; + else + return VT_I1; + case TYPE_BASIC_WCHAR: return VT_I2; /* mktyplib seems to parse wchar_t as short */ - case RPC_FC_SHORT: - return VT_I2; - case RPC_FC_USHORT: - return VT_UI2; - case RPC_FC_LONG: - if (match(t->name, "int")) return VT_INT; - return VT_I4; - case RPC_FC_ULONG: - if (match(t->name, "int")) return VT_UINT; - return VT_UI4; - case RPC_FC_HYPER: - if (t->sign < 0) return VT_UI8; - if (match(t->name, "MIDL_uhyper")) return VT_UI8; - return VT_I8; - case RPC_FC_FLOAT: + case TYPE_BASIC_INT16: + if (type_basic_get_sign(t) > 0) + return VT_UI2; + else + return VT_I2; + case TYPE_BASIC_INT: + if (type_basic_get_sign(t) > 0) + return VT_UINT; + else + return VT_INT; + case TYPE_BASIC_INT32: + case TYPE_BASIC_ERROR_STATUS_T: + if (type_basic_get_sign(t) > 0) + return VT_UI4; + else + return VT_I4; + case TYPE_BASIC_INT64: + case TYPE_BASIC_HYPER: + if (type_basic_get_sign(t) > 0) + return VT_UI8; + else + return VT_I8; + case TYPE_BASIC_FLOAT: return VT_R4; - case RPC_FC_DOUBLE: + case TYPE_BASIC_DOUBLE: return VT_R8; - default: - error("get_type_vt: unknown basic type: 0x%02x\n", type_basic_get_fc(t)); + case TYPE_BASIC_HANDLE: + error("handles can't be used in typelibs\n"); } break; case TYPE_POINTER: - if (match(type_pointer_get_ref(t)->name, "SAFEARRAY")) - return VT_SAFEARRAY; return VT_PTR; case TYPE_ARRAY: - if (t->declarray) + if (type_array_is_decl_as_ptr(t)) + { + if (match(type_array_get_element(t)->name, "SAFEARRAY")) + return VT_SAFEARRAY; + } + else error("get_type_vt: array types not supported\n"); return VT_PTR; diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 3a306847112..4359d924ba0 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -41,18 +41,42 @@ type_t *duptype(type_t *t, int dupname) return d; } +type_t *make_type(enum type_type type) +{ + type_t *t = alloc_type(); + t->name = NULL; + t->type_type = type; + t->attrs = NULL; + t->orig = NULL; + memset(&t->details, 0, sizeof(t->details)); + t->typestring_offset = 0; + t->ptrdesc = 0; + t->ignore = (parse_only != 0); + t->defined = FALSE; + t->written = FALSE; + t->user_types_registered = FALSE; + t->tfswrite = FALSE; + t->checked = FALSE; + t->is_alias = FALSE; + t->typelib_idx = -1; + init_loc_info(&t->loc_info); + return t; +} + type_t *type_new_function(var_list_t *args) { - type_t *t = make_type(RPC_FC_FUNCTION, NULL); + type_t *t = make_type(TYPE_FUNCTION); t->details.function = xmalloc(sizeof(*t->details.function)); t->details.function->args = args; t->details.function->idx = -1; return t; } -type_t *type_new_pointer(type_t *ref, attr_list_t *attrs) +type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs) { - type_t *t = make_type(pointer_default, ref); + type_t *t = make_type(TYPE_POINTER); + t->details.pointer.def_fc = pointer_default; + t->details.pointer.ref = ref; t->attrs = attrs; return t; } @@ -63,9 +87,10 @@ type_t *type_new_alias(type_t *t, const char *name) a->name = xstrdup(name); a->attrs = NULL; - a->declarray = FALSE; a->orig = t; a->is_alias = TRUE; + /* for pointer types */ + a->details = t->details; init_loc_info(&a->loc_info); return a; @@ -73,23 +98,153 @@ type_t *type_new_alias(type_t *t, const char *name) type_t *type_new_module(char *name) { - type_t *type = make_type(RPC_FC_MODULE, NULL); + type_t *type = get_type(TYPE_MODULE, name, 0); + if (type->type_type != TYPE_MODULE || type->defined) + error_loc("%s: redefinition error; original definition was at %s:%d\n", + type->name, type->loc_info.input_name, type->loc_info.line_number); + type->name = name; + return type; +} + +type_t *type_new_coclass(char *name) +{ + type_t *type = get_type(TYPE_COCLASS, name, 0); + if (type->type_type != TYPE_COCLASS || type->defined) + error_loc("%s: redefinition error; original definition was at %s:%d\n", + type->name, type->loc_info.input_name, type->loc_info.line_number); type->name = name; - /* FIXME: register type to detect multiple definitions */ return type; } -type_t *type_new_array(const char *name, type_t *element, int declarray, - unsigned int dim, expr_t *size_is, expr_t *length_is) + +type_t *type_new_array(const char *name, type_t *element, int declptr, + unsigned int dim, expr_t *size_is, expr_t *length_is, + unsigned char ptr_default_fc) { - type_t *t = make_type(RPC_FC_LGFARRAY, element); + type_t *t = make_type(TYPE_ARRAY); if (name) t->name = xstrdup(name); - t->declarray = declarray; + t->details.array.declptr = declptr; t->details.array.length_is = length_is; if (size_is) t->details.array.size_is = size_is; else t->details.array.dim = dim; + t->details.array.elem = element; + t->details.array.ptr_def_fc = ptr_default_fc; + return t; +} + +type_t *type_new_basic(enum type_basic_type basic_type) +{ + type_t *t = make_type(TYPE_BASIC); + t->details.basic.type = basic_type; + t->details.basic.sign = 0; + return t; +} + +type_t *type_new_int(enum type_basic_type basic_type, int sign) +{ + static type_t *int_types[TYPE_BASIC_INT_MAX+1][3]; + + assert(basic_type <= TYPE_BASIC_INT_MAX); + + /* map sign { -1, 0, 1 } -> { 0, 1, 2 } */ + if (!int_types[basic_type][sign + 1]) + { + int_types[basic_type][sign + 1] = type_new_basic(basic_type); + int_types[basic_type][sign + 1]->details.basic.sign = sign; + } + return int_types[basic_type][sign + 1]; +} + +type_t *type_new_void(void) +{ + static type_t *void_type = NULL; + if (!void_type) + void_type = make_type(TYPE_VOID); + return void_type; +} + +type_t *type_new_enum(const char *name, int defined, var_list_t *enums) +{ + type_t *tag_type = name ? find_type(name, tsENUM) : NULL; + type_t *t = make_type(TYPE_ENUM); + t->name = name; + + if (tag_type && tag_type->details.enumeration) + t->details.enumeration = tag_type->details.enumeration; + else if (defined) + { + t->details.enumeration = xmalloc(sizeof(*t->details.enumeration)); + t->details.enumeration->enums = enums; + t->defined = TRUE; + } + + if (name) + { + if (defined) + reg_type(t, name, tsENUM); + else + add_incomplete(t); + } + return t; +} + +type_t *type_new_struct(char *name, int defined, var_list_t *fields) +{ + type_t *tag_type = name ? find_type(name, tsSTRUCT) : NULL; + type_t *t = make_type(TYPE_STRUCT); + t->name = name; + if (tag_type && tag_type->details.structure) + t->details.structure = tag_type->details.structure; + else if (defined) + { + t->details.structure = xmalloc(sizeof(*t->details.structure)); + t->details.structure->fields = fields; + t->defined = TRUE; + } + if (name) + { + if (defined) + reg_type(t, name, tsSTRUCT); + else + add_incomplete(t); + } + return t; +} + +type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields) +{ + type_t *tag_type = name ? find_type(name, tsUNION) : NULL; + type_t *t = make_type(TYPE_UNION); + t->name = name; + if (tag_type && tag_type->details.structure) + t->details.structure = tag_type->details.structure; + else if (defined) + { + t->details.structure = xmalloc(sizeof(*t->details.structure)); + t->details.structure->fields = fields; + t->defined = TRUE; + } + if (name) + { + if (defined) + reg_type(t, name, tsUNION); + else + add_incomplete(t); + } + return t; +} + +type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases) +{ + type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, tsUNION); + if (!union_field) union_field = make_var( xstrdup("tagged_union") ); + union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases); + t->details.structure = xmalloc(sizeof(*t->details.structure)); + t->details.structure->fields = append_var( NULL, switch_field ); + t->details.structure->fields = append_var( t->details.structure->fields, union_field ); + t->defined = TRUE; return t; } @@ -118,23 +273,23 @@ static int compute_method_indexes(type_t *iface) void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts) { - iface->ref = inherit; iface->details.iface = xmalloc(sizeof(*iface->details.iface)); iface->details.iface->disp_props = NULL; iface->details.iface->disp_methods = NULL; iface->details.iface->stmts = stmts; + iface->details.iface->inherit = inherit; iface->defined = TRUE; compute_method_indexes(iface); } void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods) { - iface->ref = find_type("IDispatch", 0); - if (!iface->ref) error_loc("IDispatch is undefined\n"); iface->details.iface = xmalloc(sizeof(*iface->details.iface)); iface->details.iface->disp_props = props; iface->details.iface->disp_methods = methods; iface->details.iface->stmts = NULL; + iface->details.iface->inherit = find_type("IDispatch", 0); + if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n"); iface->defined = TRUE; compute_method_indexes(iface); } diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index a6bc982e288..fb0401b87a6 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -25,11 +25,20 @@ #define WIDL_TYPE_TREE_H type_t *type_new_function(var_list_t *args); -type_t *type_new_pointer(type_t *ref, attr_list_t *attrs); +type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs); type_t *type_new_alias(type_t *t, const char *name); type_t *type_new_module(char *name); -type_t *type_new_array(const char *name, type_t *element, int declarray, - unsigned int dim, expr_t *size_is, expr_t *length_is); +type_t *type_new_array(const char *name, type_t *element, int declptr, + unsigned int dim, expr_t *size_is, expr_t *length_is, + unsigned char ptr_default_fc); +type_t *type_new_basic(enum type_basic_type basic_type); +type_t *type_new_int(enum type_basic_type basic_type, int sign); +type_t *type_new_void(void); +type_t *type_new_coclass(char *name); +type_t *type_new_enum(const char *name, int defined, var_list_t *enums); +type_t *type_new_struct(char *name, int defined, var_list_t *fields); +type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields); +type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases); void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts); void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods); void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface); @@ -54,11 +63,18 @@ static inline enum type_type type_get_type(const type_t *type) return type_get_type_detect_alias(type_get_real_type(type)); } -static inline unsigned char type_basic_get_fc(const type_t *type) +static inline enum type_basic_type type_basic_get_type(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_BASIC); - return type->type; + return type->details.basic.type; +} + +static inline int type_basic_get_sign(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_BASIC); + return type->details.basic.sign; } static inline var_list_t *type_struct_get_fields(const type_t *type) @@ -79,7 +95,7 @@ static inline type_t *type_function_get_rettype(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_FUNCTION); - return type->ref; + return type->details.function->rettype; } static inline var_list_t *type_enum_get_values(const type_t *type) @@ -131,7 +147,7 @@ static inline type_t *type_iface_get_inherit(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_INTERFACE); - return type->ref; + return type->details.iface->inherit; } static inline var_list_t *type_dispiface_get_props(const type_t *type) @@ -218,7 +234,21 @@ static inline type_t *type_array_get_element(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_ARRAY); - return type->ref; + return type->details.array.elem; +} + +static inline int type_array_is_decl_as_ptr(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_ARRAY); + return type->details.array.declptr; +} + +static inline unsigned char type_array_get_ptr_default_fc(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_ARRAY); + return type->details.array.ptr_def_fc; } static inline int type_is_alias(const type_t *type) @@ -243,7 +273,14 @@ static inline type_t *type_pointer_get_ref(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_POINTER); - return type->ref; + return type->details.pointer.ref; +} + +static inline unsigned char type_pointer_get_default_fc(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_POINTER); + return type->details.pointer.def_fc; } #endif /* WIDL_TYPE_TREE_H */ diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 875be834926..7a194f46248 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -221,6 +221,27 @@ enum statement_type STMT_CPPQUOTE }; +enum type_basic_type +{ + TYPE_BASIC_INT8 = 1, + TYPE_BASIC_INT16, + TYPE_BASIC_INT32, + TYPE_BASIC_INT64, + TYPE_BASIC_INT, + TYPE_BASIC_CHAR, + TYPE_BASIC_HYPER, + TYPE_BASIC_BYTE, + TYPE_BASIC_WCHAR, + TYPE_BASIC_FLOAT, + TYPE_BASIC_DOUBLE, + TYPE_BASIC_ERROR_STATUS_T, + TYPE_BASIC_HANDLE, +}; + +#define TYPE_BASIC_MAX TYPE_BASIC_HANDLE +#define TYPE_BASIC_INT_MIN TYPE_BASIC_INT8 +#define TYPE_BASIC_INT_MAX TYPE_BASIC_HYPER + struct _loc_info_t { const char *input_name; @@ -274,6 +295,7 @@ struct enumeration_details struct func_details { var_list_t *args; + struct _type_t *rettype; int idx; }; @@ -282,6 +304,7 @@ struct iface_details statement_list_t *stmts; func_list_t *disp_methods; var_list_t *disp_props; + struct _type_t *inherit; }; struct module_details @@ -292,8 +315,12 @@ struct module_details struct array_details { + expr_t *size_is; + expr_t *length_is; + struct _type_t *elem; unsigned int dim; - expr_t *size_is, *length_is; + unsigned char ptr_def_fc; + unsigned char declptr; /* if declared as a pointer */ }; struct coclass_details @@ -301,6 +328,18 @@ struct coclass_details ifref_list_t *ifaces; }; +struct basic_details +{ + enum type_basic_type type; + int sign; +}; + +struct pointer_details +{ + struct _type_t *ref; + unsigned char def_fc; +}; + enum type_type { TYPE_VOID, @@ -320,8 +359,7 @@ enum type_type struct _type_t { const char *name; - unsigned char type; - struct _type_t *ref; + enum type_type type_type; attr_list_t *attrs; union { @@ -332,13 +370,14 @@ struct _type_t { struct module_details *module; struct array_details array; struct coclass_details coclass; + struct basic_details basic; + struct pointer_details pointer; } details; type_t *orig; /* dup'd types */ unsigned int typestring_offset; unsigned int ptrdesc; /* used for complex structs */ int typelib_idx; loc_info_t loc_info; - unsigned int declarray : 1; /* if declared as an array */ unsigned int ignore : 1; unsigned int defined : 1; unsigned int written : 1; @@ -346,7 +385,6 @@ struct _type_t { unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */ unsigned int checked : 1; unsigned int is_alias : 1; /* is the type an alias? */ - int sign : 2; }; struct _var_t { @@ -449,8 +487,6 @@ struct _statement_t { } u; }; -extern unsigned char pointer_default; - extern user_type_list_t user_type_list; void check_for_additional_prototype_types(const var_list_t *list); @@ -466,9 +502,19 @@ int cant_be_null(const var_t *v); int is_struct(unsigned char tc); int is_union(unsigned char tc); +#define tsENUM 1 +#define tsSTRUCT 2 +#define tsUNION 3 + var_t *find_const(const char *name, int f); type_t *find_type(const char *name, int t); -type_t *make_type(unsigned char type, type_t *ref); +type_t *make_type(enum type_type type); +type_t *get_type(enum type_type type, char *name, int t); +type_t *reg_type(type_t *type, const char *name, int t); +void add_incomplete(type_t *t); + +var_t *make_var(char *name); +var_list_t *append_var(var_list_t *list, var_t *var); void init_loc_info(loc_info_t *); @@ -481,65 +527,7 @@ static inline enum type_type type_get_type_detect_alias(const type_t *type) { if (type->is_alias) return TYPE_ALIAS; - switch (type->type) - { - case 0: - return TYPE_VOID; - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_HYPER: - case RPC_FC_IGNORE: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_BIND_PRIMITIVE: - return TYPE_BASIC; - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - return TYPE_ENUM; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - return TYPE_POINTER; - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return TYPE_STRUCT; - case RPC_FC_ENCAPSULATED_UNION: - return TYPE_ENCAPSULATED_UNION; - case RPC_FC_NON_ENCAPSULATED_UNION: - return TYPE_UNION; - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - case RPC_FC_SMVARRAY: - case RPC_FC_LGVARRAY: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - case RPC_FC_BOGUS_ARRAY: - return TYPE_ARRAY; - case RPC_FC_FUNCTION: - return TYPE_FUNCTION; - case RPC_FC_COCLASS: - return TYPE_COCLASS; - case RPC_FC_IP: - return TYPE_INTERFACE; - case RPC_FC_MODULE: - return TYPE_MODULE; - default: - assert(0); - return 0; - } + return type->type_type; } #define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \ diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index a92325a6bda..3506efeafd2 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -931,18 +931,10 @@ static int encode_type( case VT_SAFEARRAY: { - int next_vt; + type_t *element_type = type_alias_get_aliasee(type_array_get_element(type)); + int next_vt = get_type_vt(element_type); - /* skip over SAFEARRAY type straight to element type */ - type = type->ref; - - for(next_vt = 0; type->ref; type = type->ref) { - next_vt = get_type_vt(type->ref); - if (next_vt != 0) - break; - } - - encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); + encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)), &target_type, NULL, NULL, &child_size); for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; @@ -1040,8 +1032,7 @@ static int encode_type( static void dump_type(type_t *t) { - chat("dump_type: %p name %s type %d ref %p attrs %p\n", t, t->name, type_get_type(t), t->ref, t->attrs); - if(t->ref) dump_type(t->ref); + chat("dump_type: %p name %s type %d attrs %p\n", t, t->name, type_get_type(t), t->attrs); } static int encode_var( @@ -1065,16 +1056,18 @@ static int encode_var( if (!decoded_size) decoded_size = &scratch; *decoded_size = 0; - chat("encode_var: var %p type %p type->name %s type->ref %p\n", - var, type, type->name ? type->name : "NULL", type->ref); + chat("encode_var: var %p type %p type->name %s\n", + var, type, type->name ? type->name : "NULL"); - if (type->declarray) { + if (is_array(type) && !type_array_is_decl_as_ptr(type)) { int num_dims, elements = 1, arrayoffset; type_t *atype; int *arraydata; num_dims = 0; - for (atype = type; atype->declarray; atype = type_array_get_element(atype)) + for (atype = type; + is_array(atype) && !type_array_is_decl_as_ptr(atype); + atype = type_array_get_element(atype)) ++num_dims; chat("array with %d dimensions\n", num_dims); @@ -1087,7 +1080,9 @@ static int encode_var( arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16); arraydata += 2; - for (atype = type; atype->declarray; atype = type_array_get_element(atype)) + for (atype = type; + is_array(atype) && !type_array_is_decl_as_ptr(atype); + atype = type_array_get_element(atype)) { arraydata[0] = type_array_get_dim(atype); arraydata[1] = 0; diff --git a/tools/wine.inf.in b/tools/wine.inf.in index 3f3afae0a1b..d77b8c8ef34 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -2323,8 +2323,8 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 16422,Internet Explorer,iexplore.exe [SystemIni] -system.ini, mci,,"MPEGVideo=mciqtz.drv" -system.ini, mci,,"MPEGVideo2=mciqtz.drv" +system.ini, mci,,"MPEGVideo=mciqtz32.dll" +system.ini, mci,,"MPEGVideo2=mciqtz32.dll" system.ini, mci,,"avivideo=mciavi32.dll" system.ini, mci,,"cdaudio=mcicda.dll" system.ini, mci,,"sequencer=mciseq.dll" diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 572f4652cde..381826491de 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -89,6 +89,7 @@ typedef struct char *file_name; /* file name of the dll */ char *dll_name; /* internal name of the dll */ char *init_func; /* initialization routine */ + char *main_module; /* main Win32 module for Win16 specs */ SPEC_TYPE type; /* type of dll (Win16/Win32) */ int base; /* ordinal base */ int limit; /* ordinal limit */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index fcd958d24ac..1cc36892511 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -468,7 +468,7 @@ static void check_undefined_exports( DLLSPEC *spec ) for (i = 0; i < spec->nb_entry_points; i++) { ORDDEF *odp = &spec->entry_points[i]; - if (odp->type == TYPE_STUB) continue; + if (odp->type == TYPE_STUB || odp->type == TYPE_ABS) continue; if (odp->flags & FLAG_FORWARD) continue; if (find_name( odp->link_name, &undef_symbols )) { diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index cab5243c7e4..69a1d5f22af 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -82,7 +82,6 @@ char *spec_file_name = NULL; FILE *output_file = NULL; const char *output_file_name = NULL; static const char *output_file_source_name; -static char *main_module; /* FIXME: to be removed */ char *as_command = NULL; char *ld_command = NULL; @@ -360,8 +359,7 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) else force_pointer_size = 8; break; case 'M': - spec->type = SPEC_WIN16; - main_module = xstrdup( optarg ); + spec->main_module = xstrdup( optarg ); break; case 'N': spec->dll_name = xstrdup( optarg ); @@ -586,24 +584,25 @@ int main(int argc, char **argv) if (spec->subsystem != IMAGE_SUBSYSTEM_NATIVE) spec->characteristics |= IMAGE_FILE_DLL; if (!spec_file_name) fatal_error( "missing .spec file\n" ); + if (spec->type == SPEC_WIN32 && spec->main_module) /* embedded 16-bit module */ + { + spec->type = SPEC_WIN16; + load_resources( argv, spec ); + if (parse_input_file( spec )) BuildSpec16File( spec ); + break; + } /* fall through */ case MODE_EXE: load_resources( argv, spec ); load_import_libs( argv ); if (spec_file_name && !parse_input_file( spec )) break; + read_undef_symbols( spec, argv ); switch (spec->type) { case SPEC_WIN16: - if (!main_module) - { - read_undef_symbols( spec, argv ); - output_spec16_file( spec ); - } - else - BuildSpec16File( spec ); + output_spec16_file( spec ); break; case SPEC_WIN32: - read_undef_symbols( spec, argv ); BuildSpec32File( spec ); break; default: assert(0); diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index dd79a1cd15f..fc14ad3a06c 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -743,6 +743,16 @@ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 ) odp->ordinal = 1; odp->link_name = xstrdup( ".L__wine_spec_dos_header" ); + if (spec16->main_module) + { + odp = add_entry_point( spec32 ); + odp->type = TYPE_EXTERN; + odp->name = xstrdup( "__wine_spec_main_module" ); + odp->lineno = 0; + odp->ordinal = 2; + odp->link_name = xstrdup( ".L__wine_spec_main_module" ); + } + assign_names( spec32 ); assign_ordinals( spec32 ); } diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 1465d2c4409..7c6fc459609 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -875,6 +875,12 @@ void output_spec16_file( DLLSPEC *spec16 ) output_exports( spec32 ); output_imports( spec16 ); output_resources( spec16 ); + if (spec16->main_module) + { + output( "\n\t%s\n", get_asm_string_section() ); + output( ".L__wine_spec_main_module:\n" ); + output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec16->main_module ); + } output_gnu_stack_note(); free_dll_spec( spec32 ); } diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 24580d4cfb6..2e8cf123459 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -308,8 +308,7 @@ void output_exports( DLLSPEC *spec ) /* output relays */ - /* we only support relay debugging on i386 and x86_64 */ - if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64) + if (!has_relays( spec )) { output( "\t%s 0\n", get_asm_ptr_keyword() ); return; diff --git a/tools/winedump/output.c b/tools/winedump/output.c index 66c5e4d6d5d..2b9d1ae6f4e 100644 --- a/tools/winedump/output.c +++ b/tools/winedump/output.c @@ -148,7 +148,7 @@ void output_header_preamble (void) fprintf (hfile, "/*\n * %s.dll\n *\n * Generated from %s.dll by winedump.\n *\n" - " * DO NOT SEND GENERATED DLLS FOR INCLUSION INTO WINE !\n * \n */" + " * DO NOT SEND GENERATED DLLS FOR INCLUSION INTO WINE !\n *\n */" "\n#ifndef __WINE_%s_DLL_H\n#define __WINE_%s_DLL_H\n\n" "#include \"windef.h\"\n#include \"wine/debug.h\"\n" "#include \"winbase.h\"\n#include \"winnt.h\"\n\n\n", diff --git a/tools/winedump/pdb.c b/tools/winedump/pdb.c index 3641ff6a2d2..421711350f0 100644 --- a/tools/winedump/pdb.c +++ b/tools/winedump/pdb.c @@ -334,7 +334,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader) lineno_size = sym_file->lineno_size; printf("\t--------symbol file----------- %s\n", file_name); printf("\tgot symbol_file\n" - "\t\tunknown1: %08x \n" + "\t\tunknown1: %08x\n" "\t\trange\n" "\t\t\tsegment: %04x\n" "\t\t\tpad1: %04x\n" @@ -374,7 +374,7 @@ static void pdb_dump_symbols(struct pdb_reader* reader) symbol_size = sym_file->symbol_size; lineno_size = sym_file->lineno_size; printf("\t--------symbol file----------- %s\n", file_name); - printf("\t\tunknown1: %08x \n" + printf("\t\tunknown1: %08x\n" "\t\trange\n" "\t\t\tsegment: %04x\n" "\t\t\tpad1: %04x\n" -- 2.11.4.GIT