From b4df600974edb5e8f2605b7535bdc185eedf218e Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Sun, 13 Dec 2009 11:45:16 +0100 Subject: [PATCH] push 38a8c0aff9170390b5a3ded41e7cf5b02f3a73d8 --- .gitignore | 4 +- aclocal.m4 | 15 +- configure | 48 +- configure.ac | 2 + dlls/Makefile.in | 4 - dlls/advapi32/registry.c | 14 +- dlls/advapi32/tests/crypt.c | 3 + dlls/advapi32/tests/eventlog.c | 39 +- dlls/comctl32/datetime.c | 3 + dlls/comctl32/listview.c | 4 +- dlls/comctl32/tests/datetime.c | 3 +- dlls/comctl32/tests/dpa.c | 4 + dlls/comctl32/tests/rebar.c | 1 + dlls/comctl32/tests/treeview.c | 235 ++- dlls/comctl32/treeview.c | 112 +- dlls/comdlg32/filedlg.c | 9 +- dlls/crypt32/chain.c | 9 +- dlls/crypt32/crl.c | 21 +- dlls/crypt32/ctl.c | 6 + dlls/crypt32/store.c | 9 +- dlls/crypt32/tests/cert.c | 15 +- dlls/crypt32/tests/chain.c | 2 +- dlls/crypt32/tests/protectdata.c | 4 +- dlls/d3d10/d3d10_main.c | 2 +- dlls/d3d10/d3d10_private.h | 2 +- dlls/d3d10core/d3d10core.spec | 2 +- dlls/d3d10core/d3d10core_main.c | 4 +- dlls/d3d10core/d3d10core_private.h | 2 +- dlls/d3d10core/tests/device.c | 6 +- dlls/d3d8/surface.c | 17 + dlls/d3d8/tests/stateblock.c | 2 +- dlls/d3d8/volume.c | 23 +- dlls/d3d9/surface.c | 17 + dlls/d3d9/tests/stateblock.c | 2 +- dlls/d3d9/volume.c | 23 +- dlls/dbghelp/Makefile.in | 1 - dlls/dbghelp/dbghelp.c | 2 +- dlls/dbghelp/dbghelp_private.h | 1 - dlls/dbghelp/memory.c | 61 - dlls/dbghelp/pe_module.c | 64 + dlls/dbghelp/stack.c | 29 + dlls/dbghelp/symbol.c | 1 + dlls/ddraw/ddraw.c | 13 - dlls/ddraw/tests/dsurface.c | 17 +- dlls/dmime/segment.c | 6 + dlls/dmloader/loader.c | 16 +- dlls/dsound/buffer.c | 187 ++ dlls/dsound/capture.c | 11 +- dlls/dsound/dsound.c | 10 +- dlls/dsound/dsound_main.c | 76 +- dlls/dsound/dsound_private.h | 5 +- dlls/dsound/propset.c | 2157 ++++++-------------- dlls/dxdiagn/provider.c | 1 + dlls/dxgi/device.c | 19 +- dlls/dxgi/dxgi.spec | 2 +- dlls/dxgi/dxgi_main.c | 4 +- dlls/dxgi/dxgi_private.h | 5 +- dlls/dxgi/output.c | 48 +- dlls/dxgi/surface.c | 29 +- dlls/dxgi/tests/device.c | 23 +- dlls/fusion/asmname.c | 5 + dlls/fusion/tests/asmenum.c | 2 + dlls/gdi.exe16/Makefile.in | 22 + dlls/{gdi32/bidi16.c => gdi.exe16/bidi.c} | 0 dlls/{gdi32 => gdi.exe16}/env.c | 0 dlls/{gdi32/gdi16.c => gdi.exe16/gdi.c} | 0 .../gdi.exe.spec => gdi.exe16/gdi.exe16.spec} | 0 dlls/{gdi32/metafile16.c => gdi.exe16/metafile.c} | 0 dlls/{gdi32/printdrv16.c => gdi.exe16/printdrv.c} | 1 - dlls/{gdi32/version16.rc => gdi.exe16/version.rc} | 0 dlls/gdi32/Makefile.in | 18 - dlls/gdi32/bidi.c | 1 + dlls/gdi32/driver.c | 1 + dlls/gdi32/enhmetafile.c | 24 +- dlls/gdi32/enhmfdrv/init.c | 1 + dlls/gdi32/font.c | 40 +- dlls/gdi32/freetype.c | 39 + dlls/gdi32/gdi32.spec | 3 - dlls/gdi32/gdi_main.c | 1 + dlls/gdi32/gdi_private.h | 7 +- dlls/gdi32/gdiobj.c | 1 + dlls/gdi32/metafile.c | 23 +- dlls/gdi32/mfdrv/graphics.c | 58 +- dlls/gdi32/mfdrv/init.c | 1 + dlls/gdi32/mfdrv/mapping.c | 4 + dlls/gdi32/mfdrv/objects.c | 1 + dlls/gdi32/mfdrv/text.c | 1 + dlls/gdi32/printdrv.c | 1 + dlls/gdiplus/image.c | 70 +- dlls/gdiplus/region.c | 2 + dlls/gdiplus/tests/brush.c | 3 + dlls/gdiplus/tests/customlinecap.c | 2 + dlls/gdiplus/tests/graphicspath.c | 3 + dlls/gdiplus/tests/pathiterator.c | 3 + dlls/hlink/tests/hlink.c | 2 + dlls/imagehlp/integrity.c | 168 +- dlls/imagehlp/modify.c | 32 +- dlls/imagehlp/tests/integrity.c | 74 +- dlls/inetcomm/mimeole.c | 1 + dlls/inetmib1/main.c | 71 +- dlls/iphlpapi/icmp.c | 3 +- dlls/jscript/engine.c | 2 +- dlls/jscript/function.c | 139 +- dlls/jscript/regexp.c | 16 +- dlls/jscript/string.c | 8 +- dlls/jscript/tests/api.js | 45 + dlls/jscript/tests/lang.js | 7 + dlls/jscript/tests/regexp.js | 48 +- dlls/kernel32/locale.c | 67 +- dlls/kernel32/tests/locale.c | 21 +- dlls/mmdevapi/Makefile.in | 14 + dlls/{gdi32/gdi_main.c => mmdevapi/main.c} | 50 +- dlls/mmdevapi/mmdevapi.spec | 19 + dlls/mmdevapi/regsvr.c | 181 ++ dlls/mpr/wnet.c | 6 + dlls/mshtml/htmldoc.c | 14 +- dlls/mshtml/htmlevent.c | 6 + dlls/mshtml/htmlevent.h | 1 + dlls/mshtml/htmlframebase.c | 134 +- dlls/mshtml/htmliframe.c | 14 +- dlls/mshtml/htmltextnode.c | 25 +- dlls/mshtml/htmlwindow.c | 12 +- dlls/mshtml/mshtml_private.h | 7 + dlls/mshtml/nsevents.c | 25 +- dlls/mshtml/oleobj.c | 39 +- dlls/mshtml/persist.c | 84 +- dlls/mshtml/script.c | 2 +- dlls/mshtml/tests/dom.c | 93 +- dlls/mshtml/tests/events.c | 23 +- dlls/mshtml/tests/htmldoc.c | 589 +++++- dlls/mshtml/tests/script.c | 19 + dlls/mshtml/view.c | 44 +- dlls/msi/action.c | 5 + dlls/msi/automation.c | 1175 +++++++---- dlls/msi/msipriv.h | 1 + dlls/msi/msiserver.idl | 27 + dlls/msi/msiserver_dispids.h | 8 + dlls/msi/record.c | 2 +- dlls/msi/table.c | 22 +- dlls/msi/tests/automation.c | 217 +- dlls/msi/tests/db.c | 9 +- dlls/msi/tests/format.c | 17 +- dlls/msi/tests/msi.c | 10 +- dlls/msi/tests/package.c | 11 +- dlls/msi/tests/record.c | 3 +- dlls/msi/tests/suminfo.c | 10 +- dlls/msvcrt/tests/file.c | 9 + dlls/msvcrt/tests/signal.c | 6 +- dlls/msxml3/node.c | 3 +- dlls/msxml3/tests/domdoc.c | 5 +- dlls/netapi32/access.c | 4 +- dlls/netapi32/tests/apibuf.c | 2 + dlls/ntdll/directory.c | 190 +- dlls/ntdll/file.c | 2 +- dlls/ntdll/tests/directory.c | 3 + dlls/ntdll/tests/file.c | 134 +- dlls/ntdll/tests/rtlstr.c | 7 +- dlls/ntdll/virtual.c | 2 +- dlls/ntoskrnl.exe/ntoskrnl.c | 10 + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ole32/compobj.c | 8 +- dlls/ole32/errorinfo.c | 4 + dlls/ole32/rpc.c | 2 +- dlls/ole32/stg_stream.c | 317 +-- dlls/ole32/storage32.c | 1106 ++++++++-- dlls/ole32/storage32.h | 86 +- dlls/ole32/tests/hglobalstream.c | 17 + dlls/ole32/tests/moniker.c | 6 +- dlls/ole32/tests/storage32.c | 158 +- dlls/oleaut32/dispatch.c | 31 +- dlls/oleaut32/tests/Makefile.in | 1 + dlls/oleaut32/tests/dispatch.c | 272 +++ dlls/oleaut32/tests/olepicture.c | 13 +- dlls/oleaut32/tests/safearray.c | 2 + dlls/oleaut32/tests/usrmarshal.c | 116 +- dlls/oleaut32/tests/vartype.c | 16 +- dlls/oleaut32/usrmarshal.c | 27 +- dlls/rpcrt4/ndr_marshall.c | 4 +- dlls/rsaenh/rsaenh.c | 47 +- dlls/rsaenh/tests/rsaenh.c | 5 +- dlls/setupapi/queue.c | 14 +- dlls/setupapi/tests/install.c | 56 + dlls/setupapi/tests/stringtable.c | 1 + dlls/shdocvw/tests/webbrowser.c | 5 +- dlls/shell32/shlview.c | 4 +- dlls/shell32/tests/progman_dde.c | 160 +- dlls/shell32/tests/shlfolder.c | 6 +- dlls/shlwapi/Makefile.in | 2 +- dlls/shlwapi/ordinal.c | 45 +- dlls/shlwapi/shlwapi.spec | 2 +- dlls/shlwapi/tests/ordinal.c | 686 +++++++ dlls/shlwapi/tests/url.c | 4 +- dlls/snmpapi/main.c | 18 + dlls/snmpapi/snmpapi.spec | 2 +- dlls/urlmon/Makefile.in | 11 +- dlls/urlmon/http.c | 9 +- dlls/urlmon/regsvr.c | 30 +- dlls/urlmon/tests/sec_mgr.c | 26 + dlls/urlmon/urlmon_main.c | 5 + dlls/urlmon/urlmon_main.h | 6 + include/ks.h => dlls/urlmon/urlmon_urlmon.idl | 9 +- dlls/urlmon/usrmarshal.c | 162 ++ dlls/userenv/tests/userenv.c | 8 + dlls/usp10/usp10.c | 2 + dlls/uxtheme/draw.c | 5 +- dlls/uxtheme/system.c | 7 +- dlls/windowscodecs/tests/bmpformat.c | 72 + dlls/windowscodecs/ungif.c | 5 +- dlls/wined3d/arb_program_shader.c | 108 +- dlls/wined3d/ati_fragment_shader.c | 6 +- dlls/wined3d/basetexture.c | 8 +- dlls/wined3d/buffer.c | 32 +- dlls/wined3d/context.c | 26 +- dlls/wined3d/cubetexture.c | 7 +- dlls/wined3d/device.c | 535 +---- dlls/wined3d/directx.c | 66 +- dlls/wined3d/glsl_shader.c | 4 +- dlls/wined3d/nvidia_texture_shader.c | 12 +- dlls/wined3d/palette.c | 3 +- dlls/wined3d/pixelshader.c | 10 - dlls/wined3d/query.c | 36 +- dlls/wined3d/resource.c | 18 +- dlls/wined3d/state.c | 180 +- dlls/wined3d/stateblock.c | 39 +- dlls/wined3d/surface.c | 194 +- dlls/wined3d/surface_base.c | 19 +- dlls/wined3d/surface_gdi.c | 3 +- dlls/wined3d/swapchain.c | 592 +++++- dlls/wined3d/swapchain_base.c | 4 +- dlls/wined3d/swapchain_gdi.c | 2 +- dlls/wined3d/texture.c | 7 +- dlls/wined3d/utils.c | 6 +- dlls/wined3d/vertexdeclaration.c | 13 +- dlls/wined3d/vertexshader.c | 9 - dlls/wined3d/volume.c | 13 +- dlls/wined3d/volumetexture.c | 7 +- dlls/wined3d/wined3d_private.h | 35 +- dlls/wineps.drv/builtin.c | 1 + dlls/wineps.drv/download.c | 1 + dlls/wineps.drv/driver.c | 1 + dlls/wineps.drv/escape.c | 141 +- dlls/wineps.drv/font.c | 1 + dlls/wineps.drv/graphics.c | 2 +- dlls/wineps.drv/init.c | 4 +- dlls/wineps.drv/ps.c | 46 +- dlls/wineps.drv/psdrv.h | 5 +- dlls/wineps.drv/text.c | 2 +- dlls/wineps.drv/truetype.c | 2 + dlls/wineps.drv/type1afm.c | 1 + dlls/winex11.drv/opengl.c | 2 +- dlls/winex11.drv/x11drv_main.c | 4 +- dlls/winhttp/net.c | 20 +- dlls/winhttp/tests/winhttp.c | 16 +- dlls/wininet/http.c | 10 +- dlls/wininet/internet.c | 4 +- dlls/wininet/tests/ftp.c | 39 +- dlls/wininet/tests/url.c | 159 +- dlls/winspool.drv/tests/info.c | 3 +- dlls/wintrust/crypt.c | 16 +- dlls/ws2_32/socket.c | 265 ++- dlls/xinput1_3/xinput1_3_main.c | 2 +- include/Makefile.in | 1 + include/audiopolicy.idl | 2 +- include/dbs.idl | 5 + include/ddk/wdm.h | 1 + include/devicetopology.idl | 3 + include/gdiplusflat.h | 39 + include/ks.h | 44 +- include/mmdeviceapi.idl | 250 +++ include/wine/wined3d.idl | 15 - include/wine/winuser16.h | 15 - programs/clock/Makefile.in | 1 + programs/clock/main.c | 77 +- programs/clock/main.h | 2 +- programs/clock/winclock.c | 29 +- programs/clock/winclock.h | 2 +- programs/cmd/Makefile.in | 2 +- programs/cmd/batch.c | 24 +- programs/cmd/builtins.c | 264 ++- programs/cmd/directory.c | 48 +- programs/cmd/wcmdmain.c | 168 +- programs/net/Makefile.in | 1 + programs/net/net.c | 18 +- programs/reg/reg.c | 7 +- programs/services/rpc.c | 39 +- programs/services/services.c | 4 +- programs/wineboot/shutdown.c | 8 +- programs/wineboot/wineboot.c | 2 +- programs/winedbg/Makefile.in | 2 + programs/winedbg/be_i386.c | 70 +- programs/winedbg/be_x86_64.c | 100 +- programs/winedbg/break.c | 14 +- programs/winedbg/dbg.y | 8 +- programs/winedbg/debug.l | 4 +- programs/winedbg/debugger.h | 24 +- programs/winedbg/gdbproxy.c | 21 +- programs/winedbg/info.c | 42 +- programs/winedbg/memory.c | 2 +- programs/winedbg/rsrc_Es.rc | 58 + programs/winedbg/source.c | 12 +- programs/winedbg/stack.c | 12 +- programs/winedbg/symbol.c | 19 +- programs/winedbg/tgt_active.c | 18 +- programs/winedbg/tgt_minidump.c | 4 +- programs/winedbg/types.c | 4 +- programs/winedbg/winedbg.c | 24 +- programs/xcopy/De.rc | 2 +- server/change.c | 4 +- server/fd.c | 24 +- server/file.c | 63 +- server/security.h | 1 + server/token.c | 2 +- tools/wine.inf.in | 1 + tools/winedump/debug.c | 106 +- tools/winedump/main.c | 7 + tools/winedump/pe.c | 20 + tools/winedump/winedump.h | 3 + 317 files changed, 10618 insertions(+), 5260 deletions(-) delete mode 100644 dlls/dbghelp/memory.c rewrite dlls/dsound/propset.c (82%) create mode 100644 dlls/gdi.exe16/Makefile.in rename dlls/{gdi32/bidi16.c => gdi.exe16/bidi.c} (100%) rename dlls/{gdi32 => gdi.exe16}/env.c (100%) rename dlls/{gdi32/gdi16.c => gdi.exe16/gdi.c} (100%) rename dlls/{gdi32/gdi.exe.spec => gdi.exe16/gdi.exe16.spec} (100%) rename dlls/{gdi32/metafile16.c => gdi.exe16/metafile.c} (100%) rename dlls/{gdi32/printdrv16.c => gdi.exe16/printdrv.c} (99%) rename dlls/{gdi32/version16.rc => gdi.exe16/version.rc} (100%) create mode 100644 dlls/mmdevapi/Makefile.in copy dlls/{gdi32/gdi_main.c => mmdevapi/main.c} (52%) create mode 100644 dlls/mmdevapi/mmdevapi.spec create mode 100644 dlls/mmdevapi/regsvr.c create mode 100644 dlls/oleaut32/tests/dispatch.c copy include/ks.h => dlls/urlmon/urlmon_urlmon.idl (86%) create mode 100644 dlls/urlmon/usrmarshal.c create mode 100644 include/mmdeviceapi.idl create mode 100644 programs/winedbg/rsrc_Es.rc diff --git a/.gitignore b/.gitignore index ade07836ed7..dcf494f8826 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ dlls/advapi32/svcctl.h dlls/advapi32/svcctl_c.c dlls/atl/atliface.h dlls/dxdiagn/fil_data.h -dlls/gdi.exe16 dlls/jscript/jsglobal.tlb dlls/jscript/parser.tab.c dlls/jscript/parser.tab.h @@ -118,6 +117,8 @@ dlls/stdole2.tlb/std_ole_v2.tlb dlls/stdole32.tlb/std_ole_v1.tlb dlls/sti/sti_wia.h dlls/sti/sti_wia_p.c +dlls/urlmon/urlmon_urlmon.h +dlls/urlmon/urlmon_urlmon_p.c dlls/user.exe16 dlls/wprocs.dll16 include/activaut.h @@ -157,6 +158,7 @@ include/mediaobj.h include/mimeinfo.h include/mimeole.h include/mlang.h +include/mmdeviceapi.h include/mmstream.h include/mscoree.h include/msctf.h diff --git a/aclocal.m4 b/aclocal.m4 index f7beb5db322..ce3941e561e 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -140,11 +140,16 @@ dnl dnl Usage: WINE_CHECK_MINGW_PROG(variable,prog,[value-if-not-found],[path]) dnl AC_DEFUN([WINE_CHECK_MINGW_PROG], -[AC_CHECK_PROGS([$1], - m4_foreach([ac_wine_prefix], - [$host_cpu-pc-mingw32, i586-mingw32msvc, i386-mingw32msvc, i686-mingw32, i586-mingw32, i486-mingw32, i386-mingw32, i686-pc-mingw32], - [ac_wine_prefix-$2 ]), - [$3],[$4])]) +[case "$host_cpu" in + i[[3456789]]86*) + ac_prefix_list="m4_foreach([ac_wine_prefix],[pc-mingw32, mingw32msvc, mingw32], + m4_foreach([ac_wine_cpu],[i686,i586,i486,i386],[ac_wine_cpu-ac_wine_prefix-$2 ]))" ;; + x86_64) + ac_prefix_list="m4_foreach([ac_wine_prefix],[pc-mingw32,w64-mingw32],[x86_64-ac_wine_prefix-$2 ])" ;; + *) + ac_prefix_list="" ;; +esac +AC_CHECK_PROGS([$1],[$ac_prefix_list],[$3],[$4])]) dnl **** Create nonexistent directories from config.status **** diff --git a/configure b/configure index cfb25e23076..ab891c4a836 100755 --- a/configure +++ b/configure @@ -8421,7 +8421,15 @@ fi if test "$cross_compiling" = "no" -a "$LIBEXT" != "dll" then - for ac_prog in $host_cpu-pc-mingw32-gcc i586-mingw32msvc-gcc i386-mingw32msvc-gcc i686-mingw32-gcc i586-mingw32-gcc i486-mingw32-gcc i386-mingw32-gcc i686-pc-mingw32-gcc + case "$host_cpu" in + i[3456789]86*) + ac_prefix_list="i686-pc-mingw32-gcc i586-pc-mingw32-gcc i486-pc-mingw32-gcc i386-pc-mingw32-gcc i686-mingw32msvc-gcc i586-mingw32msvc-gcc i486-mingw32msvc-gcc i386-mingw32msvc-gcc i686-mingw32-gcc i586-mingw32-gcc i486-mingw32-gcc i386-mingw32-gcc " ;; + x86_64) + ac_prefix_list="x86_64-pc-mingw32-gcc x86_64-w64-mingw32-gcc " ;; + *) + ac_prefix_list="" ;; +esac +for ac_prog in $ac_prefix_list do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -8464,7 +8472,15 @@ fi done test -n "$CROSSCC" || CROSSCC="false" - for ac_prog in $host_cpu-pc-mingw32-dlltool i586-mingw32msvc-dlltool i386-mingw32msvc-dlltool i686-mingw32-dlltool i586-mingw32-dlltool i486-mingw32-dlltool i386-mingw32-dlltool i686-pc-mingw32-dlltool + case "$host_cpu" in + i[3456789]86*) + ac_prefix_list="i686-pc-mingw32-dlltool i586-pc-mingw32-dlltool i486-pc-mingw32-dlltool i386-pc-mingw32-dlltool i686-mingw32msvc-dlltool i586-mingw32msvc-dlltool i486-mingw32msvc-dlltool i386-mingw32msvc-dlltool i686-mingw32-dlltool i586-mingw32-dlltool i486-mingw32-dlltool i386-mingw32-dlltool " ;; + x86_64) + ac_prefix_list="x86_64-pc-mingw32-dlltool x86_64-w64-mingw32-dlltool " ;; + *) + ac_prefix_list="" ;; +esac +for ac_prog in $ac_prefix_list do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -8507,7 +8523,15 @@ fi done test -n "$DLLTOOL" || DLLTOOL="false" - for ac_prog in $host_cpu-pc-mingw32-ar i586-mingw32msvc-ar i386-mingw32msvc-ar i686-mingw32-ar i586-mingw32-ar i486-mingw32-ar i386-mingw32-ar i686-pc-mingw32-ar + case "$host_cpu" in + i[3456789]86*) + ac_prefix_list="i686-pc-mingw32-ar i586-pc-mingw32-ar i486-pc-mingw32-ar i386-pc-mingw32-ar i686-mingw32msvc-ar i586-mingw32msvc-ar i486-mingw32msvc-ar i386-mingw32msvc-ar i686-mingw32-ar i586-mingw32-ar i486-mingw32-ar i386-mingw32-ar " ;; + x86_64) + ac_prefix_list="x86_64-pc-mingw32-ar x86_64-w64-mingw32-ar " ;; + *) + ac_prefix_list="" ;; +esac +for ac_prog in $ac_prefix_list do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -25212,6 +25236,14 @@ dlls/fwpuclnt/Makefile: dlls/fwpuclnt/Makefile.in dlls/Makedll.rules" ac_config_files="$ac_config_files dlls/fwpuclnt/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/gdi.exe16/Makefile" +test "x$enable_win16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + gdi.exe16" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/gdi.exe16/Makefile: dlls/gdi.exe16/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/gdi.exe16/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/gdi32/Makefile" test "x$enable_gdi32" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ gdi32" @@ -25692,6 +25724,14 @@ dlls/mlang/tests/Makefile: dlls/mlang/tests/Makefile.in dlls/Maketest.rules" ac_config_files="$ac_config_files dlls/mlang/tests/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + dlls/mmdevapi/Makefile" +test "x$enable_mmdevapi" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ + mmdevapi" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +dlls/mmdevapi/Makefile: dlls/mmdevapi/Makefile.in dlls/Makedll.rules" +ac_config_files="$ac_config_files dlls/mmdevapi/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ dlls/mmdevldr.vxd/Makefile" test "x$enable_win16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\ mmdevldr.vxd" @@ -29143,6 +29183,7 @@ do "dlls/fusion/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/fusion/Makefile" ;; "dlls/fusion/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/fusion/tests/Makefile" ;; "dlls/fwpuclnt/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/fwpuclnt/Makefile" ;; + "dlls/gdi.exe16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/gdi.exe16/Makefile" ;; "dlls/gdi32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/gdi32/Makefile" ;; "dlls/gdi32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/gdi32/tests/Makefile" ;; "dlls/gdiplus/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/gdiplus/Makefile" ;; @@ -29203,6 +29244,7 @@ do "dlls/midimap/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/midimap/Makefile" ;; "dlls/mlang/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mlang/Makefile" ;; "dlls/mlang/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mlang/tests/Makefile" ;; + "dlls/mmdevapi/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mmdevapi/Makefile" ;; "dlls/mmdevldr.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mmdevldr.vxd/Makefile" ;; "dlls/mmsystem.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/mmsystem.dll16/Makefile" ;; "dlls/monodebg.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/monodebg.vxd/Makefile" ;; diff --git a/configure.ac b/configure.ac index bf3e95727ab..e3329bb9f79 100644 --- a/configure.ac +++ b/configure.ac @@ -2273,6 +2273,7 @@ WINE_CONFIG_MAKEFILE([dlls/fltlib/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL WINE_CONFIG_MAKEFILE([dlls/fusion/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/fusion/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) WINE_CONFIG_MAKEFILE([dlls/fwpuclnt/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +WINE_CONFIG_MAKEFILE([dlls/gdi.exe16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) WINE_CONFIG_MAKEFILE([dlls/gdi32/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/gdi32/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) WINE_CONFIG_MAKEFILE([dlls/gdiplus/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) @@ -2333,6 +2334,7 @@ WINE_CONFIG_MAKEFILE([dlls/mciwave/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DL WINE_CONFIG_MAKEFILE([dlls/midimap/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/mlang/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/mlang/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests]) +WINE_CONFIG_MAKEFILE([dlls/mmdevapi/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) WINE_CONFIG_MAKEFILE([dlls/mmdevldr.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) WINE_CONFIG_MAKEFILE([dlls/mmsystem.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) WINE_CONFIG_MAKEFILE([dlls/monodebg.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 5150da9103d..092986e70b3 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -18,7 +18,6 @@ DOCSUBDIRS = $(DLLSUBDIRS) # 16-bit dlls WIN16_FILES = \ - gdi.exe16 \ krnl386.exe16 \ user.exe16 \ wprocs.dll16 @@ -31,9 +30,6 @@ all: $(BUILDSUBDIRS) @WIN16_FILES@ # Placeholders for 16-bit libraries -gdi.exe16: - echo "gdi32.dll" >$@ - krnl386.exe16: echo "kernel32.dll" >$@ diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 3762908aff1..28eabe3c562 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -137,7 +137,7 @@ static inline HKEY get_special_root_hkey( HKEY hkey ) if ((hkey >= HKEY_SPECIAL_ROOT_FIRST) && (hkey <= HKEY_SPECIAL_ROOT_LAST)) { if (!(ret = special_root_keys[(UINT_PTR)hkey - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST])) - ret = create_special_root_hkey( hkey, KEY_ALL_ACCESS ); + ret = create_special_root_hkey( hkey, MAXIMUM_ALLOWED ); } return ret; } @@ -233,7 +233,7 @@ LSTATUS WINAPI RegCreateKeyExA( HKEY hkey, LPCSTR name, DWORD reserved, LPSTR cl if (reserved) return ERROR_INVALID_PARAMETER; if (!is_version_nt()) { - access = KEY_ALL_ACCESS; /* Win95 ignores the access mask */ + access = MAXIMUM_ALLOWED; /* Win95 ignores the access mask */ if (name && *name == '\\') name++; /* win9x,ME ignores one (and only one) beginning backslash */ } if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE; @@ -279,7 +279,7 @@ LSTATUS WINAPI RegCreateKeyW( HKEY hkey, LPCWSTR lpSubKey, PHKEY phkResult ) /* FIXME: previous implementation converted ERROR_INVALID_HANDLE to ERROR_BADKEY, */ /* but at least my version of NT (4.0 SP5) doesn't do this. -- AJ */ return RegCreateKeyExW( hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, NULL, phkResult, NULL ); + MAXIMUM_ALLOWED, NULL, phkResult, NULL ); } @@ -291,7 +291,7 @@ LSTATUS WINAPI RegCreateKeyW( HKEY hkey, LPCWSTR lpSubKey, PHKEY phkResult ) LSTATUS WINAPI RegCreateKeyA( HKEY hkey, LPCSTR lpSubKey, PHKEY phkResult ) { return RegCreateKeyExA( hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, NULL, phkResult, NULL ); + MAXIMUM_ALLOWED, NULL, phkResult, NULL ); } @@ -348,7 +348,7 @@ LSTATUS WINAPI RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD reserved, REGSAM acc STRING nameA; NTSTATUS status; - if (!is_version_nt()) access = KEY_ALL_ACCESS; /* Win95 ignores the access mask */ + if (!is_version_nt()) access = MAXIMUM_ALLOWED; /* Win95 ignores the access mask */ else { /* NT+ allows beginning backslash for HKEY_CLASSES_ROOT */ @@ -389,7 +389,7 @@ LSTATUS WINAPI RegOpenKeyW( HKEY hkey, LPCWSTR name, PHKEY retkey ) *retkey = hkey; return ERROR_SUCCESS; } - return RegOpenKeyExW( hkey, name, 0, KEY_ALL_ACCESS, retkey ); + return RegOpenKeyExW( hkey, name, 0, MAXIMUM_ALLOWED, retkey ); } @@ -417,7 +417,7 @@ LSTATUS WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, PHKEY retkey ) *retkey = hkey; return ERROR_SUCCESS; } - return RegOpenKeyExA( hkey, name, 0, KEY_ALL_ACCESS, retkey ); + return RegOpenKeyExA( hkey, name, 0, MAXIMUM_ALLOWED, retkey ); } diff --git a/dlls/advapi32/tests/crypt.c b/dlls/advapi32/tests/crypt.c index 9eacbd4d113..f31723758dd 100644 --- a/dlls/advapi32/tests/crypt.c +++ b/dlls/advapi32/tests/crypt.c @@ -234,6 +234,7 @@ static void test_incorrect_api_usage(void) result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash); ok (result, "%d\n", GetLastError()); if (!result) return; + pCryptDestroyHash(hHash); result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey); ok (result, "%d\n", GetLastError()); @@ -557,6 +558,7 @@ static void test_enum_providers(void) ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider); ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen); + LocalFree(pszProvName); LocalFree(provider); } @@ -844,6 +846,7 @@ static void test_get_default_provider(void) ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName); ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize); + LocalFree(pszProvName); LocalFree(provName); } diff --git a/dlls/advapi32/tests/eventlog.c b/dlls/advapi32/tests/eventlog.c index 207fec5836d..c0f516acd6f 100644 --- a/dlls/advapi32/tests/eventlog.c +++ b/dlls/advapi32/tests/eventlog.c @@ -31,6 +31,8 @@ static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*); static BOOL (WINAPI *pGetEventLogInformation)(HANDLE,DWORD,LPVOID,DWORD,LPDWORD); + +static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD); static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(PVOID *); static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(PVOID); @@ -42,6 +44,7 @@ static void init_function_pointers(void) pCreateWellKnownSid = (void*)GetProcAddress(hadvapi32, "CreateWellKnownSid"); pGetEventLogInformation = (void*)GetProcAddress(hadvapi32, "GetEventLogInformation"); + pGetComputerNameExA = (void*)GetProcAddress(hkernel32, "GetComputerNameExA"); pWow64DisableWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64DisableWow64FsRedirection"); pWow64RevertWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64RevertWow64FsRedirection"); } @@ -709,8 +712,8 @@ static void test_readwrite(void) BOOL ret, sidavailable; BOOL on_vista = FALSE; /* Used to indicate Vista, W2K8 or Win7 */ int i; - char localcomputer[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD len = sizeof(localcomputer); + char *localcomputer = NULL; + DWORD size; if (pCreateWellKnownSid) { @@ -727,8 +730,6 @@ static void test_readwrite(void) user = NULL; } - GetComputerNameA(localcomputer, &len); - /* Write an event with an incorrect event type. This will fail on Windows 7 * but succeed on all others, hence it's not part of the struct. */ @@ -737,8 +738,7 @@ static void test_readwrite(void) { /* Intermittently seen on NT4 when tests are run immediately after boot */ win_skip("Could not get a handle to the eventlog\n"); - HeapFree(GetProcessHeap(), 0, user); - return; + goto cleanup; } count = 0xdeadbeef; @@ -756,9 +756,8 @@ static void test_readwrite(void) if (count != 0) { win_skip("We didn't open our new eventlog\n"); - HeapFree(GetProcessHeap(), 0, user); CloseEventLog(handle); - return; + goto cleanup; } } @@ -854,13 +853,29 @@ static void test_readwrite(void) if (count == 0) { skip("No events were written to the eventlog\n"); - return; + goto cleanup; } /* Report only once */ if (on_vista) skip("There is no DWORD alignment enforced for UserSid on Vista, W2K8 or Win7\n"); + if (on_vista && pGetComputerNameExA) + { + /* New Vista+ behavior */ + size = 0; + SetLastError(0xdeadbeef); + pGetComputerNameExA(ComputerNameDnsFullyQualified, NULL, &size); + localcomputer = HeapAlloc(GetProcessHeap(), 0, size); + pGetComputerNameExA(ComputerNameDnsFullyQualified, localcomputer, &size); + } + else + { + size = MAX_COMPUTERNAME_LENGTH + 1; + localcomputer = HeapAlloc(GetProcessHeap(), 0, size); + GetComputerNameA(localcomputer, &size); + } + /* Read all events from our created eventlog, one by one */ handle = OpenEventLogA(NULL, eventlogname); i = 0; @@ -962,8 +977,6 @@ static void test_readwrite(void) } CloseEventLog(handle); - HeapFree(GetProcessHeap(), 0, user); - /* Test clearing a real eventlog */ handle = OpenEventLogA(NULL, eventlogname); @@ -977,6 +990,10 @@ static void test_readwrite(void) ok(count == 0, "Expected an empty eventlog, got %d records\n", count); CloseEventLog(handle); + +cleanup: + HeapFree(GetProcessHeap(), 0, localcomputer); + HeapFree(GetProcessHeap(), 0, user); } /* Before Vista: diff --git a/dlls/comctl32/datetime.c b/dlls/comctl32/datetime.c index a7b433d8f61..c240d4fde40 100644 --- a/dlls/comctl32/datetime.c +++ b/dlls/comctl32/datetime.c @@ -1360,6 +1360,9 @@ DATETIME_Destroy (DATETIME_INFO *infoPtr) if (infoPtr->hMonthCal) DestroyWindow(infoPtr->hMonthCal); SetWindowLongPtrW( infoPtr->hwndSelf, 0, 0 ); /* clear infoPtr */ + Free (infoPtr->buflen); + Free (infoPtr->fieldRect); + Free (infoPtr->fieldspec); Free (infoPtr); return 0; } diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 8f6db541de4..3d327086501 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -2834,6 +2834,8 @@ static INT LISTVIEW_CalculateItemWidth(const LISTVIEW_INFO *infoPtr) nItemWidth += WIDTH_PADDING; } + TRACE("nItemWidth=%d\n", nItemWidth); + return nItemWidth; } @@ -7476,7 +7478,7 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, TRACE(" inserting at %d, sorted=%d, count=%d, iItem=%d\n", nItem, is_sorted, infoPtr->nItemCount, lpLVItem->iItem); nItem = DPA_InsertPtr( infoPtr->hdpaItems, nItem, hdpaSubItems ); if (nItem == -1) goto fail; - if (infoPtr->nItemCount++ == 0) LISTVIEW_UpdateItemSize(infoPtr); + if (++infoPtr->nItemCount > 0) LISTVIEW_UpdateItemSize(infoPtr); /* shift indices first so they don't get tangled */ LISTVIEW_ShiftIndices(infoPtr, nItem, 1); diff --git a/dlls/comctl32/tests/datetime.c b/dlls/comctl32/tests/datetime.c index a871930a576..a97ab342dae 100644 --- a/dlls/comctl32/tests/datetime.c +++ b/dlls/comctl32/tests/datetime.c @@ -667,7 +667,8 @@ static void test_wm_set_get_text(void) ret = SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)a_str); ok(CB_ERR == ret || - broken(1 == ret), /* comctl32 <= 4.72 */ + broken(0 == ret) || /* comctl32 <= 4.72 */ + broken(1 == ret), /* comctl32 <= 4.70 */ "Expected CB_ERR, got %ld\n", ret); buff[0] = 0; diff --git a/dlls/comctl32/tests/dpa.c b/dlls/comctl32/tests/dpa.c index c9e91c25437..5fb11e32070 100644 --- a/dlls/comctl32/tests/dpa.c +++ b/dlls/comctl32/tests/dpa.c @@ -347,6 +347,8 @@ static void test_dpa(void) pDPA_DeleteAllPtrs(dpa2); rc=CheckDPA(dpa2, 0, &dw2); ok(rc, "dw2=0x%x\n", dw2); + + pDPA_Destroy(dpa); pDPA_Destroy(dpa2); pDPA_Destroy(dpa3); } @@ -623,8 +625,10 @@ static void test_DPA_LoadStream(void) hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL); expect(S_OK, hRes); + dpa = NULL; hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL); expect(S_OK, hRes); + DPA_Destroy(dpa); /* try with altered dwData2 field */ header.dwSize = sizeof(header); diff --git a/dlls/comctl32/tests/rebar.c b/dlls/comctl32/tests/rebar.c index 6f263887934..45b3c066ac3 100644 --- a/dlls/comctl32/tests/rebar.c +++ b/dlls/comctl32/tests/rebar.c @@ -503,6 +503,7 @@ static void layout_test(void) check_sizes(); DestroyWindow(hRebar); + ImageList_Destroy(himl); } #if 0 /* use this to generate more tests */ diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c index adc74225b19..be89b8ff299 100644 --- a/dlls/comctl32/tests/treeview.c +++ b/dlls/comctl32/tests/treeview.c @@ -100,7 +100,7 @@ static const struct message focus_seq[] = { { 0 } }; -static const struct message TestGetSetBkColorSeq[] = { +static const struct message test_get_set_bkcolor_seq[] = { { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, { TVM_SETBKCOLOR, sent|wparam|lparam, 0, 0 }, { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, @@ -110,13 +110,13 @@ static const struct message TestGetSetBkColorSeq[] = { { 0 } }; -static const struct message TestGetSetImageListSeq[] = { +static const struct message test_get_set_imagelist_seq[] = { { TVM_SETIMAGELIST, sent|wparam|lparam, 0, 0 }, { TVM_GETIMAGELIST, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetIndentSeq[] = { +static const struct message test_get_set_indent_seq[] = { { TVM_SETINDENT, sent|wparam|lparam, 0, 0 }, { TVM_GETINDENT, sent|wparam|lparam, 0, 0 }, /* The actual amount to indent is dependent on the system for this message */ @@ -125,13 +125,13 @@ static const struct message TestGetSetIndentSeq[] = { { 0 } }; -static const struct message TestGetSetInsertMarkColorSeq[] = { +static const struct message test_get_set_insertmarkcolor_seq[] = { { TVM_SETINSERTMARKCOLOR, sent|wparam|lparam, 0, 0 }, { TVM_GETINSERTMARKCOLOR, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetItemSeq[] = { +static const struct message test_get_set_item_seq[] = { { TVM_GETITEM, sent }, { TVM_SETITEM, sent }, { TVM_GETITEM, sent }, @@ -139,7 +139,7 @@ static const struct message TestGetSetItemSeq[] = { { 0 } }; -static const struct message TestGetSetItemHeightSeq[] = { +static const struct message test_get_set_itemheight_seq[] = { { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, { TVM_SETITEMHEIGHT, sent|wparam|lparam, -1, 0 }, { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, @@ -150,13 +150,13 @@ static const struct message TestGetSetItemHeightSeq[] = { { 0 } }; -static const struct message TestGetSetScrollTimeSeq[] = { +static const struct message test_get_set_scrolltime_seq[] = { { TVM_SETSCROLLTIME, sent|wparam|lparam, 20, 0 }, { TVM_GETSCROLLTIME, sent|wparam|lparam, 0, 0 }, { 0 } }; -static const struct message TestGetSetTextColorSeq[] = { +static const struct message test_get_set_textcolor_seq[] = { { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, @@ -166,7 +166,7 @@ static const struct message TestGetSetTextColorSeq[] = { { 0 } }; -static const struct message TestGetSetToolTipsSeq[] = { +static const struct message test_get_set_tooltips_seq[] = { { WM_KILLFOCUS, sent }, { WM_IME_SETCONTEXT, sent|optional }, { WM_IME_NOTIFY, sent|optional }, @@ -175,7 +175,7 @@ static const struct message TestGetSetToolTipsSeq[] = { { 0 } }; -static const struct message TestGetSetUnicodeFormatSeq[] = { +static const struct message test_get_set_unicodeformat_seq[] = { { TVM_SETUNICODEFORMAT, sent|wparam|lparam, TRUE, 0 }, { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, @@ -186,7 +186,6 @@ static const struct message TestGetSetUnicodeFormatSeq[] = { static HWND hMainWnd; -static HWND hTree, hEdit; static HTREEITEM hRoot, hChild; static int pos = 0; @@ -283,6 +282,7 @@ static void fill_tree(HWND hTree) static void test_fillroot(void) { TVITEM tvi; + HWND hTree; hTree = create_treeview_control(); @@ -318,6 +318,7 @@ static void test_callback(void) CHAR test_string[] = "Test_string"; CHAR buf[128]; LRESULT ret; + HWND hTree; hTree = create_treeview_control(); fill_tree(hTree); @@ -379,6 +380,7 @@ static void test_callback(void) static void test_select(void) { BOOL r; + HWND hTree; hTree = create_treeview_control(); fill_tree(hTree); @@ -429,6 +431,7 @@ static void test_getitemtext(void) TVINSERTSTRUCTA ins; HTREEITEM hChild; TVITEM tvi; + HWND hTree; CHAR szBuffer[80] = "Blah"; int nBufferSize = sizeof(szBuffer)/sizeof(CHAR); @@ -467,6 +470,8 @@ static void test_focus(void) static CHAR child1[] = "Edit", child2[] = "A really long string"; HTREEITEM hChild1, hChild2; + HWND hTree; + HWND hEdit; hTree = create_treeview_control(); fill_tree(hTree); @@ -500,9 +505,15 @@ static void test_focus(void) DestroyWindow(hTree); } -static void TestGetSetBkColor(void) +static void test_get_set_bkcolor(void) { COLORREF crColor = RGB(0,0,0); + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* If the value is -1, the control is using the system color for the background color. */ crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); @@ -520,11 +531,22 @@ static void TestGetSetBkColor(void) /* Reset the default background */ SendMessage( hTree, TVM_SETBKCOLOR, 0, -1 ); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_bkcolor_seq, + "test get set bkcolor", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetImageList(void) +static void test_get_set_imagelist(void) { HIMAGELIST hImageList = NULL; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Test a NULL HIMAGELIST */ SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList ); @@ -532,13 +554,24 @@ static void TestGetSetImageList(void) ok(hImageList == NULL, "NULL image list, reported as 0x%p, expected 0.\n", hImageList); /* TODO: Test an actual image list */ + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_imagelist_seq, + "test get imagelist", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetIndent(void) +static void test_get_set_indent(void) { int ulIndent = -1; int ulMinIndent = -1; int ulMoreThanTwiceMin = -1; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Finding the minimum indent */ SendMessage( hTree, TVM_SETINDENT, 0, 0 ); @@ -549,21 +582,44 @@ static void TestGetSetIndent(void) SendMessage( hTree, TVM_SETINDENT, ulMoreThanTwiceMin, 0 ); ulIndent = (DWORD)SendMessage( hTree, TVM_GETINDENT, 0, 0 ); ok(ulIndent == ulMoreThanTwiceMin, "Indent reported as %d, expected %d\n", ulIndent, ulMoreThanTwiceMin); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_indent_seq, + "test get set indent", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetInsertMarkColor(void) +static void test_get_set_insertmark(void) { COLORREF crColor = RGB(0,0,0); + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + SendMessage( hTree, TVM_SETINSERTMARKCOLOR, 0, crColor ); crColor = (COLORREF)SendMessage( hTree, TVM_GETINSERTMARKCOLOR, 0, 0 ); ok(crColor == RGB(0,0,0), "Insert mark color reported as 0x%.8x, expected 0x00000000\n", crColor); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_insertmarkcolor_seq, + "test get set insertmark color", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetItem(void) +static void test_get_set_item(void) { TVITEM tviRoot = {0}; int nBufferSize = 80; char szBuffer[80] = {0}; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Test the root item */ tviRoot.hItem = hRoot; @@ -584,12 +640,23 @@ static void TestGetSetItem(void) memset(szBuffer, 0, nBufferSize); strncpy(szBuffer, "Root", nBufferSize); SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot ); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq, + "test get set item", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetItemHeight(void) +static void test_get_set_itemheight(void) { int ulOldHeight = 0; int ulNewHeight = 0; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Assuming default height to begin with */ ulOldHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); @@ -608,21 +675,45 @@ static void TestGetSetItemHeight(void) SendMessage( hTree, TVM_SETITEMHEIGHT, 9, 0 ); ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); ok(ulNewHeight == 8, "Uneven height not set properly, reported %d, expected %d\n", ulNewHeight, 8); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_itemheight_seq, + "test get set item height", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetScrollTime(void) +static void test_get_set_scrolltime(void) { int ulExpectedTime = 20; int ulTime = 0; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + SendMessage( hTree, TVM_SETSCROLLTIME, ulExpectedTime, 0 ); ulTime = (int)SendMessage( hTree, TVM_GETSCROLLTIME, 0, 0 ); ok(ulTime == ulExpectedTime, "Scroll time reported as %d, expected %d\n", ulTime, ulExpectedTime); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_scrolltime_seq, + "test get set scroll time", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetTextColor(void) +static void test_get_set_textcolor(void) { /* If the value is -1, the control is using the system color for the text color. */ COLORREF crColor = RGB(0,0,0); + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); + crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 ); ok(crColor == -1, "Default text color reported as 0x%.8x\n", crColor); @@ -638,12 +729,23 @@ static void TestGetSetTextColor(void) /* Reset the default text color */ SendMessage( hTree, TVM_SETTEXTCOLOR, 0, -1 ); + + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_textcolor_seq, + "test get set text color", FALSE); + + DestroyWindow(hTree); } -static void TestGetSetToolTips(void) +static void test_get_set_tooltips(void) { HWND hwndLastToolTip = NULL; HWND hPopupTreeView; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */ hPopupTreeView = CreateWindow(WC_TREEVIEW, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100, hMainWnd, NULL, NULL, NULL); @@ -654,13 +756,23 @@ static void TestGetSetToolTips(void) hwndLastToolTip = (HWND)SendMessage( hTree, TVM_GETTOOLTIPS, 0, 0 ); ok(hwndLastToolTip == NULL, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_tooltips_seq, + "test get set tooltips", TRUE); + /* TODO: Add a test of an actual tooltip */ + DestroyWindow(hTree); } -static void TestGetSetUnicodeFormat(void) +static void test_get_set_unicodeformat(void) { BOOL bPreviousSetting = 0; BOOL bNewSetting = 0; + HWND hTree; + + hTree = create_treeview_control(); + fill_tree(hTree); + + flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); /* Set to Unicode */ bPreviousSetting = (BOOL)SendMessage( hTree, TVM_SETUNICODEFORMAT, 1, 0 ); @@ -674,72 +786,9 @@ static void TestGetSetUnicodeFormat(void) /* Revert to original setting */ SendMessage( hTree, TVM_SETUNICODEFORMAT, (LPARAM)bPreviousSetting, 0 ); -} - -static void test_getset(void) -{ - hTree = create_treeview_control(); - fill_tree(hTree); - - /* TVM_GETBKCOLOR and TVM_SETBKCOLOR */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetBkColor(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetBkColorSeq, - "TestGetSetBkColor", FALSE); - - /* TVM_GETIMAGELIST and TVM_SETIMAGELIST */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetImageList(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetImageListSeq, - "TestGetImageList", FALSE); - - /* TVM_SETINDENT and TVM_GETINDENT */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetIndent(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetIndentSeq, - "TestGetSetIndent", FALSE); - - /* TVM_GETINSERTMARKCOLOR and TVM_GETINSERTMARKCOLOR */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetInsertMarkColor(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetInsertMarkColorSeq, - "TestGetSetInsertMarkColor", FALSE); - - /* TVM_GETITEM and TVM_SETITEM */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetItem(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetItemSeq, - "TestGetSetItem", FALSE); - - /* TVM_GETITEMHEIGHT and TVM_SETITEMHEIGHT */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetItemHeight(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetItemHeightSeq, - "TestGetSetItemHeight", FALSE); - - /* TVM_GETSCROLLTIME and TVM_SETSCROLLTIME */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetScrollTime(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetScrollTimeSeq, - "TestGetSetScrollTime", FALSE); - /* TVM_GETTEXTCOLOR and TVM_SETTEXTCOLOR */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetTextColor(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetTextColorSeq, - "TestGetSetTextColor", FALSE); - - /* TVM_GETTOOLTIPS and TVM_SETTOOLTIPS */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetToolTips(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetToolTipsSeq, - "TestGetSetToolTips", TRUE); - - /* TVM_GETUNICODEFORMAT and TVM_SETUNICODEFORMAT */ - flush_sequences(MsgSequences, NUM_MSG_SEQUENCES); - TestGetSetUnicodeFormat(); - ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, TestGetSetUnicodeFormatSeq, - "TestGetSetUnicodeFormat", FALSE); + ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_unicodeformat_seq, + "test get set unicode format", FALSE); DestroyWindow(hTree); } @@ -796,6 +845,7 @@ static void test_expandinvisible(void) RECT dummyRect; BOOL nodeVisible; LRESULT ret; + HWND hTree; hTree = create_treeview_control(); @@ -868,6 +918,7 @@ static void test_itemedit(void) HWND edit; TVITEMA item; CHAR buff[2]; + HWND hTree; hTree = create_treeview_control(); fill_tree(hTree); @@ -972,7 +1023,6 @@ START_TEST(treeview) wc.lpfnWndProc = MyWndProc; RegisterClassA(&wc); - hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0); @@ -983,7 +1033,16 @@ START_TEST(treeview) test_select(); test_getitemtext(); test_focus(); - test_getset(); + test_get_set_bkcolor(); + test_get_set_imagelist(); + test_get_set_indent(); + test_get_set_insertmark(); + test_get_set_item(); + test_get_set_itemheight(); + test_get_set_scrolltime(); + test_get_set_textcolor(); + test_get_set_tooltips(); + test_get_set_unicodeformat(); test_callback(); test_expandinvisible(); test_itemedit(); diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index d762a79ea3f..30699c5e952 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -63,6 +63,8 @@ #include "wine/unicode.h" #include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(treeview); + /* internal structures */ typedef struct _TREEITEM /* HTREEITEM is a _TREEINFO *. */ @@ -153,10 +155,10 @@ typedef struct tagTREEVIEW_INFO int stateImageWidth; HDPA items; - DWORD lastKeyPressTimestamp; /* Added */ - WPARAM charCode; /* Added */ - INT nSearchParamLength; /* Added */ - WCHAR szSearchParam[ MAX_PATH ]; /* Added */ + DWORD lastKeyPressTimestamp; + WPARAM charCode; + INT nSearchParamLength; + WCHAR szSearchParam[ MAX_PATH ]; } TREEVIEW_INFO; @@ -177,14 +179,6 @@ typedef struct tagTREEVIEW_INFO #define TV_EDIT_TIMER 2 #define TV_EDIT_TIMER_SET 2 - -VOID TREEVIEW_Register (VOID); -VOID TREEVIEW_Unregister (VOID); - - -WINE_DEFAULT_DEBUG_CHANNEL(treeview); - - #define TEXT_CALLBACK_SIZE 260 #define TREEVIEW_LEFT_MARGIN 8 @@ -213,8 +207,6 @@ static LRESULT TREEVIEW_RButtonUp(const TREEVIEW_INFO *, const POINT *); static LRESULT TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel); static VOID TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr); static LRESULT TREEVIEW_HScroll(TREEVIEW_INFO *, WPARAM); -static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND wParam, UINT lParam); - /* Random Utilities *****************************************************/ @@ -842,6 +834,23 @@ TREEVIEW_HasChildren(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem) return wineItem->cChildren > 0; } +static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand) +{ + INT format; + + TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand); + + if (nCommand != NF_REQUERY) return 0; + + format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY); + TRACE("format=%d\n", format); + + if (format != NFR_ANSI && format != NFR_UNICODE) return 0; + + infoPtr->bNtfUnicode = (format == NFR_UNICODE); + + return format; +} /* Item Position ********************************************************/ @@ -2858,10 +2867,16 @@ TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc) TREEVIEW_SendCustomDrawNotify(infoPtr, CDDS_POSTPAINT, hdc, rect); } +static inline void +TREEVIEW_InvalidateItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item) +{ + if (item) InvalidateRect(infoPtr->hwnd, &item->rect, TRUE); +} + static void TREEVIEW_Invalidate(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item) { - if (item != NULL) + if (item) InvalidateRect(infoPtr->hwnd, &item->rect, TRUE); else InvalidateRect(infoPtr->hwnd, NULL, TRUE); @@ -4026,7 +4041,6 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) HWND hwnd = infoPtr->hwnd; TVHITTESTINFO ht; BOOL bTrack, bDoLabelEdit; - HTREEITEM tempItem; /* If Edit control is active - kill it and return. * The best way to do it is to set focus to itself. @@ -4049,10 +4063,8 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) if(ht.hItem && (ht.flags & TVHT_ONITEM)) { infoPtr->focusedItem = ht.hItem; - InvalidateRect(hwnd, &ht.hItem->rect, TRUE); - - if(infoPtr->selectedItem) - InvalidateRect(hwnd, &(infoPtr->selectedItem->rect), TRUE); + TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem); + TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem); } bTrack = (ht.flags & TVHT_ONITEM) @@ -4086,12 +4098,11 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) if(infoPtr->focusedItem) { /* refresh the item that was focused */ - tempItem = infoPtr->focusedItem; - infoPtr->focusedItem = 0; - InvalidateRect(infoPtr->hwnd, &tempItem->rect, TRUE); + TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem); + infoPtr->focusedItem = NULL; /* refresh the selected item to return the filled background */ - InvalidateRect(infoPtr->hwnd, &(infoPtr->selectedItem->rect), TRUE); + TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem); } return 0; @@ -4311,7 +4322,6 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, INT cause) { TREEVIEW_ITEM *prevSelect; - RECT rcFocused; assert(newSelect == NULL || TREEVIEW_ValidItem(infoPtr, newSelect)); @@ -4321,12 +4331,8 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, /* reset and redraw focusedItem if focusedItem was set so we don't */ /* have to worry about the previously focused item when we set a new one */ - if(infoPtr->focusedItem) - { - rcFocused = (infoPtr->focusedItem)->rect; - infoPtr->focusedItem = 0; - InvalidateRect(infoPtr->hwnd, &rcFocused, TRUE); - } + TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem); + infoPtr->focusedItem = NULL; switch (action) { @@ -4355,10 +4361,8 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, TREEVIEW_EnsureVisible(infoPtr, infoPtr->selectedItem, FALSE); - if (prevSelect) - TREEVIEW_Invalidate(infoPtr, prevSelect); - if (newSelect) - TREEVIEW_Invalidate(infoPtr, newSelect); + TREEVIEW_InvalidateItem(infoPtr, prevSelect); + TREEVIEW_InvalidateItem(infoPtr, newSelect); TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SELCHANGEDW, @@ -5064,7 +5068,11 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr) { TRACE("\n"); + /* free item data */ TREEVIEW_RemoveTree(infoPtr); + /* root isn't freed with other items */ + TREEVIEW_FreeItem(infoPtr, infoPtr->root); + DPA_Destroy(infoPtr->items); /* tool tip is automatically destroyed: we are its owner */ @@ -5252,12 +5260,10 @@ TREEVIEW_KeyDown(TREEVIEW_INFO *infoPtr, WPARAM wParam) static LRESULT TREEVIEW_MouseLeave (TREEVIEW_INFO * infoPtr) { - if (infoPtr->hotItem) - { - /* remove hot effect from item */ - InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE); - infoPtr->hotItem = NULL; - } + /* remove hot effect from item */ + TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem); + infoPtr->hotItem = NULL; + return 0; } @@ -5297,12 +5303,10 @@ TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, LPARAM lParam) if (item != infoPtr->hotItem) { /* redraw old hot item */ - if (infoPtr->hotItem) - InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE); + TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem); infoPtr->hotItem = item; /* redraw new hot item */ - if (infoPtr->hotItem) - InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE); + TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem); } return 0; @@ -5366,24 +5370,6 @@ TREEVIEW_Notify(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) return DefWindowProcW(infoPtr->hwnd, WM_NOTIFY, wParam, lParam); } -static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand) -{ - INT format; - - TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand); - - if (nCommand != NF_REQUERY) return 0; - - format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY); - TRACE("format=%d\n", format); - - if (format != NFR_ANSI && format != NFR_UNICODE) return 0; - - infoPtr->bNtfUnicode = (format == NFR_UNICODE); - - return format; -} - static LRESULT TREEVIEW_Size(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c index afd02dcaa57..d8908fec180 100644 --- a/dlls/comdlg32/filedlg.c +++ b/dlls/comdlg32/filedlg.c @@ -1527,12 +1527,11 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) if ( win98plus && handledPath == FALSE && fodInfos->filter && *fodInfos->filter) { - BOOL searchMore = TRUE; LPCWSTR lpstrPos = fodInfos->filter; WIN32_FIND_DATAW FindFileData; HANDLE hFind; - while (searchMore) + while (1) { /* filter is a list... title\0ext\0......\0\0 */ @@ -1550,7 +1549,6 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) lpstrPos += lstrlenW(lpstrPos) + 1; } else { - searchMore = FALSE; MemFree(fodInfos->initdir); fodInfos->initdir = MemAlloc(MAX_PATH*sizeof(WCHAR)); @@ -1559,6 +1557,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd) handledPath = TRUE; TRACE("No initial dir specified, but files of type %s found in current, so using it\n", debugstr_w(lpstrPos)); + FindClose(hFind); break; } } @@ -3258,6 +3257,7 @@ static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMet static void FILEDLG95_LOOKIN_Clean(HWND hwnd) { FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); + LookInInfos *liInfos = GetPropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr); int iPos; int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB); @@ -3276,9 +3276,10 @@ static void FILEDLG95_LOOKIN_Clean(HWND hwnd) } /* LookInInfos structure */ + MemFree(liInfos); RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr); - } + /*********************************************************************** * FILEDLG95_FILENAME_FillFromSelection * diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index 5cc46b763bc..e5ad7dcf40c 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -2541,10 +2541,11 @@ static void CRYPT_CheckUsages(PCERT_CHAIN_CONTEXT chain, * key usage extension be present and that a particular purpose * be indicated in order for the certificate to be acceptable to * that application." - * For now I'm being more conservative and disallowing it. + * Not all web sites include the extended key usage extension, so + * accept chains without it. */ - WARN_(chain)("requested usage from a certificate with no usages\n"); - validForUsage = FALSE; + TRACE_(chain)("requested usage from certificate with no usages\n"); + validForUsage = TRUE; } if (!validForUsage) { @@ -2641,6 +2642,8 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, if (!pChain->TrustStatus.dwErrorStatus) CRYPT_VerifyChainRevocation(pChain, pTime, pChainPara, dwFlags); CRYPT_CheckUsages(pChain, pChainPara); + TRACE_(chain)("error status: %08x\n", + pChain->TrustStatus.dwErrorStatus); if (ppChainContext) *ppChainContext = pChain; else diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c index a24e6adf887..72180c52473 100644 --- a/dlls/crypt32/crl.c +++ b/dlls/crypt32/crl.c @@ -167,14 +167,21 @@ static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType, } else if (info->KeyId.cbData) { - if ((ext = CertFindExtension( - szOID_SUBJECT_KEY_IDENTIFIER, - issuer->pCertInfo->cExtension, - issuer->pCertInfo->rgExtension))) + DWORD size; + + ret = CertGetCertificateContextProperty(issuer, + CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); + if (ret && size == info->KeyId.cbData) { - if (info->KeyId.cbData == ext->Value.cbData) - ret = !memcmp(info->KeyId.pbData, - ext->Value.pbData, info->KeyId.cbData); + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + CertGetCertificateContextProperty(issuer, + CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); + ret = !memcmp(buf, info->KeyId.pbData, size); + CryptMemFree(buf); + } else ret = FALSE; } diff --git a/dlls/crypt32/ctl.c b/dlls/crypt32/ctl.c index 44b517aeff3..40895fa1bdb 100644 --- a/dlls/crypt32/ctl.c +++ b/dlls/crypt32/ctl.c @@ -113,7 +113,13 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore, break; case CERT_STORE_ADD_USE_EXISTING: if (existing) + { CtlContext_CopyProperties(existing, pCtlContext); + if (ppStoreContext) + *ppStoreContext = CertDuplicateCTLContext(existing); + } + else + toAdd = CertDuplicateCTLContext(pCtlContext); break; default: FIXME("Unimplemented add disposition %d\n", dwAddDisposition); diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 3a786b05cf4..153d3aa71ea 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -899,7 +899,8 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, if (existing) { CertContext_CopyProperties(existing, pCertContext); - *ppStoreContext = CertDuplicateCertificateContext(existing); + if (ppStoreContext) + *ppStoreContext = CertDuplicateCertificateContext(existing); } else toAdd = CertDuplicateCertificateContext(pCertContext); @@ -1090,7 +1091,13 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, break; case CERT_STORE_ADD_USE_EXISTING: if (existing) + { CrlContext_CopyProperties(existing, pCrlContext); + if (ppStoreContext) + *ppStoreContext = CertDuplicateCRLContext(existing); + } + else + toAdd = CertDuplicateCRLContext(pCrlContext); break; default: FIXME("Unimplemented add disposition %d\n", dwAddDisposition); diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 0566797925b..d3b362c8a34 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -1639,16 +1639,16 @@ static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen, /* Tests signing the certificate described by toBeSigned with the CSP passed in, * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a - * keyset named AT_SIGNATURE will be added to it. The signing key will be - * stored in *key, and the signature will be stored in sig. sigLen should be - * at least 64 bytes. + * keyset named AT_SIGNATURE will be added to it. The signature will be stored + * in sig. sigLen should be at least 64 bytes. */ static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, - LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen) + LPCSTR sigOID, BYTE *sig, DWORD *sigLen) { BOOL ret; DWORD size = 0; CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } }; + HCRYPTKEY key; /* These all crash ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); @@ -1680,7 +1680,7 @@ static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() == NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n", GetLastError()); - ret = CryptGenKey(csp, AT_SIGNATURE, 0, key); + ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key); ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); if (ret) { @@ -1700,6 +1700,7 @@ static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, size); } } + CryptDestroyKey(key); } } @@ -1809,7 +1810,6 @@ static void testCertSigs(void) HCRYPTPROV csp; CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert }; BOOL ret; - HCRYPTKEY key; BYTE sig[64]; DWORD sigSize = sizeof(sig); @@ -1820,10 +1820,9 @@ static void testCertSigs(void) CRYPT_NEWKEYSET); ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); - testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize); + testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, &sigSize); testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize); - CryptDestroyKey(key); CryptReleaseContext(csp, 0); ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_DELETEKEYSET); diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c index 4192e116d17..a626b82c4fe 100644 --- a/dlls/crypt32/tests/chain.c +++ b/dlls/crypt32/tests/chain.c @@ -4018,7 +4018,7 @@ static void check_ssl_policy(void) /* And again authenticating a client, but specify the size of the policy * parameter. */ - sslPolicyPara.cbSize = sizeof(sslPolicyCheck); + U(sslPolicyPara).cbSize = sizeof(sslPolicyCheck); sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT; for (i = 0; i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) diff --git a/dlls/crypt32/tests/protectdata.c b/dlls/crypt32/tests/protectdata.c index 91bad8e43c6..29d04e81aa6 100644 --- a/dlls/crypt32/tests/protectdata.c +++ b/dlls/crypt32/tests/protectdata.c @@ -235,8 +235,10 @@ static void test_simpleroundtrip(const char *plaintext) res = pCryptUnprotectData(&encrypted, NULL, NULL, NULL, NULL, 0, &output); ok(res != 0, "can't unprotect; last error %u\n", GetLastError()); - ok(output.cbData == strlen(plaintext), "output wrong length %d for input '%s', wanted %d\n", output.cbData, plaintext, strlen(plaintext)); + ok(output.cbData == strlen(plaintext), "output wrong length %d for input '%s', wanted %d\n", output.cbData, plaintext, lstrlenA(plaintext)); ok(!memcmp(plaintext, (char *)output.pbData, output.cbData), "output wrong contents for input '%s'\n", plaintext); + LocalFree(output.pbData); + LocalFree(encrypted.pbData); } START_TEST(protectdata) diff --git a/dlls/d3d10/d3d10_main.c b/dlls/d3d10/d3d10_main.c index 10bf5335606..65ce1e07d5f 100644 --- a/dlls/d3d10/d3d10_main.c +++ b/dlls/d3d10/d3d10_main.c @@ -124,7 +124,7 @@ HRESULT WINAPI D3D10CreateDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver } } - hr = D3D10CoreCreateDevice(factory, adapter, flags, 0, device); + hr = D3D10CoreCreateDevice(factory, adapter, flags, NULL, device); IDXGIAdapter_Release(adapter); IDXGIFactory_Release(factory); if (FAILED(hr)) diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h index f07711559b9..5bf59b1c463 100644 --- a/dlls/d3d10/d3d10_private.h +++ b/dlls/d3d10/d3d10_private.h @@ -179,6 +179,6 @@ HRESULT d3d10_effect_parse(struct d3d10_effect *This, const void *data, SIZE_T d /* D3D10Core */ HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, - UINT flags, DWORD unknown0, ID3D10Device **device); + UINT flags, void *unknown0, ID3D10Device **device); #endif /* __WINE_D3D10_PRIVATE_H */ diff --git a/dlls/d3d10core/d3d10core.spec b/dlls/d3d10core/d3d10core.spec index 9bf25b5c7f4..65698881c92 100644 --- a/dlls/d3d10core/d3d10core.spec +++ b/dlls/d3d10core/d3d10core.spec @@ -1,2 +1,2 @@ -@ stdcall D3D10CoreCreateDevice(ptr ptr long long ptr) +@ stdcall D3D10CoreCreateDevice(ptr ptr long ptr ptr) @ stdcall D3D10CoreRegisterLayers() diff --git a/dlls/d3d10core/d3d10core_main.c b/dlls/d3d10core/d3d10core_main.c index 4151dd05336..9d0c5d7e020 100644 --- a/dlls/d3d10core/d3d10core_main.c +++ b/dlls/d3d10core/d3d10core_main.c @@ -102,13 +102,13 @@ HRESULT WINAPI D3D10CoreRegisterLayers(void) } HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, - UINT flags, DWORD unknown0, ID3D10Device **device) + UINT flags, void *unknown0, ID3D10Device **device) { IUnknown *dxgi_device; HMODULE d3d10core; HRESULT hr; - TRACE("factory %p, adapter %p, flags %#x, unknown0 %#x, device %p\n", + TRACE("factory %p, adapter %p, flags %#x, unknown0 %p, device %p.\n", factory, adapter, flags, unknown0, device); d3d10core = GetModuleHandleA("d3d10core.dll"); diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 35d5ed3e256..cc3029fe642 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -257,7 +257,7 @@ struct dxgi_device_layer }; HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter, - UINT flags, DWORD unknown0, void **device); + UINT flags, void *unknown0, void **device); HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count); #endif /* __WINE_D3D10CORE_PRIVATE_H */ diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index fb166ec45bb..122a1543451 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -22,7 +22,7 @@ #include "wine/test.h" HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter, - UINT flags, DWORD unknown0, ID3D10Device **device); + UINT flags, void *unknown0, ID3D10Device **device); static ID3D10Device *create_device(void) { @@ -38,7 +38,7 @@ static ID3D10Device *create_device(void) ok(SUCCEEDED(hr), "EnumAdapters failed, hr %#x\n", hr); if (FAILED(hr)) goto cleanup; - hr = D3D10CoreCreateDevice(factory, adapter, 0, 0, &device); + hr = D3D10CoreCreateDevice(factory, adapter, 0, NULL, &device); if (FAILED(hr)) { HMODULE d3d10ref; @@ -59,7 +59,7 @@ static ID3D10Device *create_device(void) ok(SUCCEEDED(hr), "CreateSoftwareAdapter failed, hr %#x\n", hr); if (FAILED(hr)) goto cleanup; - hr = D3D10CoreCreateDevice(factory, adapter, 0, 0, &device); + hr = D3D10CoreCreateDevice(factory, adapter, 0, NULL, &device); ok(SUCCEEDED(hr), "Failed to create a REF device, hr %#x\n", hr); if (FAILED(hr)) goto cleanup; } diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c index 1d4b1dca0b6..cf72e3e7d22 100644 --- a/dlls/d3d8/surface.c +++ b/dlls/d3d8/surface.c @@ -106,6 +106,23 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(IDirect3DSurface8 *iface, TRACE("iface %p, device %p.\n", iface, device); + if (This->forwardReference) + { + IDirect3DResource8 *resource; + HRESULT hr; + + hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource8, (void **)&resource); + if (SUCCEEDED(hr)) + { + hr = IDirect3DResource8_GetDevice(resource, device); + IDirect3DResource8_Release(resource); + + TRACE("Returning device %p.\n", *device); + } + + return hr; + } + *device = (IDirect3DDevice8 *)This->parentDevice; IDirect3DDevice8_AddRef(*device); diff --git a/dlls/d3d8/tests/stateblock.c b/dlls/d3d8/tests/stateblock.c index 630c4deed07..33cc56d5429 100644 --- a/dlls/d3d8/tests/stateblock.c +++ b/dlls/d3d8/tests/stateblock.c @@ -1745,7 +1745,7 @@ static void resource_test_data_init(IDirect3DDevice8 *device, static void resource_poison_data_init(struct resource_test_data *data, const struct resource_test_arg *arg) { - DWORD poison = 0xdeadbeef; + DWORD_PTR poison = 0xdeadbeef; unsigned int i; data->vs = poison++; diff --git a/dlls/d3d8/volume.c b/dlls/d3d8/volume.c index 89489975654..8e8dc603075 100644 --- a/dlls/d3d8/volume.c +++ b/dlls/d3d8/volume.c @@ -94,19 +94,24 @@ static ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) { } /* IDirect3DVolume8 Interface follow: */ -static HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(LPDIRECT3DVOLUME8 iface, IDirect3DDevice8 **ppDevice) { +static HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(IDirect3DVolume8 *iface, IDirect3DDevice8 **device) +{ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface; - IWineD3DDevice *myDevice = NULL; + IDirect3DResource8 *resource; + HRESULT hr; - TRACE("iface %p, device %p.\n", iface, ppDevice); + TRACE("iface %p, device %p.\n", iface, device); - wined3d_mutex_lock(); - IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice); - IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice); - IWineD3DDevice_Release(myDevice); - wined3d_mutex_unlock(); + hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource8, (void **)&resource); + if (SUCCEEDED(hr)) + { + hr = IDirect3DResource8_GetDevice(resource, device); + IDirect3DResource8_Release(resource); - return D3D_OK; + TRACE("Returning device %p.\n", *device); + } + + return hr; } static HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) { diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index 6f55eca7f44..210a0ee1d45 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -108,6 +108,23 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDevice(IDirect3DSurface9 *iface, TRACE("iface %p, device %p.\n", iface, device); + if (This->forwardReference) + { + IDirect3DResource9 *resource; + HRESULT hr; + + hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource9, (void **)&resource); + if (SUCCEEDED(hr)) + { + hr = IDirect3DResource9_GetDevice(resource, device); + IDirect3DResource9_Release(resource); + + TRACE("Returning device %p.\n", *device); + } + + return hr; + } + *device = (IDirect3DDevice9 *)This->parentDevice; IDirect3DDevice9_AddRef(*device); diff --git a/dlls/d3d9/tests/stateblock.c b/dlls/d3d9/tests/stateblock.c index f5800624d82..9430ab21721 100644 --- a/dlls/d3d9/tests/stateblock.c +++ b/dlls/d3d9/tests/stateblock.c @@ -1974,7 +1974,7 @@ static void resource_test_data_init(IDirect3DDevice9 *device, static void resource_poison_data_init(struct resource_test_data *data, const struct resource_test_arg *arg) { - DWORD poison = 0xdeadbeef; + DWORD_PTR poison = 0xdeadbeef; unsigned int i; data->decl = (IDirect3DVertexDeclaration9 *)poison++; diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c index 0d83ce1655a..baa286b4f2a 100644 --- a/dlls/d3d9/volume.c +++ b/dlls/d3d9/volume.c @@ -94,21 +94,24 @@ static ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) { } /* IDirect3DVolume9 Interface follow: */ -static HRESULT WINAPI IDirect3DVolume9Impl_GetDevice(LPDIRECT3DVOLUME9 iface, IDirect3DDevice9** ppDevice) { +static HRESULT WINAPI IDirect3DVolume9Impl_GetDevice(IDirect3DVolume9 *iface, IDirect3DDevice9 **device) +{ IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; - IWineD3DDevice *myDevice = NULL; + IDirect3DResource9 *resource; + HRESULT hr; - TRACE("iface %p, device %p.\n", iface, ppDevice); + TRACE("iface %p, device %p.\n", iface, device); - wined3d_mutex_lock(); - - IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice); - IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice); - IWineD3DDevice_Release(myDevice); + hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource9, (void **)&resource); + if (SUCCEEDED(hr)) + { + hr = IDirect3DResource9_GetDevice(resource, device); + IDirect3DResource9_Release(resource); - wined3d_mutex_unlock(); + TRACE("Returning device %p.\n", *device); + } - return D3D_OK; + return hr; } static HRESULT WINAPI IDirect3DVolume9Impl_SetPrivateData(LPDIRECT3DVOLUME9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { diff --git a/dlls/dbghelp/Makefile.in b/dlls/dbghelp/Makefile.in index a44d3c9d58d..eaf0ae4ef02 100644 --- a/dlls/dbghelp/Makefile.in +++ b/dlls/dbghelp/Makefile.in @@ -16,7 +16,6 @@ C_SRCS = \ elf_module.c \ image.c \ macho_module.c \ - memory.c \ minidump.c \ module.c \ msc.c \ diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index 1f9f0f8abd7..b501425d522 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -524,7 +524,7 @@ BOOL pcs_callback(const struct process* pcs, ULONG action, void* data) case CBA_DEFERRED_SYMBOL_LOAD_FAILURE: case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL: case CBA_DEFERRED_SYMBOL_LOAD_START: - idslW = (IMAGEHLP_DEFERRED_SYMBOL_LOADW64*)(DWORD)data; + idslW = data; idsl.SizeOfStruct = sizeof(idsl); idsl.BaseOfImage = idslW->BaseOfImage; idsl.CheckSum = idslW->CheckSum; diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 4faae4d0344..cae3c95aeda 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -441,7 +441,6 @@ extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs); extern BOOL elf_synchronize_module_list(struct process* pcs); struct elf_thunk_area; extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks); -extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr); /* macho_module.c */ #define MACHO_NO_MAP ((const void*)-1) diff --git a/dlls/dbghelp/memory.c b/dlls/dbghelp/memory.c deleted file mode 100644 index 6f64016dabe..00000000000 --- a/dlls/dbghelp/memory.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * File memory.c - managing memory - * - * Copyright (C) 2004, Eric Pouech - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include "dbghelp_private.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); - -/****************************************************************** - * addr_to_linear - * - * converts an address into its linear value - */ -DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr) -{ - LDT_ENTRY le; - - switch (addr->Mode) - { - case AddrMode1616: - if (GetThreadSelectorEntry(hThread, addr->Segment, &le)) - return (le.HighWord.Bits.BaseHi << 24) + - (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + LOWORD(addr->Offset); - break; - case AddrMode1632: - if (GetThreadSelectorEntry(hThread, addr->Segment, &le)) - return (le.HighWord.Bits.BaseHi << 24) + - (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + addr->Offset; - break; - case AddrModeReal: - return (DWORD)(LOWORD(addr->Segment) << 4) + addr->Offset; - case AddrModeFlat: - return addr->Offset; - default: - FIXME("Unsupported (yet) mode (%x)\n", addr->Mode); - return 0; - } - FIXME("Failed to linearize address %04x:%08x (mode %x)\n", - addr->Segment, addr->Offset, addr->Mode); - return 0; -} diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c index 44a4d6a14b2..3b9cceb4337 100644 --- a/dlls/dbghelp/pe_module.c +++ b/dlls/dbghelp/pe_module.c @@ -36,6 +36,69 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); /****************************************************************** + * pe_load_symbol_table + * + * Use the COFF symbol table (if any) from the IMAGE_FILE_HEADER to set the absolute address + * of global symbols. + * Mingw32 requires this for stabs debug information as address for global variables isn't filled in + * (this is similar to what is done in elf_module.c when using the .symtab ELF section) + */ +static BOOL pe_load_symbol_table(struct module* module, IMAGE_NT_HEADERS* nth, void* mapping) +{ + const IMAGE_SYMBOL* isym; + int i, numsym, naux; + const char* strtable; + char tmp[9]; + const char* name; + struct hash_table_iter hti; + void* ptr; + struct symt_data* sym; + const IMAGE_SECTION_HEADER* sect; + + numsym = nth->FileHeader.NumberOfSymbols; + if (!nth->FileHeader.PointerToSymbolTable || !numsym) + return TRUE; + isym = (const IMAGE_SYMBOL*)((char*)mapping + nth->FileHeader.PointerToSymbolTable); + /* FIXME: no way to get strtable size */ + strtable = (const char*)&isym[numsym]; + sect = IMAGE_FIRST_SECTION(nth); + + for (i = 0; i < numsym; i+= naux, isym += naux) + { + if (isym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && + isym->SectionNumber > 0 && isym->SectionNumber <= nth->FileHeader.NumberOfSections) + { + if (isym->N.Name.Short) + { + name = memcpy(tmp, isym->N.ShortName, 8); + tmp[8] = '\0'; + } + else name = strtable + isym->N.Name.Long; + if (name[0] == '_') name++; + hash_table_iter_init(&module->ht_symbols, &hti, name); + while ((ptr = hash_table_iter_up(&hti))) + { + sym = GET_ENTRY(ptr, struct symt_data, hash_elt); + if (sym->symt.tag == SymTagData && + (sym->kind == DataIsGlobal || sym->kind == DataIsFileStatic) && + !strcmp(sym->hash_elt.name, name)) + { + TRACE("Changing absolute address for %d.%s: %lx -> %s\n", + isym->SectionNumber, name, sym->u.var.offset, + wine_dbgstr_longlong(module->module.BaseOfImage + + sect[isym->SectionNumber - 1].VirtualAddress + isym->Value)); + sym->u.var.offset = module->module.BaseOfImage + + sect[isym->SectionNumber - 1].VirtualAddress + isym->Value; + break; + } + } + } + naux = isym->NumberOfAuxSymbols + 1; + } + return TRUE; +} + +/****************************************************************** * pe_load_stabs * * look for stabs information in PE header (it's how the mingw compiler provides @@ -74,6 +137,7 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module, RtlImageRvaToVa(nth, mapping, stabstr, NULL), stabstrsize, NULL, NULL); + if (ret) pe_load_symbol_table(module, nth, mapping); } TRACE("%s the STABS debug info\n", ret ? "successfully loaded" : "failed to load"); diff --git a/dlls/dbghelp/stack.c b/dlls/dbghelp/stack.c index 3c66fcbc04c..959ab644840 100644 --- a/dlls/dbghelp/stack.c +++ b/dlls/dbghelp/stack.c @@ -56,6 +56,35 @@ static const char* wine_dbgstr_addr(const ADDRESS* addr) } } +static DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr) +{ + LDT_ENTRY le; + + switch (addr->Mode) + { + case AddrMode1616: + if (GetThreadSelectorEntry(hThread, addr->Segment, &le)) + return (le.HighWord.Bits.BaseHi << 24) + + (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + LOWORD(addr->Offset); + break; + case AddrMode1632: + if (GetThreadSelectorEntry(hThread, addr->Segment, &le)) + return (le.HighWord.Bits.BaseHi << 24) + + (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + addr->Offset; + break; + case AddrModeReal: + return (DWORD)(LOWORD(addr->Segment) << 4) + addr->Offset; + case AddrModeFlat: + return addr->Offset; + default: + FIXME("Unsupported (yet) mode (%x)\n", addr->Mode); + return 0; + } + FIXME("Failed to linearize address %04x:%08x (mode %x)\n", + addr->Segment, addr->Offset, addr->Mode); + return 0; +} + static BOOL CALLBACK read_mem(HANDLE hProcess, DWORD addr, void* buffer, DWORD size, LPDWORD nread) { diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index c322a62c45a..c266ce24f92 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -1034,6 +1034,7 @@ static BOOL sym_enum(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, regex_t mod_regex, sym_regex; pair.pcs = process_find_by_handle(hProcess); + if (!pair.pcs) return FALSE; if (BaseOfDll == 0) { /* do local variables ? */ diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index af5506d8f57..42ad0d98db0 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1307,21 +1307,8 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface, WINED3DFORMAT checkFormatList[] = { - WINED3DFMT_B8G8R8_UNORM, - WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B5G6R5_UNORM, - WINED3DFMT_B5G5R5X1_UNORM, - WINED3DFMT_B5G5R5A1_UNORM, - WINED3DFMT_B4G4R4A4_UNORM, - WINED3DFMT_B2G3R3_UNORM, - WINED3DFMT_B2G3R3A8_UNORM, - WINED3DFMT_B4G4R4X4_UNORM, - WINED3DFMT_R10G10B10A2_UNORM, - WINED3DFMT_R8G8B8A8_UNORM, - WINED3DFMT_R8G8B8X8_UNORM, - WINED3DFMT_B10G10R10A2_UNORM, - WINED3DFMT_P8_UINT_A8_UNORM, WINED3DFMT_P8_UINT, }; diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c index f6f1258ad52..ab0408bd288 100644 --- a/dlls/ddraw/tests/dsurface.c +++ b/dlls/ddraw/tests/dsurface.c @@ -3048,6 +3048,7 @@ static void GetDCFormatTest(void) const char *name; DDPIXELFORMAT fmt; BOOL getdc_capable; + HRESULT alt_result; } testdata[] = { { "D3DFMT_A8R8G8B8", @@ -3071,7 +3072,8 @@ static void GetDCFormatTest(void) sizeof(DDPIXELFORMAT), DDPF_RGB, 0, {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000} }, - TRUE + TRUE, + DDERR_CANTCREATEDC /* Vista+ */ }, { "D3DFMT_X8B8G8R8", @@ -3079,7 +3081,8 @@ static void GetDCFormatTest(void) sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000} }, - TRUE + TRUE, + DDERR_CANTCREATEDC /* Vista+ */ }, { "D3DFMT_A4R4G4B4", @@ -3087,7 +3090,8 @@ static void GetDCFormatTest(void) sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000} }, - TRUE + TRUE, + DDERR_CANTCREATEDC /* Vista+ */ }, { "D3DFMT_X4R4G4B4", @@ -3095,7 +3099,8 @@ static void GetDCFormatTest(void) sizeof(DDPIXELFORMAT), DDPF_RGB, 0, {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000} }, - TRUE + TRUE, + DDERR_CANTCREATEDC /* Vista+ */ }, { "D3DFMT_R5G6B5", @@ -3240,7 +3245,9 @@ static void GetDCFormatTest(void) hr = IDirectDrawSurface7_GetDC(surface, &dc); if(testdata[i].getdc_capable) { - ok(SUCCEEDED(hr), "GetDC on a %s surface failed(0x%08x), expected it to work\n", + ok(SUCCEEDED(hr) || + (testdata[i].alt_result && hr == testdata[i].alt_result), + "GetDC on a %s surface failed(0x%08x), expected it to work\n", testdata[i].name, hr); } else diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c index 64cb10a03c3..ca127d7c482 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c @@ -359,6 +359,12 @@ static HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetParam (LP LIST_FOR_EACH (pEntry, &This->Tracks) { pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry); + hr = IDirectMusicTrack_QueryInterface(pIt->pTrack, &IID_IPersistStream, (void**) &pCLSIDStream); + if (FAILED(hr)) { + ERR("(%p): object %p don't implement IPersistStream Interface. Expect a crash (critical problem)\n", This, pIt->pTrack); + continue ; + } + TRACE(" - %p -> 0x%x,%p\n", pIt, pIt->dwGroupBits, pIt->pTrack); if (0xFFFFFFFF != dwGroupBits && 0 == (pIt->dwGroupBits & dwGroupBits)) continue ; diff --git a/dlls/dmloader/loader.c b/dlls/dmloader/loader.c index 17a8eb29cf0..393b6b9fa27 100644 --- a/dlls/dmloader/loader.c +++ b/dlls/dmloader/loader.c @@ -333,18 +333,14 @@ static HRESULT WINAPI IDirectMusicLoaderImpl_IDirectMusicLoader_GetObject (LPDIR if (!pObjectEntry) { pObjectEntry = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(WINE_LOADER_ENTRY)); DM_STRUCT_INIT(&pObjectEntry->Desc); - if (pObject) { - DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc); - pObjectEntry->pObject = pObject; - pObjectEntry->bInvalidDefaultDLS = FALSE; - } + DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc); + pObjectEntry->pObject = pObject; + pObjectEntry->bInvalidDefaultDLS = FALSE; list_add_head (This->pObjects, &pObjectEntry->entry); } else { - if (pObject) { - DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc); - pObjectEntry->pObject = pObject; - pObjectEntry->bInvalidDefaultDLS = FALSE; - } + DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc); + pObjectEntry->pObject = pObject; + pObjectEntry->bInvalidDefaultDLS = FALSE; } TRACE(": filled in cache entry\n"); } else TRACE(": caching disabled\n"); diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 2a25d50a2c4..0e9096acc65 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -28,10 +28,12 @@ #include "winuser.h" #include "mmsystem.h" #include "winternl.h" +#include "vfwmsgs.h" #include "wine/debug.h" #include "dsound.h" #include "dsdriver.h" #include "dsound_private.h" +#include "dsconf.h" WINE_DEFAULT_DEBUG_CHANNEL(dsound); @@ -1538,3 +1540,188 @@ static HRESULT SecondaryBufferImpl_Destroy( return S_OK; } + +/******************************************************************************* + * IKsBufferPropertySet + */ + +/* IUnknown methods */ +static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface( + LPKSPROPERTYSET iface, + REFIID riid, + LPVOID *ppobj ) +{ + IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + + return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj); +} + +static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface) +{ + IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; + ULONG ref = InterlockedIncrement(&(This->ref)); + TRACE("(%p) ref was %d\n", This, ref - 1); + return ref; +} + +static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface) +{ + IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; + ULONG ref = InterlockedDecrement(&(This->ref)); + TRACE("(%p) ref was %d\n", This, ref + 1); + + if (!ref) { + This->dsb->iks = 0; + IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb); + HeapFree(GetProcessHeap(), 0, This); + TRACE("(%p) released\n", This); + } + return ref; +} + +static HRESULT WINAPI IKsBufferPropertySetImpl_Get( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + LPVOID pInstanceData, + ULONG cbInstanceData, + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; + PIDSDRIVERPROPERTYSET ps; + TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned); + + if (This->dsb->hwbuf) { + IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps); + + if (ps) { + DSPROPERTY prop; + HRESULT hres; + + prop.s.Set = *guidPropSet; + prop.s.Id = dwPropID; + prop.s.Flags = 0; /* unused */ + prop.s.InstanceId = (ULONG)This->dsb->device; + + + hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned); + + IDsDriverPropertySet_Release(ps); + + return hres; + } + } + + return E_PROP_ID_UNSUPPORTED; +} + +static HRESULT WINAPI IKsBufferPropertySetImpl_Set( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + LPVOID pInstanceData, + ULONG cbInstanceData, + LPVOID pPropData, + ULONG cbPropData ) +{ + IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; + PIDSDRIVERPROPERTYSET ps; + TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData); + + if (This->dsb->hwbuf) { + IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps); + + if (ps) { + DSPROPERTY prop; + HRESULT hres; + + prop.s.Set = *guidPropSet; + prop.s.Id = dwPropID; + prop.s.Flags = 0; /* unused */ + prop.s.InstanceId = (ULONG)This->dsb->device; + hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData); + + IDsDriverPropertySet_Release(ps); + + return hres; + } + } + + return E_PROP_ID_UNSUPPORTED; +} + +static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + PULONG pTypeSupport ) +{ + IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; + PIDSDRIVERPROPERTYSET ps; + TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport); + + if (This->dsb->hwbuf) { + IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps); + + if (ps) { + HRESULT hres; + + hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport); + + IDsDriverPropertySet_Release(ps); + + return hres; + } + } + + return E_PROP_ID_UNSUPPORTED; +} + +static const IKsPropertySetVtbl iksbvt = { + IKsBufferPropertySetImpl_QueryInterface, + IKsBufferPropertySetImpl_AddRef, + IKsBufferPropertySetImpl_Release, + IKsBufferPropertySetImpl_Get, + IKsBufferPropertySetImpl_Set, + IKsBufferPropertySetImpl_QuerySupport +}; + +HRESULT IKsBufferPropertySetImpl_Create( + IDirectSoundBufferImpl *dsb, + IKsBufferPropertySetImpl **piks) +{ + IKsBufferPropertySetImpl *iks; + TRACE("(%p,%p)\n",dsb,piks); + *piks = NULL; + + iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks)); + if (iks == 0) { + WARN("out of memory\n"); + *piks = NULL; + return DSERR_OUTOFMEMORY; + } + + iks->ref = 0; + iks->dsb = dsb; + dsb->iks = iks; + iks->lpVtbl = &iksbvt; + + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb); + + *piks = iks; + return S_OK; +} + +HRESULT IKsBufferPropertySetImpl_Destroy( + IKsBufferPropertySetImpl *piks) +{ + TRACE("(%p)\n",piks); + + while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0); + + return S_OK; +} diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index 26c86b8fac0..f2a26bcf76f 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -1059,13 +1059,10 @@ static HRESULT DirectSoundCaptureDevice_Initialize( return DSERR_NODRIVER; } - /* enumerate WINMM audio devices and find the one we want */ - for (wid=0; widData4[7] = ds_default_playback; TRACE("returns %s\n", get_device_id(pGuidDest)); - return DS_OK; + return DS_OK; } if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) || - IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) { - *pGuidDest = DSOUND_capture_guids[ds_default_capture]; + IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) { + *pGuidDest = DSOUND_capture_guid; + pGuidDest->Data4[7] = ds_default_capture; TRACE("returns %s\n", get_device_id(pGuidDest)); - return DS_OK; + return DS_OK; } *pGuidDest = *pGuidSrc; @@ -355,17 +357,16 @@ HRESULT WINAPI DirectSoundEnumerateW( if (devs > 0) { if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) { static const WCHAR empty[] = { 0 }; - for (wod = 0; wod < devs; ++wod) { - if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod] ) ) { - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", - "Primary Sound Driver",desc.szDrvname,lpContext); - MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1, - wDesc, sizeof(wDesc)/sizeof(WCHAR) ); - if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE) - return DS_OK; - } + wod = guid.Data4[7]; + if (wod < devs) { + err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); + if (err == DS_OK) { + TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", + "Primary Sound Driver",desc.szDrvname,lpContext); + MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1, + wDesc, sizeof(wDesc)/sizeof(WCHAR) ); + if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE) + return DS_OK; } } } @@ -374,13 +375,14 @@ HRESULT WINAPI DirectSoundEnumerateW( for (wod = 0; wod < devs; ++wod) { err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); if (err == DS_OK) { + guid.Data4[7] = wod; TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n", - debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext); + debugstr_guid(&guid),desc.szDesc,desc.szDrvname,lpContext); MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDesc, sizeof(wDesc)/sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wName, sizeof(wName)/sizeof(WCHAR) ); - if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], wDesc, wName, lpContext) == FALSE) + if (lpDSEnumCallback(&guid, wDesc, wName, lpContext) == FALSE) return DS_OK; } } @@ -452,19 +454,18 @@ DirectSoundCaptureEnumerateW( devs = waveInGetNumDevs(); if (devs > 0) { if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) { - for (wid = 0; wid < devs; ++wid) { - if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", - "Primary Sound Capture Driver",desc.szDrvname,lpContext); - MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1, - wDesc, sizeof(wDesc)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, - wName, sizeof(wName)/sizeof(WCHAR) ); - if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) - return DS_OK; - } + wid = guid.Data4[7]; + if (wid < devs) { + err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); + if (err == DS_OK) { + TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", + "Primary Sound Capture Driver",desc.szDrvname,lpContext); + MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1, + wDesc, sizeof(wDesc)/sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, + wName, sizeof(wName)/sizeof(WCHAR) ); + if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) + return DS_OK; } } } @@ -473,13 +474,14 @@ DirectSoundCaptureEnumerateW( for (wid = 0; wid < devs; ++wid) { err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); if (err == DS_OK) { + guid.Data4[7] = wid; TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n", - debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext); + debugstr_guid(&guid),desc.szDesc,desc.szDrvname,lpContext); MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDesc, sizeof(wDesc)/sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wName, sizeof(wName)/sizeof(WCHAR) ); - if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE) + if (lpDSEnumCallback(&guid, wDesc, wName, lpContext) == FALSE) return DS_OK; } } @@ -664,8 +666,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) for (i = 0; i < MAXWAVEDRIVERS; i++) { DSOUND_renderer[i] = NULL; DSOUND_capture[i] = NULL; - INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i); - INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i); } DisableThreadLibraryCalls(hInstDLL); /* Increase refcount on dsound by 1 */ diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 1b25ddd3b73..33c2f9849f3 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -414,10 +414,9 @@ HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8); #define DSOUND_FREQSHIFT (20) extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS]; -extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]; - extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS]; -extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS]; +extern GUID DSOUND_capture_guid; +extern GUID DSOUND_renderer_guid; HRESULT mmErr(UINT err); void setup_dsound_options(void); diff --git a/dlls/dsound/propset.c b/dlls/dsound/propset.c dissimilarity index 82% index 85bbbae3f90..19a88fb1e08 100644 --- a/dlls/dsound/propset.c +++ b/dlls/dsound/propset.c @@ -1,1511 +1,646 @@ -/* DirectSound - * - * Copyright 1998 Marcus Meissner - * Copyright 1998 Rob Riggs - * Copyright 2000-2002 TransGaming Technologies, Inc. - * - * 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 - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "mmsystem.h" -#include "winternl.h" -#include "winnls.h" -#include "vfwmsgs.h" -#include "mmddk.h" -#include "wine/debug.h" -#include "dsound.h" -#include "dsdriver.h" -#include "dsound_private.h" -#include "dsconf.h" - -#ifdef NONAMELESSSTRUCT -# define S(x) (x).s -#else -# define S(x) (x) -#endif - -WINE_DEFAULT_DEBUG_CHANNEL(dsound); - - -/******************************************************************************* - * IKsBufferPropertySet - */ - -/* IUnknown methods */ -static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface( - LPKSPROPERTYSET iface, - REFIID riid, - LPVOID *ppobj ) -{ - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - - return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj); -} - -static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface) -{ - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} - -static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface) -{ - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - ULONG ref = InterlockedDecrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref + 1); - - if (!ref) { - This->dsb->iks = 0; - IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb); - HeapFree(GetProcessHeap(), 0, This); - TRACE("(%p) released\n", This); - } - return ref; -} - -static HRESULT WINAPI IKsBufferPropertySetImpl_Get( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - LPVOID pInstanceData, - ULONG cbInstanceData, - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - PIDSDRIVERPROPERTYSET ps; - TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned); - - if (This->dsb->hwbuf) { - IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps); - - if (ps) { - DSPROPERTY prop; - HRESULT hres; - - S(prop).Set = *guidPropSet; - S(prop).Id = dwPropID; - S(prop).Flags = 0; /* unused */ - S(prop).InstanceId = (ULONG)This->dsb->device; - - hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned); - - IDsDriverPropertySet_Release(ps); - - return hres; - } - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT WINAPI IKsBufferPropertySetImpl_Set( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - LPVOID pInstanceData, - ULONG cbInstanceData, - LPVOID pPropData, - ULONG cbPropData ) -{ - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - PIDSDRIVERPROPERTYSET ps; - TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData); - - if (This->dsb->hwbuf) { - IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps); - - if (ps) { - DSPROPERTY prop; - HRESULT hres; - - S(prop).Set = *guidPropSet; - S(prop).Id = dwPropID; - S(prop).Flags = 0; /* unused */ - S(prop).InstanceId = (ULONG)This->dsb->device; - hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData); - - IDsDriverPropertySet_Release(ps); - - return hres; - } - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - PULONG pTypeSupport ) -{ - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - PIDSDRIVERPROPERTYSET ps; - TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport); - - if (This->dsb->hwbuf) { - IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps); - - if (ps) { - HRESULT hres; - - hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport); - - IDsDriverPropertySet_Release(ps); - - return hres; - } - } - - return E_PROP_ID_UNSUPPORTED; -} - -static const IKsPropertySetVtbl iksbvt = { - IKsBufferPropertySetImpl_QueryInterface, - IKsBufferPropertySetImpl_AddRef, - IKsBufferPropertySetImpl_Release, - IKsBufferPropertySetImpl_Get, - IKsBufferPropertySetImpl_Set, - IKsBufferPropertySetImpl_QuerySupport -}; - -HRESULT IKsBufferPropertySetImpl_Create( - IDirectSoundBufferImpl *dsb, - IKsBufferPropertySetImpl **piks) -{ - IKsBufferPropertySetImpl *iks; - TRACE("(%p,%p)\n",dsb,piks); - *piks = NULL; - - iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks)); - if (iks == 0) { - WARN("out of memory\n"); - *piks = NULL; - return DSERR_OUTOFMEMORY; - } - - iks->ref = 0; - iks->dsb = dsb; - dsb->iks = iks; - iks->lpVtbl = &iksbvt; - - IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb); - - *piks = iks; - return S_OK; -} - -HRESULT IKsBufferPropertySetImpl_Destroy( - IKsBufferPropertySetImpl *piks) -{ - TRACE("(%p)\n",piks); - - while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0); - - return S_OK; -} - -/******************************************************************************* - * IKsPrivatePropertySet - */ - -/* IUnknown methods */ -static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface( - LPKSPROPERTYSET iface, - REFIID riid, - LPVOID *ppobj ) -{ - IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - - if (IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IKsPropertySet)) { - *ppobj = iface; - IUnknown_AddRef(iface); - return S_OK; - } - *ppobj = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface) -{ - IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} - -static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface) -{ - IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; - ULONG ref = InterlockedDecrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref + 1); - - if (!ref) { - HeapFree(GetProcessHeap(), 0, This); - TRACE("(%p) released\n", This); - } - return ref; -} - -static HRESULT DSPROPERTY_WaveDeviceMappingA( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - HRESULT hr = DSERR_INVALIDPARAM; - PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - ppd = pPropData; - - if (!ppd) { - WARN("invalid parameter: pPropData\n"); - return DSERR_INVALIDPARAM; - } - - if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { - ULONG wod; - unsigned int wodn; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - WAVEOUTCAPSA capsA; - MMRESULT res; - res = waveOutGetDevCapsA(wod, &capsA, sizeof(capsA)); - if (res == MMSYSERR_NOERROR) { - if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) { - ppd->DeviceId = DSOUND_renderer_guids[wod]; - hr = DS_OK; - TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), - ppd->DeviceName); - break; - } - } - } - } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { - ULONG wid; - unsigned int widn; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - WAVEINCAPSA capsA; - MMRESULT res; - res = waveInGetDevCapsA(wid, &capsA, sizeof(capsA)); - if (res == MMSYSERR_NOERROR) { - if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) { - ppd->DeviceId = DSOUND_capture_guids[wid]; - TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), - ppd->DeviceName); - hr = DS_OK; - break; - } - } - } - } - - if (pcbReturned) - *pcbReturned = cbPropData; - - return hr; -} - -static HRESULT DSPROPERTY_WaveDeviceMappingW( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - HRESULT hr = DSERR_INVALIDPARAM; - PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - ppd = pPropData; - - if (!ppd) { - WARN("invalid parameter: pPropData\n"); - return DSERR_INVALIDPARAM; - } - - if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { - ULONG wod; - unsigned int wodn; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - WAVEOUTCAPSW capsW; - MMRESULT res; - res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW)); - if (res == MMSYSERR_NOERROR) { - if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) { - ppd->DeviceId = DSOUND_renderer_guids[wod]; - hr = DS_OK; - TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), - debugstr_w(ppd->DeviceName)); - break; - } - } - } - } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { - ULONG wid; - unsigned int widn; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - WAVEINCAPSW capsW; - MMRESULT res; - res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW)); - if (res == MMSYSERR_NOERROR) { - if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) { - ppd->DeviceId = DSOUND_capture_guids[wid]; - hr = DS_OK; - TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), - debugstr_w(ppd->DeviceName)); - break; - } - } - } - } - - if (pcbReturned) - *pcbReturned = cbPropData; - - return hr; -} - -static HRESULT DSPROPERTY_Description1( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - HRESULT err; - GUID dev_guid; - PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA ppd; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA) pPropData; - - if (!ppd) { - WARN("invalid parameter: pPropData\n"); - return DSERR_INVALIDPARAM; - } - - TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); - if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { - /* default device of type specified by ppd->DataFlow */ - if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - } else { - TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow); - } - FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n", - pPropData,cbPropData,pcbReturned); - return E_PROP_ID_UNSUPPORTED; - } - - ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - GetDeviceID(&ppd->DeviceId, &dev_guid); - - if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) || - IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) { - ULONG wod; - unsigned int wodn; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) { - DSDRIVERDESC desc; - ppd->WaveDeviceId = wod; - ppd->Devnode = wod; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA)); - lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA)); - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) ); - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - break; - } else { - WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) || - IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) { - ULONG wid; - unsigned int widn; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) { - DSDRIVERDESC desc; - ppd->WaveDeviceId = wid; - ppd->Devnode = wid; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA)); - lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA)); - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) ); - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - break; - } else { - WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } else { - BOOL found = FALSE; - ULONG wod; - unsigned int wodn; - /* given specific device so try the render devices first */ - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) { - DSDRIVERDESC desc; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - ppd->WaveDeviceId = wod; - ppd->Devnode = wod; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA)); - lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA)); - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) ); - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - found = TRUE; - break; - } else { - WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - - if (found == FALSE) { - ULONG wid; - unsigned int widn; - /* given specific device so try the capture devices next */ - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) { - DSDRIVERDESC desc; - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - ppd->WaveDeviceId = wid; - ppd->Devnode = wid; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA)); - lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA)); - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) ); - err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - found = TRUE; - break; - } else { - WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - - if (found == FALSE) { - WARN("device not found\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - - if (pcbReturned) { - *pcbReturned = cbPropData; - TRACE("*pcbReturned=%d\n", *pcbReturned); - } - - return S_OK; -} - -static HRESULT DSPROPERTY_DescriptionA( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = pPropData; - HRESULT err; - GUID dev_guid; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); - if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { - /* default device of type specified by ppd->DataFlow */ - if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - } else { - TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow); - } - FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n", - pPropData,cbPropData,pcbReturned); - return E_PROP_ID_UNSUPPORTED; - } - - ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - GetDeviceID(&ppd->DeviceId, &dev_guid); - - if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) || - IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) { - ULONG wod; - unsigned int wodn; - if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ) - TRACE("DSDEVID_DefaultPlayback\n"); - else - TRACE("DSDEVID_DefaultVoicePlayback\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) { - DSDRIVERDESC desc; - ppd->WaveDeviceId = wod; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - /* FIXME: this is a memory leak */ - CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1); - CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1); - CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1); - - if (szDescription && szModule && szInterface) { - strcpy(szDescription, desc.szDesc); - strcpy(szModule, desc.szDrvname); - strcpy(szInterface, "Interface"); - - ppd->Description = szDescription; - ppd->Module = szModule; - ppd->Interface = szInterface; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, szDescription); - HeapFree(GetProcessHeap(), 0, szModule); - HeapFree(GetProcessHeap(), 0, szInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) || - IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) { - ULONG wid; - unsigned int widn; - if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ) - TRACE("DSDEVID_DefaultCapture\n"); - else - TRACE("DSDEVID_DefaultVoiceCapture\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) { - DSDRIVERDESC desc; - ppd->WaveDeviceId = wid; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - /* FIXME: this is a memory leak */ - CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1); - CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1); - CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1); - - if (szDescription && szModule && szInterface) { - strcpy(szDescription, desc.szDesc); - strcpy(szModule, desc.szDrvname); - strcpy(szInterface, "Interface"); - - ppd->Description = szDescription; - ppd->Module = szModule; - ppd->Interface = szInterface; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, szDescription); - HeapFree(GetProcessHeap(), 0, szModule); - HeapFree(GetProcessHeap(), 0, szInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } else { - BOOL found = FALSE; - ULONG wod; - unsigned int wodn; - /* given specific device so try the render devices first */ - TRACE("Checking renderer devices\n"); - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) { - DSDRIVERDESC desc; - TRACE("DSOUND_renderer_guids[%d]\n", wod); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - ppd->WaveDeviceId = wod; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - /* FIXME: this is a memory leak */ - CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1); - CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1); - CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1); - - if (szDescription && szModule && szInterface) { - strcpy(szDescription, desc.szDesc); - strcpy(szModule, desc.szDrvname); - strcpy(szInterface, "Interface"); - - ppd->Description = szDescription; - ppd->Module = szModule; - ppd->Interface = szInterface; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - found = TRUE; - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, szDescription); - HeapFree(GetProcessHeap(), 0, szModule); - HeapFree(GetProcessHeap(), 0, szInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - - if (found == FALSE) { - ULONG wid; - unsigned int widn; - TRACE("Checking capture devices\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) { - DSDRIVERDESC desc; - TRACE("DSOUND_capture_guids[%d]\n", wid); - ppd->WaveDeviceId = wid; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - /* FIXME: this is a memory leak */ - CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1); - CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1); - CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1); - - if (szDescription && szModule && szInterface) { - strcpy(szDescription, desc.szDesc); - strcpy(szModule, desc.szDrvname); - strcpy(szInterface, "Interface"); - - ppd->Description = szDescription; - ppd->Module = szModule; - ppd->Interface = szInterface; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - found = TRUE; - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, szDescription); - HeapFree(GetProcessHeap(), 0, szModule); - HeapFree(GetProcessHeap(), 0, szInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } - - if (found == FALSE) { - WARN("device not found\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - - if (pcbReturned) { - *pcbReturned = cbPropData; - TRACE("*pcbReturned=%d\n", *pcbReturned); - } - - return S_OK; -} - -static HRESULT DSPROPERTY_DescriptionW( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData; - HRESULT err; - GUID dev_guid; - TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); - if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { - /* default device of type specified by ppd->DataFlow */ - if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); - } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { - TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); - } else { - TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow); - } - FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n", - pPropData,cbPropData,pcbReturned); - return E_PROP_ID_UNSUPPORTED; - } - - ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - GetDeviceID(&ppd->DeviceId, &dev_guid); - - if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) || - IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) { - ULONG wod; - unsigned int wodn; - if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ) - TRACE("DSDEVID_DefaultPlayback\n"); - else - TRACE("DSDEVID_DefaultVoicePlayback\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) { - DSDRIVERDESC desc; - TRACE("DSOUND_renderer_guids[%d]\n", wod); - ppd->WaveDeviceId = wod; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - /* FIXME: this is a memory leak */ - WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200); - - if (wDescription && wModule && wInterface) { - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 ); - - ppd->Description = wDescription; - ppd->Module = wModule; - ppd->Interface = wInterface; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, wDescription); - HeapFree(GetProcessHeap(), 0, wModule); - HeapFree(GetProcessHeap(), 0, wInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) || - IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) { - ULONG wid; - unsigned int widn; - if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture)) - TRACE("DSDEVID_DefaultCapture\n"); - else - TRACE("DSDEVID_DefaultVoiceCapture\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) { - DSDRIVERDESC desc; - ppd->WaveDeviceId = wid; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - /* FIXME: this is a memory leak */ - WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200); - - if (wDescription && wModule && wInterface) { - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 ); - - ppd->Description = wDescription; - ppd->Module = wModule; - ppd->Interface = wInterface; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, wDescription); - HeapFree(GetProcessHeap(), 0, wModule); - HeapFree(GetProcessHeap(), 0, wInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } else { - BOOL found = FALSE; - ULONG wod; - unsigned int wodn; - TRACE("Checking renderer devices\n"); - /* given specific device so try the render devices first */ - wodn = waveOutGetNumDevs(); - for (wod = 0; wod < wodn; wod++) { - if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) { - DSDRIVERDESC desc; - TRACE("DSOUND_renderer_guids[%d]\n", wod); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - ppd->WaveDeviceId = wod; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSDRIVER drv = NULL; - /* FIXME: this is a memory leak */ - WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200); - - if (wDescription && wModule && wInterface) { - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 ); - - ppd->Description = wDescription; - ppd->Module = wModule; - ppd->Interface = wInterface; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - found = TRUE; - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, wDescription); - HeapFree(GetProcessHeap(), 0, wModule); - HeapFree(GetProcessHeap(), 0, wInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - - if (found == FALSE) { - ULONG wid; - unsigned int widn; - TRACE("Checking capture devices\n"); - ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - widn = waveInGetNumDevs(); - for (wid = 0; wid < widn; wid++) { - if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) { - DSDRIVERDESC desc; - TRACE("DSOUND_capture_guids[%d]\n", wid); - ppd->WaveDeviceId = wid; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - /* FIXME: this is a memory leak */ - WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200); - - if (wDescription && wModule && wInterface) { - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 ); - - ppd->Description = wDescription; - ppd->Module = wModule; - ppd->Interface = wInterface; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0)); - if (err == DS_OK && drv) - ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - found = TRUE; - break; - } else { - WARN("no memory\n"); - HeapFree(GetProcessHeap(), 0, wDescription); - HeapFree(GetProcessHeap(), 0, wModule); - HeapFree(GetProcessHeap(), 0, wInterface); - return E_OUTOFMEMORY; - } - } else { - WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - } - } - - if (found == FALSE) { - WARN("device not found\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - - if (pcbReturned) { - *pcbReturned = cbPropData; - TRACE("*pcbReturned=%d\n", *pcbReturned); - } - - return S_OK; -} - -static HRESULT DSPROPERTY_Enumerate1( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA) pPropData; - HRESULT err; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - if (ppd) { - if (ppd->Callback) { - unsigned devs, wod, wid; - DSDRIVERDESC desc; - DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data; - - devs = waveOutGetNumDevs(); - for (wod = 0; wod < devs; ++wod) { - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - data.WaveDeviceId = wod; - data.DeviceId = DSOUND_renderer_guids[wod]; - lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA)); - lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA)); - - MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) ); - - data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - } - - devs = waveInGetNumDevs(); - for (wid = 0; wid < devs; ++wid) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - PIDSCDRIVER drv; - ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - data.WaveDeviceId = wid; - data.DeviceId = DSOUND_capture_guids[wid]; - lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA)); - lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA)); - - MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) ); - - data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - } - - return S_OK; - } - } - - if (pcbReturned) { - *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT DSPROPERTY_EnumerateA( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = pPropData; - HRESULT err; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - if (ppd) { - if (ppd->Callback) { - unsigned devs, wod, wid; - DSDRIVERDESC desc; - DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data; - - devs = waveOutGetNumDevs(); - for (wod = 0; wod < devs; ++wod) { - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - DWORD size; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0)); - if (err == DS_OK) { - WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size); - if (nameW) { - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size)); - if (err == DS_OK) { - CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR)); - if (szInterface) { - PIDSCDRIVER drv; - ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - data.WaveDeviceId = wod; - data.DeviceId = DSOUND_renderer_guids[wod]; - data.Description = desc.szDesc; - data.Module = desc.szDrvname; - WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL ); - data.Interface = szInterface; - - data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - HeapFree(GetProcessHeap(),0,szInterface); - } - } - HeapFree(GetProcessHeap(),0,nameW); - } - } - } - - devs = waveInGetNumDevs(); - for (wid = 0; wid < devs; ++wid) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - DWORD size; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0)); - if (err == DS_OK) { - WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size); - if (nameW) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size)); - if (err == DS_OK) { - CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR)); - if (szInterface) { - PIDSCDRIVER drv; - ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - data.WaveDeviceId = wid; - data.DeviceId = DSOUND_capture_guids[wid]; - data.Description = desc.szDesc; - data.Module = desc.szDrvname; - WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL ); - data.Interface = szInterface; - - data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - HeapFree(GetProcessHeap(),0,szInterface); - } - } - HeapFree(GetProcessHeap(),0,nameW); - } - } - } - - return S_OK; - } - } - - if (pcbReturned) { - *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT DSPROPERTY_EnumerateW( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData; - HRESULT err; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - if (ppd) { - if (ppd->Callback) { - unsigned devs, wod, wid; - DSDRIVERDESC desc; - DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; - - devs = waveOutGetNumDevs(); - for (wod = 0; wod < devs; ++wod) { - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200); - if (wDescription && wModule) { - DWORD size; - err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0)); - if (err == DS_OK) { - WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size); - if (wInterface) { - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size)); - if (err == DS_OK) { - PIDSCDRIVER drv; - ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; - data.WaveDeviceId = wod; - data.DeviceId = DSOUND_renderer_guids[wod]; - - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 ); - - data.Description = wDescription; - data.Module = wModule; - data.Interface = wInterface; - - data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - } - HeapFree(GetProcessHeap(),0,wInterface); - } - } - HeapFree(GetProcessHeap(),0,wDescription); - HeapFree(GetProcessHeap(),0,wModule); - } - } - - devs = waveInGetNumDevs(); - for (wid = 0; wid < devs; ++wid) { - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0)); - if (err == DS_OK) { - WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200); - WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200); - if (wDescription && wModule) { - DWORD size; - err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0)); - if (err == DS_OK) { - WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size); - if (wInterface) { - err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size)); - if (err == DS_OK) { - PIDSCDRIVER drv; - ZeroMemory(&data, sizeof(data)); - data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; - data.WaveDeviceId = wid; - data.DeviceId = DSOUND_capture_guids[wid]; - - MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 ); - MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 ); - - data.Description = wDescription; - data.Module = wModule; - data.Interface = wInterface; - data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0)); - if (err == DS_OK && drv) - data.Type = DIRECTSOUNDDEVICE_TYPE_VXD; - else - WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n"); - - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - } - HeapFree(GetProcessHeap(),0,wInterface); - } - } - HeapFree(GetProcessHeap(),0,wDescription); - HeapFree(GetProcessHeap(),0,wModule); - } - } - - return S_OK; - } - } - - if (pcbReturned) { - *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT WINAPI IKsPrivatePropertySetImpl_Get( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - LPVOID pInstanceData, - ULONG cbInstanceData, - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; - TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned); - - if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) { - switch (dwPropID) { - case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: - return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: - return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: - return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: - return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: - return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: - return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: - return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned); - case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: - return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned); - default: - FIXME("unsupported ID: %d\n",dwPropID); - break; - } - } else { - FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet)); - } - - if (pcbReturned) { - *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT WINAPI IKsPrivatePropertySetImpl_Set( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - LPVOID pInstanceData, - ULONG cbInstanceData, - LPVOID pPropData, - ULONG cbPropData ) -{ - IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; - - FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData); - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - PULONG pTypeSupport ) -{ - IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; - TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport); - - if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) { - switch (dwPropID) { - case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: - *pTypeSupport = KSPROPERTY_SUPPORT_GET; - return S_OK; - default: - FIXME("unsupported ID: %d\n",dwPropID); - break; - } - } else { - FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet)); - } - - return E_PROP_ID_UNSUPPORTED; -} - -static const IKsPropertySetVtbl ikspvt = { - IKsPrivatePropertySetImpl_QueryInterface, - IKsPrivatePropertySetImpl_AddRef, - IKsPrivatePropertySetImpl_Release, - IKsPrivatePropertySetImpl_Get, - IKsPrivatePropertySetImpl_Set, - IKsPrivatePropertySetImpl_QuerySupport -}; - -HRESULT IKsPrivatePropertySetImpl_Create( - REFIID riid, - IKsPrivatePropertySetImpl **piks) -{ - IKsPrivatePropertySetImpl *iks; - TRACE("(%s, %p)\n", debugstr_guid(riid), piks); - - if (!IsEqualIID(riid, &IID_IUnknown) && - !IsEqualIID(riid, &IID_IKsPropertySet)) { - *piks = 0; - return E_NOINTERFACE; - } - - iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks)); - iks->ref = 1; - iks->lpVtbl = &ikspvt; - - *piks = iks; - return S_OK; -} +/* DirectSound + * + * Copyright 1998 Marcus Meissner + * Copyright 1998 Rob Riggs + * Copyright 2000-2002 TransGaming Technologies, Inc. + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "mmsystem.h" +#include "winternl.h" +#include "winnls.h" +#include "vfwmsgs.h" +#include "mmddk.h" +#include "wine/debug.h" +#include "dsound.h" +#include "dsdriver.h" +#include "dsound_private.h" +#include "dsconf.h" + +#ifdef NONAMELESSSTRUCT +# define S(x) (x).s +#else +# define S(x) (x) +#endif + +WINE_DEFAULT_DEBUG_CHANNEL(dsound); + +/******************************************************************************* + * IKsPrivatePropertySet + */ + +/* IUnknown methods */ +static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface( + LPKSPROPERTYSET iface, + REFIID riid, + LPVOID *ppobj ) +{ + IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IKsPropertySet)) { + *ppobj = iface; + IUnknown_AddRef(iface); + return S_OK; + } + *ppobj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface) +{ + IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; + ULONG ref = InterlockedIncrement(&(This->ref)); + TRACE("(%p) ref was %d\n", This, ref - 1); + return ref; +} + +static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface) +{ + IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; + ULONG ref = InterlockedDecrement(&(This->ref)); + TRACE("(%p) ref was %d\n", This, ref + 1); + + if (!ref) { + HeapFree(GetProcessHeap(), 0, This); + TRACE("(%p) released\n", This); + } + return ref; +} + +static HRESULT DSPROPERTY_WaveDeviceMappingW( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + HRESULT hr = DSERR_INVALIDPARAM; + PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd; + TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + pPropData,cbPropData,pcbReturned); + + ppd = pPropData; + + if (!ppd) { + WARN("invalid parameter: pPropData\n"); + return DSERR_INVALIDPARAM; + } + + if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { + ULONG wod; + unsigned int wodn; + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); + wodn = waveOutGetNumDevs(); + for (wod = 0; wod < wodn; wod++) { + WAVEOUTCAPSW capsW; + MMRESULT res; + res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW)); + if (res == MMSYSERR_NOERROR) { + if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) { + ppd->DeviceId = DSOUND_renderer_guid; + ppd->DeviceId.Data4[7] = wod; + hr = DS_OK; + TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), + debugstr_w(ppd->DeviceName)); + break; + } + } + } + } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { + ULONG wid; + unsigned int widn; + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); + widn = waveInGetNumDevs(); + for (wid = 0; wid < widn; wid++) { + WAVEINCAPSW capsW; + MMRESULT res; + res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW)); + if (res == MMSYSERR_NOERROR) { + if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) { + ppd->DeviceId = DSOUND_capture_guid; + ppd->DeviceId.Data4[7] = wid; + hr = DS_OK; + TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId), + debugstr_w(ppd->DeviceName)); + break; + } + } + } + } + + if (pcbReturned) + *pcbReturned = cbPropData; + + return hr; +} + +static HRESULT DSPROPERTY_WaveDeviceMappingA( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data; + DWORD len; + HRESULT hr; + + TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + pPropData,cbPropData,pcbReturned); + + if (!ppd || !ppd->DeviceName) { + WARN("invalid parameter: ppd=%p\n", ppd); + return DSERR_INVALIDPARAM; + } + + data.DataFlow = ppd->DataFlow; + len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0); + data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!data.DeviceName) + return E_OUTOFMEMORY; + MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len); + + hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned); + HeapFree(GetProcessHeap(), 0, data.DeviceName); + ppd->DeviceId = data.DeviceId; + + if (pcbReturned) + *pcbReturned = cbPropData; + + return hr; +} + +static HRESULT DSPROPERTY_DescriptionW( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData; + HRESULT err; + GUID dev_guid; + ULONG wod, wid, wodn, widn; + DSDRIVERDESC desc; + + TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + pPropData,cbPropData,pcbReturned); + + TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); + if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { + /* default device of type specified by ppd->DataFlow */ + if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); + ppd->DeviceId = DSDEVID_DefaultCapture; + } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); + ppd->DeviceId = DSDEVID_DefaultPlayback; + } else { + WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow); + return E_PROP_ID_UNSUPPORTED; + } + } + + GetDeviceID(&ppd->DeviceId, &dev_guid); + + wodn = waveOutGetNumDevs(); + widn = waveInGetNumDevs(); + wid = wod = dev_guid.Data4[7]; + if (!memcmp(&dev_guid, &DSOUND_renderer_guid, sizeof(GUID)-1) + && wod < wodn) + { + ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; + ppd->WaveDeviceId = wod; + } + else if (!memcmp(&dev_guid, &DSOUND_capture_guid, sizeof(GUID)-1) + && wid < widn) + { + ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; + ppd->WaveDeviceId = wid; + } + else + { + WARN("Device not found\n"); + return E_PROP_ID_UNSUPPORTED; + } + + if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) + err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0); + else + err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0); + + if (err != MMSYSERR_NOERROR) + { + WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n"); + return E_PROP_ID_UNSUPPORTED; + } + else + { + /* FIXME: Still a memory leak.. */ + int desclen, modlen; + static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 }; + + modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 ); + desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 ); + ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR)); + ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR)); + ppd->Interface = wInterface; + if (!ppd->Description || !ppd->Module) + { + WARN("Out of memory\n"); + HeapFree(GetProcessHeap(), 0, ppd->Description); + HeapFree(GetProcessHeap(), 0, ppd->Module); + ppd->Description = ppd->Module = NULL; + return E_OUTOFMEMORY; + } + + MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen ); + MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen ); + } + + ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; + + if (pcbReturned) { + *pcbReturned = sizeof(*ppd); + TRACE("*pcbReturned=%d\n", *pcbReturned); + } + + return S_OK; +} + +static HRESULT DSPROPERTY_EnumerateW( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; + BOOL ret; + int widn, wodn, i; + TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + pPropData,cbPropData,pcbReturned); + + if (pcbReturned) + *pcbReturned = 0; + + if (!ppd || !ppd->Callback) + { + WARN("Invalid ppd %p\n", ppd); + return E_PROP_ID_UNSUPPORTED; + } + + wodn = waveOutGetNumDevs(); + widn = waveInGetNumDevs(); + + data.DeviceId = DSOUND_renderer_guid; + for (i = 0; i < wodn; ++i) + { + HRESULT hr; + data.DeviceId.Data4[7] = i; + hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); + if (FAILED(hr)) + { + ERR("DescriptionW failed!\n"); + return S_OK; + } + ret = ppd->Callback(&data, ppd->Context); + HeapFree(GetProcessHeap(), 0, data.Module); + HeapFree(GetProcessHeap(), 0, data.Description); + if (!ret) + return S_OK; + } + + data.DeviceId = DSOUND_capture_guid; + for (i = 0; i < widn; ++i) + { + HRESULT hr; + data.DeviceId.Data4[7] = i; + hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); + if (FAILED(hr)) + { + ERR("DescriptionW failed!\n"); + return S_OK; + } + ret = ppd->Callback(&data, ppd->Context); + HeapFree(GetProcessHeap(), 0, data.Module); + HeapFree(GetProcessHeap(), 0, data.Description); + if (!ret) + return S_OK; + } + return S_OK; +} + +static BOOL DSPROPERTY_descWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA) +{ + DWORD modlen, desclen; + static char Interface[] = "Interface"; + + modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL); + desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL); + dataA->Type = dataW->Type; + dataA->DataFlow = dataW->DataFlow; + dataA->DeviceId = dataW->DeviceId; + dataA->WaveDeviceId = dataW->WaveDeviceId; + dataA->Interface = Interface; + dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen); + dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen); + if (!dataA->Module || !dataA->Description) + { + HeapFree(GetProcessHeap(), 0, dataA->Module); + HeapFree(GetProcessHeap(), 0, dataA->Description); + dataA->Module = dataA->Description = NULL; + return FALSE; + } + + WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL); + return TRUE; +} + +static void DSPROPERTY_descWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1) +{ + data1->DeviceId = dataW->DeviceId; + lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW)); + lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW)); + WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL); + data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0; + data1->ModuleA[sizeof(data1->ModuleA)-1] = 0; + data1->Type = dataW->Type; + data1->DataFlow = dataW->DataFlow; + data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId; +} + +static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA; + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data; + BOOL ret; + + ret = DSPROPERTY_descWtoA(descW, &descA); + if (!ret) + return FALSE; + ret = ppd->Callback(&descA, ppd->Context); + HeapFree(GetProcessHeap(), 0, descA.Module); + HeapFree(GetProcessHeap(), 0, descA.Description); + return ret; +} + +static HRESULT DSPROPERTY_EnumerateA( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; + + if (!ppd || !ppd->Callback) + { + WARN("Invalid ppd %p\n", ppd); + return E_PROP_ID_UNSUPPORTED; + } + + data.Callback = DSPROPERTY_enumWtoA; + data.Context = ppd; + + return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned); +} + +static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1; + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data; + BOOL ret; + + DSPROPERTY_descWto1(descW, &desc1); + ret = ppd->Callback(&desc1, ppd->Context); + return ret; +} + +static HRESULT DSPROPERTY_Enumerate1( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; + + if (!ppd || !ppd->Callback) + { + WARN("Invalid ppd %p\n", ppd); + return E_PROP_ID_UNSUPPORTED; + } + + data.Callback = DSPROPERTY_enumWto1; + data.Context = ppd; + + return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned); +} + +static HRESULT DSPROPERTY_DescriptionA( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData; + HRESULT hr; + + if (pcbReturned) + *pcbReturned = sizeof(*ppd); + if (!pPropData) + return S_OK; + + data.DeviceId = ppd->DeviceId; + data.DataFlow = ppd->DataFlow; + hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); + if (FAILED(hr)) + return hr; + if (!DSPROPERTY_descWtoA(&data, ppd)) + hr = E_OUTOFMEMORY; + HeapFree(GetProcessHeap(), 0, data.Module); + HeapFree(GetProcessHeap(), 0, data.Interface); + return hr; +} + +static HRESULT DSPROPERTY_Description1( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData; + HRESULT hr; + + if (pcbReturned) + *pcbReturned = sizeof(*ppd); + if (!pPropData) + return S_OK; + + data.DeviceId = ppd->DeviceId; + data.DataFlow = ppd->DataFlow; + hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL); + if (FAILED(hr)) + return hr; + DSPROPERTY_descWto1(&data, ppd); + HeapFree(GetProcessHeap(), 0, data.Module); + HeapFree(GetProcessHeap(), 0, data.Interface); + return hr; +} + +static HRESULT WINAPI IKsPrivatePropertySetImpl_Get( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + LPVOID pInstanceData, + ULONG cbInstanceData, + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; + TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned); + + if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) { + switch (dwPropID) { + case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: + return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: + return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: + return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: + return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: + return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: + return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: + return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned); + case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: + return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned); + default: + FIXME("unsupported ID: %d\n",dwPropID); + break; + } + } else { + FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet)); + } + + if (pcbReturned) { + *pcbReturned = 0; + FIXME("*pcbReturned=%d\n", *pcbReturned); + } + + return E_PROP_ID_UNSUPPORTED; +} + +static HRESULT WINAPI IKsPrivatePropertySetImpl_Set( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + LPVOID pInstanceData, + ULONG cbInstanceData, + LPVOID pPropData, + ULONG cbPropData ) +{ + IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; + + FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData); + return E_PROP_ID_UNSUPPORTED; +} + +static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport( + LPKSPROPERTYSET iface, + REFGUID guidPropSet, + ULONG dwPropID, + PULONG pTypeSupport ) +{ + IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface; + TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport); + + if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) { + switch (dwPropID) { + case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: + *pTypeSupport = KSPROPERTY_SUPPORT_GET; + return S_OK; + default: + FIXME("unsupported ID: %d\n",dwPropID); + break; + } + } else { + FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet)); + } + + return E_PROP_ID_UNSUPPORTED; +} + +static const IKsPropertySetVtbl ikspvt = { + IKsPrivatePropertySetImpl_QueryInterface, + IKsPrivatePropertySetImpl_AddRef, + IKsPrivatePropertySetImpl_Release, + IKsPrivatePropertySetImpl_Get, + IKsPrivatePropertySetImpl_Set, + IKsPrivatePropertySetImpl_QuerySupport +}; + +HRESULT IKsPrivatePropertySetImpl_Create( + REFIID riid, + IKsPrivatePropertySetImpl **piks) +{ + IKsPrivatePropertySetImpl *iks; + TRACE("(%s, %p)\n", debugstr_guid(riid), piks); + + if (!IsEqualIID(riid, &IID_IUnknown) && + !IsEqualIID(riid, &IID_IKsPropertySet)) { + *piks = 0; + return E_NOINTERFACE; + } + + iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks)); + iks->ref = 1; + iks->lpVtbl = &ikspvt; + + *piks = iks; + return S_OK; +} diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c index cb91ed4fa34..88d67b60268 100644 --- a/dlls/dxdiagn/provider.c +++ b/dlls/dxdiagn/provider.c @@ -498,6 +498,7 @@ static HRESULT DXDiag_InitDXDiagDisplayContainer(IDxDiagContainer* pSubCont) hr = IDxDiagContainerImpl_AddChildContainer( pSubCont, szAdapterID, pDisplayAdapterSubCont ); if (FAILED( hr )) return hr; + disp_dev.cb = sizeof(disp_dev); if (EnumDisplayDevicesW( NULL, 0, &disp_dev, 0 )) { add_prop_str( pDisplayAdapterSubCont, szDeviceName, disp_dev.DeviceName ); diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index 8562d67f782..eddb1e4da64 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -262,6 +262,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, void **surface) { struct dxgi_surface *object; + HRESULT hr; FIXME("iface %p, desc %p, usage %#x, shared_resource %p, outer %p, surface %p partial stub!\n", iface, desc, usage, shared_resource, outer, surface); @@ -273,22 +274,16 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa return E_OUTOFMEMORY; } - object->vtbl = &dxgi_surface_vtbl; - object->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl; - object->refcount = 1; - - if (outer) - { - object->outer_unknown = outer; - *surface = &object->inner_unknown_vtbl; - } - else + hr = dxgi_surface_init(object, (IDXGIDevice *)iface, outer); + if (FAILED(hr)) { - object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl; - *surface = object; + WARN("Failed to initialize surface, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; } TRACE("Created IDXGISurface %p\n", object); + *surface = outer ? (void *)&object->inner_unknown_vtbl : object; return S_OK; } diff --git a/dlls/dxgi/dxgi.spec b/dlls/dxgi/dxgi.spec index d7f8aba61d9..853d8e28d13 100644 --- a/dlls/dxgi/dxgi.spec +++ b/dlls/dxgi/dxgi.spec @@ -1,3 +1,3 @@ @ stdcall CreateDXGIFactory(ptr ptr) -@ stdcall DXGID3D10CreateDevice(ptr ptr ptr long long ptr) +@ stdcall DXGID3D10CreateDevice(ptr ptr ptr long ptr ptr) @ stdcall DXGID3D10RegisterLayers(ptr long) diff --git a/dlls/dxgi/dxgi_main.c b/dlls/dxgi/dxgi_main.c index 489f9862320..312b3b79ebb 100644 --- a/dlls/dxgi/dxgi_main.c +++ b/dlls/dxgi/dxgi_main.c @@ -224,7 +224,7 @@ static HRESULT register_d3d10core_layers(HMODULE d3d10core) } HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter, - UINT flags, DWORD unknown0, void **device) + UINT flags, void *unknown0, void **device) { struct layer_get_size_args get_size_args; struct dxgi_device *dxgi_device; @@ -233,7 +233,7 @@ HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, I DWORD count; HRESULT hr; - TRACE("d3d10core %p, factory %p, adapter %p, flags %#x, unknown0 %#x, device %p\n", + TRACE("d3d10core %p, factory %p, adapter %p, flags %#x, unknown0 %p, device %p.\n", d3d10core, factory, adapter, flags, unknown0, device); hr = register_d3d10core_layers(d3d10core); diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 033168bbeb7..6151800855c 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -130,14 +130,15 @@ struct dxgi_swapchain }; /* IDXGISurface */ -extern const struct IDXGISurfaceVtbl dxgi_surface_vtbl DECLSPEC_HIDDEN; -extern const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl DECLSPEC_HIDDEN; struct dxgi_surface { const struct IDXGISurfaceVtbl *vtbl; const struct IUnknownVtbl *inner_unknown_vtbl; IUnknown *outer_unknown; LONG refcount; + IDXGIDevice *device; }; +HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, IUnknown *outer) DECLSPEC_HIDDEN; + #endif /* __WINE_DXGI_PRIVATE_H */ diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 5b8342774ec..eee6e55e590 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -117,10 +117,54 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput *iface, DXGI_OU static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *iface, DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *desc) { - FIXME("iface %p, format %s, flags %#x, mode_count %p, desc %p stub!\n", + struct dxgi_output *This = (struct dxgi_output *)iface; + WINED3DFORMAT wined3d_format; + IWineD3D *wined3d; + UINT i; + + TRACE("iface %p, format %s, flags %#x, mode_count %p, desc %p.\n", iface, debug_dxgi_format(format), flags, mode_count, desc); - return E_NOTIMPL; + wined3d = IWineDXGIFactory_get_wined3d(This->adapter->parent); + wined3d_format = wined3dformat_from_dxgi_format(format); + + if (!desc) + { + EnterCriticalSection(&dxgi_cs); + *mode_count = IWineD3D_GetAdapterModeCount(wined3d, This->adapter->ordinal, wined3d_format); + IWineD3D_Release(wined3d); + LeaveCriticalSection(&dxgi_cs); + + return S_OK; + } + + EnterCriticalSection(&dxgi_cs); + for (i = 0; i < *mode_count; ++i) + { + WINED3DDISPLAYMODE mode; + HRESULT hr; + + hr = IWineD3D_EnumAdapterModes(wined3d, This->adapter->ordinal, wined3d_format, i, &mode); + if (FAILED(hr)) + { + WARN("EnumAdapterModes failed, hr %#x.\n", hr); + IWineD3D_Release(wined3d); + LeaveCriticalSection(&dxgi_cs); + return hr; + } + + desc[i].Width = mode.Width; + desc[i].Height = mode.Height; + desc[i].RefreshRate.Numerator = mode.RefreshRate; + desc[i].RefreshRate.Denominator = 1; + desc[i].Format = format; + desc[i].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; /* FIXME */ + desc[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ + } + IWineD3D_Release(wined3d); + LeaveCriticalSection(&dxgi_cs); + + return S_OK; } static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput *iface, diff --git a/dlls/dxgi/surface.c b/dlls/dxgi/surface.c index bdbeaf333e2..6296c1a3802 100644 --- a/dlls/dxgi/surface.c +++ b/dlls/dxgi/surface.c @@ -72,6 +72,7 @@ static ULONG STDMETHODCALLTYPE dxgi_surface_inner_Release(IUnknown *iface) if (!refcount) { + IDXGIDevice_Release(This->device); HeapFree(GetProcessHeap(), 0, This); } @@ -129,18 +130,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface *iface static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface *iface, REFIID riid, void **parent) { - FIXME("iface %p, riid %s, parent %p stub!\n", iface, debugstr_guid(riid), parent); + struct dxgi_surface *This = (struct dxgi_surface *)iface; - return E_NOTIMPL; + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + return IDXGIDevice_QueryInterface(This->device, riid, parent); } /* IDXGIDeviceSubObject methods */ static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface *iface, REFIID riid, void **device) { - FIXME("iface %p, riid %s, device %p stub!\n", iface, debugstr_guid(riid), device); + struct dxgi_surface *This = (struct dxgi_surface *)iface; - return E_NOTIMPL; + TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device); + + return IDXGIDevice_QueryInterface(This->device, riid, device); } /* IDXGISurface methods */ @@ -165,7 +170,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface *iface) return E_NOTIMPL; } -const struct IDXGISurfaceVtbl dxgi_surface_vtbl = +static const struct IDXGISurfaceVtbl dxgi_surface_vtbl = { /* IUnknown methods */ dxgi_surface_QueryInterface, @@ -184,10 +189,22 @@ const struct IDXGISurfaceVtbl dxgi_surface_vtbl = dxgi_surface_Unmap, }; -const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl = +static const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl = { /* IUnknown methods */ dxgi_surface_inner_QueryInterface, dxgi_surface_inner_AddRef, dxgi_surface_inner_Release, }; + +HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, IUnknown *outer) +{ + surface->vtbl = &dxgi_surface_vtbl; + surface->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl; + surface->refcount = 1; + surface->outer_unknown = outer ? outer : (IUnknown *)&surface->inner_unknown_vtbl; + surface->device = device; + IDXGIDevice_AddRef(device); + + return S_OK; +} diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 32e87e6b742..d4ca50b28aa 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -22,7 +22,7 @@ #include "wine/test.h" HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, - IDXGIAdapter *adapter, UINT flags, DWORD arg5, void **device); + IDXGIAdapter *adapter, UINT flags, void *unknown0, void **device); static IDXGIDevice *create_device(HMODULE d3d10core) { @@ -39,7 +39,7 @@ static IDXGIDevice *create_device(HMODULE d3d10core) ok(SUCCEEDED(hr), "EnumAdapters failed, hr %#x\n", hr); if (FAILED(hr)) goto cleanup; - hr = DXGID3D10CreateDevice(d3d10core, factory, adapter, 0, 0, (void **)&device); + hr = DXGID3D10CreateDevice(d3d10core, factory, adapter, 0, NULL, (void **)&device); if (FAILED(hr)) { HMODULE d3d10ref; @@ -60,7 +60,7 @@ static IDXGIDevice *create_device(HMODULE d3d10core) ok(SUCCEEDED(hr), "CreateSoftwareAdapter failed, hr %#x\n", hr); if (FAILED(hr)) goto cleanup; - hr = DXGID3D10CreateDevice(d3d10core, factory, adapter, 0, 0, (void **)&device); + hr = DXGID3D10CreateDevice(d3d10core, factory, adapter, 0, NULL, (void **)&device); ok(SUCCEEDED(hr), "Failed to create a REF device, hr %#x\n", hr); if (FAILED(hr)) goto cleanup; } @@ -153,12 +153,29 @@ static void test_create_surface(IDXGIDevice *device) static void test_parents(IDXGIDevice *device) { + DXGI_SURFACE_DESC surface_desc; + IDXGISurface *surface; IDXGIFactory *factory; IDXGIAdapter *adapter; IDXGIOutput *output; IUnknown *parent; HRESULT hr; + surface_desc.Width = 512; + surface_desc.Height = 512; + surface_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + surface_desc.SampleDesc.Count = 1; + surface_desc.SampleDesc.Quality = 0; + + hr = IDXGIDevice_CreateSurface(device, &surface_desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface); + ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr); + + hr = IDXGISurface_GetParent(surface, &IID_IDXGIDevice, (void **)&parent); + IDXGISurface_Release(surface); + ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + ok(parent == (IUnknown *)device, "Got parent %p, expected %p.\n", parent, device); + IUnknown_Release(parent); + hr = IDXGIDevice_GetAdapter(device, &adapter); ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr); diff --git a/dlls/fusion/asmname.c b/dlls/fusion/asmname.c index 913674aa80e..3c014ea3244 100644 --- a/dlls/fusion/asmname.c +++ b/dlls/fusion/asmname.c @@ -471,6 +471,11 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam done: HeapFree(GetProcessHeap(), 0, save); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, name->displayname); + HeapFree(GetProcessHeap(), 0, name->name); + } return hr; } diff --git a/dlls/fusion/tests/asmenum.c b/dlls/fusion/tests/asmenum.c index 48f7b2a97b1..cb6ea3dfdeb 100644 --- a/dlls/fusion/tests/asmenum.c +++ b/dlls/fusion/tests/asmenum.c @@ -209,6 +209,8 @@ static void test_CreateAssemblyEnum(void) ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); ok(asmenum == (IAssemblyEnum *)0xdeadbeef, "Expected asmenum to be unchanged, got %p\n", asmenum); + + IAssemblyName_Release(asmname); } typedef struct _tagASMNAME diff --git a/dlls/gdi.exe16/Makefile.in b/dlls/gdi.exe16/Makefile.in new file mode 100644 index 00000000000..ab845a5ac0c --- /dev/null +++ b/dlls/gdi.exe16/Makefile.in @@ -0,0 +1,22 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = gdi.exe16 +IMPORTS = user32 advapi32 gdi32 kernel32 + +EXTRADLLFLAGS = -Wb,--subsystem,win16,--main-module,gdi32.dll,--heap,65520 +EXTRARCFLAGS = -O res16 + +C_SRCS = \ + bidi.c \ + env.c \ + gdi.c \ + metafile.c \ + printdrv.c + +RC_SRCS = version.rc + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/gdi32/bidi16.c b/dlls/gdi.exe16/bidi.c similarity index 100% rename from dlls/gdi32/bidi16.c rename to dlls/gdi.exe16/bidi.c diff --git a/dlls/gdi32/env.c b/dlls/gdi.exe16/env.c similarity index 100% rename from dlls/gdi32/env.c rename to dlls/gdi.exe16/env.c diff --git a/dlls/gdi32/gdi16.c b/dlls/gdi.exe16/gdi.c similarity index 100% rename from dlls/gdi32/gdi16.c rename to dlls/gdi.exe16/gdi.c diff --git a/dlls/gdi32/gdi.exe.spec b/dlls/gdi.exe16/gdi.exe16.spec similarity index 100% rename from dlls/gdi32/gdi.exe.spec rename to dlls/gdi.exe16/gdi.exe16.spec diff --git a/dlls/gdi32/metafile16.c b/dlls/gdi.exe16/metafile.c similarity index 100% rename from dlls/gdi32/metafile16.c rename to dlls/gdi.exe16/metafile.c diff --git a/dlls/gdi32/printdrv16.c b/dlls/gdi.exe16/printdrv.c similarity index 99% rename from dlls/gdi32/printdrv16.c rename to dlls/gdi.exe16/printdrv.c index f0b8cf07b35..aee0e65f158 100644 --- a/dlls/gdi32/printdrv16.c +++ b/dlls/gdi.exe16/printdrv.c @@ -48,7 +48,6 @@ #include "winreg.h" #include "wownt32.h" #include "wine/debug.h" -#include "gdi_private.h" WINE_DEFAULT_DEBUG_CHANNEL(print); diff --git a/dlls/gdi32/version16.rc b/dlls/gdi.exe16/version.rc similarity index 100% rename from dlls/gdi32/version16.rc rename to dlls/gdi.exe16/version.rc diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in index 45bdad58b24..16ea5b4a9bd 100644 --- a/dlls/gdi32/Makefile.in +++ b/dlls/gdi32/Makefile.in @@ -9,8 +9,6 @@ IMPORTS = advapi32 kernel32 ntdll EXTRAINCL = @FREETYPEINCL@ @FONTCONFIGINCL@ EXTRALIBS = @CARBONLIB@ -SPEC_SRCS16 = gdi.exe.spec - C_SRCS = \ bidi.c \ bitblt.c \ @@ -47,17 +45,9 @@ C_SRCS = \ path.c \ pen.c \ printdrv.c \ - printdrv16.c \ region.c -C_SRCS16 = \ - bidi16.c \ - env.c \ - gdi16.c \ - metafile16.c - RC_SRCS = version.rc -RC_SRCS16 = version16.rc EXTRASUBDIRS = \ enhmfdrv \ @@ -65,12 +55,4 @@ EXTRASUBDIRS = \ @MAKE_DLL_RULES@ -# Special rules for 16-bit resource and spec files - -gdi.exe.spec.o: gdi.exe.spec version16.res - $(WINEBUILD) $(WINEBUILDFLAGS) --dll -o $@ --heap 65520 --main-module $(MODULE) --res version16.res --export $(SRCDIR)/gdi.exe.spec - -version16.res: version16.rc - $(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc - @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/gdi32/bidi.c b/dlls/gdi32/bidi.c index 9ac5e1d283a..7d7f6bc5c44 100644 --- a/dlls/gdi32/bidi.c +++ b/dlls/gdi32/bidi.c @@ -46,6 +46,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winnls.h" #include "wine/debug.h" #include "gdi_private.h" diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 41c59c74711..635eeb8e33d 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -29,6 +29,7 @@ #include "winbase.h" #include "winreg.h" #include "ddrawgdi.h" +#include "wine/winbase16.h" #include "gdi_private.h" #include "wine/unicode.h" diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c index 25b33894ab4..95e55890b18 100644 --- a/dlls/gdi32/enhmetafile.c +++ b/dlls/gdi32/enhmetafile.c @@ -1073,16 +1073,16 @@ BOOL WINAPI PlayEnhMetaFileRecord( /* NB POINTS array doesn't start at pPolyPoly->apts it's actually pPolyPoly->aPolyCounts + pPolyPoly->nPolys */ - POINT16 *pts16 = (POINT16 *)(pPolyPoly->aPolyCounts + pPolyPoly->nPolys); - POINT *pts = HeapAlloc( GetProcessHeap(), 0, pPolyPoly->cpts * sizeof(POINT) ); + POINTS *pts = (POINTS *)(pPolyPoly->aPolyCounts + pPolyPoly->nPolys); + POINT *pt = HeapAlloc( GetProcessHeap(), 0, pPolyPoly->cpts * sizeof(POINT) ); DWORD i; for(i = 0; i < pPolyPoly->cpts; i++) { - pts[i].x = pts16[i].x; - pts[i].y = pts16[i].y; + pt[i].x = pts[i].x; + pt[i].y = pts[i].y; } - PolyPolygon(hdc, pts, (INT*)pPolyPoly->aPolyCounts, pPolyPoly->nPolys); - HeapFree( GetProcessHeap(), 0, pts ); + PolyPolygon(hdc, pt, (INT*)pPolyPoly->aPolyCounts, pPolyPoly->nPolys); + HeapFree( GetProcessHeap(), 0, pt ); break; } case EMR_POLYPOLYLINE16: @@ -1091,16 +1091,16 @@ BOOL WINAPI PlayEnhMetaFileRecord( /* NB POINTS array doesn't start at pPolyPoly->apts it's actually pPolyPoly->aPolyCounts + pPolyPoly->nPolys */ - POINT16 *pts16 = (POINT16 *)(pPolyPoly->aPolyCounts + pPolyPoly->nPolys); - POINT *pts = HeapAlloc( GetProcessHeap(), 0, pPolyPoly->cpts * sizeof(POINT) ); + POINTS *pts = (POINTS *)(pPolyPoly->aPolyCounts + pPolyPoly->nPolys); + POINT *pt = HeapAlloc( GetProcessHeap(), 0, pPolyPoly->cpts * sizeof(POINT) ); DWORD i; for(i = 0; i < pPolyPoly->cpts; i++) { - pts[i].x = pts16[i].x; - pts[i].y = pts16[i].y; + pt[i].x = pts[i].x; + pt[i].y = pts[i].y; } - PolyPolyline(hdc, pts, pPolyPoly->aPolyCounts, pPolyPoly->nPolys); - HeapFree( GetProcessHeap(), 0, pts ); + PolyPolyline(hdc, pt, pPolyPoly->aPolyCounts, pPolyPoly->nPolys); + HeapFree( GetProcessHeap(), 0, pt ); break; } diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index bc53493a719..115bb3935bd 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -25,6 +25,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winnls.h" #include "gdi_private.h" #include "enhmfdrv/enhmetafiledrv.h" #include "wine/debug.h" diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 7f8f6f6d0c0..eea53fd2b2f 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -2908,34 +2908,40 @@ BOOL WINAPI GetCharABCWidthsFloatA( HDC hdc, UINT first, UINT last, LPABCFLOAT a * RETURNS * Success: TRUE * Failure: FALSE - * - * BUGS - * Only works with TrueType fonts. It also doesn't return real - * floats but converted integers because it's implemented on - * top of GetCharABCWidthsW. */ BOOL WINAPI GetCharABCWidthsFloatW( HDC hdc, UINT first, UINT last, LPABCFLOAT abcf ) { - ABC *abc, *abc_base; - unsigned int i, size = sizeof(ABC) * (last - first + 1); - BOOL ret; + UINT i; + BOOL ret = FALSE; + DC *dc = get_dc_ptr( hdc ); + + TRACE("%p, %d, %d, %p\n", hdc, first, last, abcf); + + if (!dc) return FALSE; - TRACE("%p, %d, %d, %p - partial stub\n", hdc, first, last, abcf); + if (!abcf) + { + release_dc_ptr( dc ); + return FALSE; + } - abc = abc_base = HeapAlloc( GetProcessHeap(), 0, size ); - if (!abc) return FALSE; + if (dc->gdiFont) + ret = WineEngGetCharABCWidthsFloat( dc->gdiFont, first, last, abcf ); + else + FIXME("stub\n"); - ret = GetCharABCWidthsW( hdc, first, last, abc ); if (ret) { - for (i = first; i <= last; i++, abc++, abcf++) + /* convert device units to logical */ + for (i = first; i <= last; i++, abcf++) { - abcf->abcfA = abc->abcA; - abcf->abcfB = abc->abcB; - abcf->abcfC = abc->abcC; + abcf->abcfA = abcf->abcfA * dc->xformVport2World.eM11; + abcf->abcfB = abcf->abcfB * dc->xformVport2World.eM11; + abcf->abcfC = abcf->abcfC * dc->xformVport2World.eM11; } } - HeapFree( GetProcessHeap(), 0, abc_base ); + + release_dc_ptr( dc ); return ret; } diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 9b5f44fd7d2..a93cb60c8cf 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -84,6 +84,7 @@ #include "winreg.h" #include "wingdi.h" #include "gdi_private.h" +#include "wine/library.h" #include "wine/unicode.h" #include "wine/debug.h" #include "wine/list.h" @@ -5912,6 +5913,38 @@ BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar, } /************************************************************* + * WineEngGetCharABCWidthsFloat + * + */ +BOOL WineEngGetCharABCWidthsFloat(GdiFont *font, UINT first, UINT last, LPABCFLOAT buffer) +{ + static const MAT2 identity = {{0,1}, {0,0}, {0,0}, {0,1}}; + UINT c; + GLYPHMETRICS gm; + FT_UInt glyph_index; + GdiFont *linked_font; + + TRACE("%p, %d, %d, %p\n", font, first, last, buffer); + + GDI_CheckNotLock(); + EnterCriticalSection( &freetype_cs ); + + for (c = first; c <= last; c++) + { + get_glyph_index_linked(font, c, &linked_font, &glyph_index); + WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, + &gm, 0, NULL, &identity); + buffer[c - first].abcfA = FONT_GM(linked_font, glyph_index)->lsb; + buffer[c - first].abcfB = FONT_GM(linked_font, glyph_index)->bbx; + buffer[c - first].abcfC = FONT_GM(linked_font, glyph_index)->adv - + FONT_GM(linked_font, glyph_index)->lsb - + FONT_GM(linked_font, glyph_index)->bbx; + } + LeaveCriticalSection( &freetype_cs ); + return TRUE; +} + +/************************************************************* * WineEngGetCharABCWidthsI * */ @@ -6604,6 +6637,12 @@ BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar, return FALSE; } +BOOL WineEngGetCharABCWidthsFloat(GdiFont *font, UINT first, UINT last, LPABCFLOAT buffer) +{ + ERR("called but we don't have FreeType\n"); + return FALSE; +} + BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar, UINT count, LPWORD pgi, LPABC buffer) { diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index ebd95256367..96faf06e1c5 100644 --- a/dlls/gdi32/gdi32.spec +++ b/dlls/gdi32/gdi32.spec @@ -513,13 +513,10 @@ ################################################################ # Wine extensions: Win16 functions that are needed by other dlls # -@ stdcall CloseJob16(long) @ stdcall GetDCHook(long ptr) -@ stdcall OpenJob16(str str long) @ stdcall SelectVisRgn(long long) @ stdcall SetDCHook(long ptr long) @ stdcall SetHookFlags(long long) -@ stdcall WriteSpool16(long ptr long) ################################################################ # Wine internal extensions diff --git a/dlls/gdi32/gdi_main.c b/dlls/gdi32/gdi_main.c index 6734ed5df50..b757ac070b2 100644 --- a/dlls/gdi32/gdi_main.c +++ b/dlls/gdi32/gdi_main.c @@ -23,6 +23,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "wine/winbase16.h" #include "gdi_private.h" /*********************************************************************** diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 7b565c96587..d5f9112ecdc 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -22,7 +22,10 @@ #define __WINE_GDI_PRIVATE_H #include -#include "wine/wingdi16.h" +#include +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" /* Metafile defines */ #define META_EOF 0x0000 @@ -409,6 +412,8 @@ extern BOOL WineEngDestroyFontInstance(HFONT handle) DECLSPEC_HIDDEN; extern DWORD WineEngEnumFonts(LPLOGFONTW, FONTENUMPROCW, LPARAM) DECLSPEC_HIDDEN; extern BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar, LPABC buffer) DECLSPEC_HIDDEN; +extern BOOL WineEngGetCharABCWidthsFloat(GdiFont *font, UINT firstChar, + UINT lastChar, LPABCFLOAT buffer) DECLSPEC_HIDDEN; extern BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar, UINT count, LPWORD pgi, LPABC buffer) DECLSPEC_HIDDEN; extern BOOL WineEngGetCharWidth(GdiFont*, UINT, UINT, LPINT) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 6ba4a4c8cdb..245b1ccf68d 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -29,6 +29,7 @@ #include "winbase.h" #include "wingdi.h" #include "winreg.h" +#include "winnls.h" #include "winerror.h" #include "winternl.h" diff --git a/dlls/gdi32/metafile.c b/dlls/gdi32/metafile.c index 27ce7b5cbab..dae991f9de0 100644 --- a/dlls/gdi32/metafile.c +++ b/dlls/gdi32/metafile.c @@ -55,6 +55,7 @@ #include "winbase.h" #include "wingdi.h" #include "winreg.h" +#include "winnls.h" #include "winternl.h" #include "gdi_private.h" #include "wine/debug.h" @@ -137,10 +138,10 @@ static METAHEADER *MF_GetMetaHeader( HMETAFILE hmf ) /****************************************************************** * convert_points * - * Convert an array of POINT16 to an array of POINT. + * Convert an array of POINTS to an array of POINT. * Result must be freed by caller. */ -static POINT *convert_points( UINT count, POINT16 *pt16 ) +static POINT *convert_points( UINT count, const POINTS *pts ) { UINT i; POINT *ret = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*ret) ); @@ -148,8 +149,8 @@ static POINT *convert_points( UINT count, POINT16 *pt16 ) { for (i = 0; i < count; i++) { - ret[i].x = pt16[i].x; - ret[i].y = pt16[i].y; + ret[i].x = pts[i].x; + ret[i].y = pts[i].y; } } return ret; @@ -741,7 +742,7 @@ BOOL WINAPI PlayMetaFileRecord( HDC hdc, HANDLETABLE *ht, METARECORD *mr, UINT break; case META_POLYGON: - if ((pt = convert_points( mr->rdParm[0], (LPPOINT16)(mr->rdParm + 1)))) + if ((pt = convert_points( mr->rdParm[0], (POINTS *)(mr->rdParm + 1)))) { Polygon(hdc, pt, mr->rdParm[0]); HeapFree( GetProcessHeap(), 0, pt ); @@ -754,7 +755,7 @@ BOOL WINAPI PlayMetaFileRecord( HDC hdc, HANDLETABLE *ht, METARECORD *mr, UINT SHORT *counts = (SHORT *)(mr->rdParm + 1); for (i = total = 0; i < mr->rdParm[0]; i++) total += counts[i]; - pt = convert_points( total, (LPPOINT16)(counts + mr->rdParm[0]) ); + pt = convert_points( total, (POINTS *)(counts + mr->rdParm[0]) ); if (pt) { INT *cnt32 = HeapAlloc( GetProcessHeap(), 0, mr->rdParm[0] * sizeof(*cnt32) ); @@ -770,7 +771,7 @@ BOOL WINAPI PlayMetaFileRecord( HDC hdc, HANDLETABLE *ht, METARECORD *mr, UINT break; case META_POLYLINE: - if ((pt = convert_points( mr->rdParm[0], (LPPOINT16)(mr->rdParm + 1)))) + if ((pt = convert_points( mr->rdParm[0], (POINTS *)(mr->rdParm + 1)))) { Polyline( hdc, pt, mr->rdParm[0] ); HeapFree( GetProcessHeap(), 0, pt ); @@ -1430,7 +1431,7 @@ static BOOL MF_Play_MetaExtTextOut(HDC hdc, METARECORD *mr) { INT *dx = NULL; int i; - LPINT16 dxx; + SHORT *dxx; LPSTR sot; DWORD len; WORD s1; @@ -1439,7 +1440,7 @@ static BOOL MF_Play_MetaExtTextOut(HDC hdc, METARECORD *mr) s1 = mr->rdParm[2]; /* String length */ len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short) - + sizeof(UINT16) + (isrect ? sizeof(RECT16) : 0); + + sizeof(UINT16) + (isrect ? 4 * sizeof(SHORT) : 0); /* rec len without dx array */ sot = (LPSTR)&mr->rdParm[4]; /* start_of_text */ @@ -1449,7 +1450,7 @@ static BOOL MF_Play_MetaExtTextOut(HDC hdc, METARECORD *mr) rect.top = (SHORT)mr->rdParm[5]; rect.right = (SHORT)mr->rdParm[6]; rect.bottom = (SHORT)mr->rdParm[7]; - sot += sizeof(RECT16); /* there is a rectangle, so add offset */ + sot += 4 * sizeof(SHORT); /* there is a rectangle, so add offset */ } if (mr->rdSize == len / 2) @@ -1457,7 +1458,7 @@ static BOOL MF_Play_MetaExtTextOut(HDC hdc, METARECORD *mr) else if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2) { - dxx = (LPINT16)(sot+(((s1+1)>>1)*2)); + dxx = (SHORT *)(sot+(((s1+1)>>1)*2)); dx = HeapAlloc( GetProcessHeap(), 0, s1*sizeof(INT)); if (dx) for (i = 0; i < s1; i++) dx[i] = dxx[i]; } diff --git a/dlls/gdi32/mfdrv/graphics.c b/dlls/gdi32/mfdrv/graphics.c index 9b92f850907..e2cc6eb6674 100644 --- a/dlls/gdi32/mfdrv/graphics.c +++ b/dlls/gdi32/mfdrv/graphics.c @@ -18,9 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" #include "mfdrv/metafiledrv.h" #include "wine/debug.h" @@ -123,7 +127,7 @@ MFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) /****************************************************************** * MFDRV_MetaPoly - implements Polygon and Polyline */ -static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, LPPOINT16 pt, short count) +static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, POINTS *pt, short count) { BOOL ret; DWORD len; @@ -149,20 +153,20 @@ static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, LPPOINT16 pt, short count) BOOL CDECL MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count ) { - register int i; - LPPOINT16 pt16; - BOOL16 ret; + int i; + POINTS *pts; + BOOL ret; - pt16 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count ); - if(!pt16) return FALSE; + pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS)*count ); + if(!pts) return FALSE; for (i=count;i--;) { - pt16[i].x = pt[i].x; - pt16[i].y = pt[i].y; + pts[i].x = pt[i].x; + pts[i].y = pt[i].y; } - ret = MFDRV_MetaPoly(dev, META_POLYLINE, pt16, count); + ret = MFDRV_MetaPoly(dev, META_POLYLINE, pts, count); - HeapFree( GetProcessHeap(), 0, pt16 ); + HeapFree( GetProcessHeap(), 0, pts ); return ret; } @@ -173,20 +177,20 @@ MFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count ) BOOL CDECL MFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) { - register int i; - LPPOINT16 pt16; - BOOL16 ret; + int i; + POINTS *pts; + BOOL ret; - pt16 = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16)*count ); - if(!pt16) return FALSE; + pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS)*count ); + if(!pts) return FALSE; for (i=count;i--;) { - pt16[i].x = pt[i].x; - pt16[i].y = pt[i].y; + pts[i].x = pt[i].x; + pts[i].y = pt[i].y; } - ret = MFDRV_MetaPoly(dev, META_POLYGON, pt16, count); + ret = MFDRV_MetaPoly(dev, META_POLYGON, pts, count); - HeapFree( GetProcessHeap(), 0, pt16 ); + HeapFree( GetProcessHeap(), 0, pts ); return ret; } @@ -201,7 +205,7 @@ MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygon DWORD len; METARECORD *mr; unsigned int i,j; - LPPOINT16 pt16; + POINTS *pts; INT16 totalpoint16 = 0; INT16 * pointcounts; @@ -210,7 +214,7 @@ MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygon } /* allocate space for all points */ - pt16=HeapAlloc( GetProcessHeap(), 0, sizeof(POINT16) * totalpoint16 ); + pts=HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS) * totalpoint16 ); pointcounts = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16) * totalpoint16 ); /* copy point counts */ @@ -220,14 +224,14 @@ MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygon /* convert all points */ for (j = totalpoint16; j--;){ - pt16[j].x = pt[j].x; - pt16[j].y = pt[j].y; + pts[j].x = pt[j].x; + pts[j].y = pt[j].y; } - len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(POINT16); + len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(*pts); if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) { - HeapFree( GetProcessHeap(), 0, pt16 ); + HeapFree( GetProcessHeap(), 0, pts ); HeapFree( GetProcessHeap(), 0, pointcounts ); return FALSE; } @@ -236,10 +240,10 @@ MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygon mr->rdFunction = META_POLYPOLYGON; *(mr->rdParm) = polygons; memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16)); - memcpy(mr->rdParm + 1+polygons, pt16 , totalpoint16*sizeof(POINT16)); + memcpy(mr->rdParm + 1+polygons, pts , totalpoint16*sizeof(*pts)); ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); - HeapFree( GetProcessHeap(), 0, pt16 ); + HeapFree( GetProcessHeap(), 0, pts ); HeapFree( GetProcessHeap(), 0, pointcounts ); HeapFree( GetProcessHeap(), 0, mr); return ret; diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c index 4c88ac6d833..f515bcf88d7 100644 --- a/dlls/gdi32/mfdrv/init.c +++ b/dlls/gdi32/mfdrv/init.c @@ -23,6 +23,7 @@ #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "gdi_private.h" #include "mfdrv/metafiledrv.h" #include "wine/debug.h" diff --git a/dlls/gdi32/mfdrv/mapping.c b/dlls/gdi32/mfdrv/mapping.c index 998a7a12ece..f306cc66599 100644 --- a/dlls/gdi32/mfdrv/mapping.c +++ b/dlls/gdi32/mfdrv/mapping.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" #include "gdi_private.h" #include "mfdrv/metafiledrv.h" diff --git a/dlls/gdi32/mfdrv/objects.c b/dlls/gdi32/mfdrv/objects.c index e74cde83f4f..a7a442b39a5 100644 --- a/dlls/gdi32/mfdrv/objects.c +++ b/dlls/gdi32/mfdrv/objects.c @@ -27,6 +27,7 @@ #include "winbase.h" #include "wingdi.h" #include "wownt32.h" +#include "wine/wingdi16.h" #include "mfdrv/metafiledrv.h" #include "gdi_private.h" #include "wine/debug.h" diff --git a/dlls/gdi32/mfdrv/text.c b/dlls/gdi32/mfdrv/text.c index c3c182c67b5..3ec37033801 100644 --- a/dlls/gdi32/mfdrv/text.c +++ b/dlls/gdi32/mfdrv/text.c @@ -23,6 +23,7 @@ #include "windef.h" #include "winbase.h" +#include "wine/wingdi16.h" #include "mfdrv/metafiledrv.h" #include "wine/debug.h" diff --git a/dlls/gdi32/printdrv.c b/dlls/gdi32/printdrv.c index 18f9db7fc55..cc1e61fc451 100644 --- a/dlls/gdi32/printdrv.c +++ b/dlls/gdi32/printdrv.c @@ -26,6 +26,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winnls.h" #include "winspool.h" #include "winerror.h" #include "wine/debug.h" diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 5b70918aa07..73a6bd659ee 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -607,17 +607,73 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap, GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height, PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap) { - FIXME("(%f,%f,%f,%f,%i,%p,%p): stub\n", x, y, width, height, format, srcBitmap, dstBitmap); + BitmapData lockeddata_src, lockeddata_dst; + int i; + UINT row_size; + Rect area; + GpStatus stat; - return NotImplemented; + TRACE("(%f,%f,%f,%f,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap); + + if (!srcBitmap || !dstBitmap || srcBitmap->image.type != ImageTypeBitmap || + x < 0 || y < 0 || + x + width > srcBitmap->width || y + height > srcBitmap->height) + { + TRACE("<-- InvalidParameter\n"); + return InvalidParameter; + } + + if (format == PixelFormatDontCare) + format = srcBitmap->format; + + area.X = roundr(x); + area.Y = roundr(y); + area.Width = roundr(width); + area.Height = roundr(height); + + stat = GdipBitmapLockBits(srcBitmap, &area, ImageLockModeRead, format, + &lockeddata_src); + if (stat != Ok) return stat; + + stat = GdipCreateBitmapFromScan0(lockeddata_src.Width, lockeddata_src.Height, + 0, lockeddata_src.PixelFormat, NULL, dstBitmap); + if (stat == Ok) + { + stat = GdipBitmapLockBits(*dstBitmap, NULL, ImageLockModeWrite, + lockeddata_src.PixelFormat, &lockeddata_dst); + + if (stat == Ok) + { + /* copy the image data */ + row_size = (lockeddata_src.Width * PIXELFORMATBPP(lockeddata_src.PixelFormat) +7)/8; + for (i=0; iformat, &image->format, sizeof(GUID)); diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c index 197b68af4a8..eab9b8fa5db 100644 --- a/dlls/gdiplus/region.c +++ b/dlls/gdiplus/region.c @@ -249,6 +249,7 @@ GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, Combin if(mode == CombineModeReplace){ delete_element(®ion->node); memcpy(region, path_region, sizeof(GpRegion)); + GdipFree(path_region); return Ok; } @@ -295,6 +296,7 @@ GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, if(mode == CombineModeReplace){ delete_element(®ion->node); memcpy(region, rect_region, sizeof(GpRegion)); + GdipFree(rect_region); return Ok; } diff --git a/dlls/gdiplus/tests/brush.c b/dlls/gdiplus/tests/brush.c index cf9461189b8..0ee4dd485a2 100644 --- a/dlls/gdiplus/tests/brush.c +++ b/dlls/gdiplus/tests/brush.c @@ -641,6 +641,9 @@ static void test_linelinearblend(void) expectf(0.0, res_positions[0]); expectf(0.8, res_factors[1]); expectf(1.0, res_positions[1]); + + status = GdipDeleteBrush((GpBrush*)brush); + expect(Ok, status); } START_TEST(brush) diff --git a/dlls/gdiplus/tests/customlinecap.c b/dlls/gdiplus/tests/customlinecap.c index 78a8c704830..7aa8dc46ca7 100644 --- a/dlls/gdiplus/tests/customlinecap.c +++ b/dlls/gdiplus/tests/customlinecap.c @@ -59,8 +59,10 @@ static void test_constructor_destructor(void) stat = GdipDeleteCustomLineCap(custom); expect(Ok, stat); /* it's strange but native returns NotImplemented on stroke == NULL */ + custom = NULL; stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 10.0, &custom); todo_wine expect(NotImplemented, stat); + todo_wine ok(custom == NULL, "Expected a failure on creation\n"); GdipDeletePath(path2); GdipDeletePath(path); diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 6e257eb8008..5f4a92eb719 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -410,11 +410,14 @@ static void test_worldbounds(void) status = GdipGetPathWorldBounds(path, &bounds, matrix, NULL); expect(Ok, status); GdipDeletePath(path); + GdipDeleteMatrix(matrix); expectf(-209.6, bounds.X); expectf(-1274.8, bounds.Y); expectf(705.0, bounds.Width); expectf(945.0, bounds.Height); + + GdipDeletePen(pen); } static path_test_t pathpath_path[] = { diff --git a/dlls/gdiplus/tests/pathiterator.c b/dlls/gdiplus/tests/pathiterator.c index eddb24e89fd..3e1c287f326 100644 --- a/dlls/gdiplus/tests/pathiterator.c +++ b/dlls/gdiplus/tests/pathiterator.c @@ -36,8 +36,11 @@ static void test_constructor_destructor(void) /* NULL args */ stat = GdipCreatePathIter(NULL, NULL); expect(InvalidParameter, stat); + iter = NULL; stat = GdipCreatePathIter(&iter, NULL); expect(Ok, stat); + ok(iter != NULL, "Expected iterator to be created\n"); + GdipDeletePathIter(iter); stat = GdipCreatePathIter(NULL, path); expect(InvalidParameter, stat); stat = GdipDeletePathIter(NULL); diff --git a/dlls/hlink/tests/hlink.c b/dlls/hlink/tests/hlink.c index fc009986e39..1a7536fee93 100644 --- a/dlls/hlink/tests/hlink.c +++ b/dlls/hlink/tests/hlink.c @@ -1044,6 +1044,7 @@ static void test_HlinkGetSetMonikerReference(void) ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); ok(lstrcmpW(found_loc, one) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(one), wine_dbgstr_w(found_loc)); IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); /* set location => two */ hres = IHlink_SetMonikerReference(hlink, HLINKSETF_LOCATION, dummy2, two); @@ -1053,6 +1054,7 @@ static void test_HlinkGetSetMonikerReference(void) ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt); ok(lstrcmpW(found_loc, two) == 0, "Found location should've been %s, was: %s\n", wine_dbgstr_w(two), wine_dbgstr_w(found_loc)); IMoniker_Release(found_trgt); + CoTaskMemFree(found_loc); /* set target => dummy2 */ hres = IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, dummy2, one); diff --git a/dlls/imagehlp/integrity.c b/dlls/imagehlp/integrity.c index 6a13c53bb23..72bf1552eff 100644 --- a/dlls/imagehlp/integrity.c +++ b/dlls/imagehlp/integrity.c @@ -285,6 +285,88 @@ static BOOL IMAGEHLP_GetCertificateOffset( HANDLE handle, DWORD num, return TRUE; } +/*********************************************************************** + * IMAGEHLP_RecalculateChecksum (INTERNAL) + * + * Update the NT header checksum for the specified file. + */ +static BOOL IMAGEHLP_RecalculateChecksum(HANDLE handle) +{ + DWORD FileLength, count, HeaderSum, pe_offset, nt_hdr_size; + IMAGE_NT_HEADERS32 nt_hdr32; + IMAGE_NT_HEADERS64 nt_hdr64; + LPVOID BaseAddress; + HANDLE hMapping; + DWORD *CheckSum; + void *nt_hdr; + int ret; + BOOL r; + + TRACE("handle %p\n", handle); + + ret = IMAGEHLP_GetNTHeaders(handle, &pe_offset, &nt_hdr32, &nt_hdr64); + + if (ret == HDR_NT32) + { + CheckSum = &nt_hdr32.OptionalHeader.CheckSum; + + nt_hdr = &nt_hdr32; + nt_hdr_size = sizeof(IMAGE_NT_HEADERS32); + } + else if (ret == HDR_NT64) + { + CheckSum = &nt_hdr64.OptionalHeader.CheckSum; + + nt_hdr = &nt_hdr64; + nt_hdr_size = sizeof(IMAGE_NT_HEADERS64); + } + else + return FALSE; + + hMapping = CreateFileMappingW(handle, NULL, PAGE_READONLY, 0, 0, NULL); + + if (!hMapping) + return FALSE; + + BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + + if (!BaseAddress) + { + CloseHandle(hMapping); + return FALSE; + } + + FileLength = GetFileSize(handle, NULL); + + *CheckSum = 0; + CheckSumMappedFile(BaseAddress, FileLength, &HeaderSum, CheckSum); + + UnmapViewOfFile(BaseAddress); + CloseHandle(hMapping); + + if (*CheckSum) + { + /* write the header back again */ + count = SetFilePointer(handle, pe_offset, NULL, FILE_BEGIN); + + if (count == INVALID_SET_FILE_POINTER) + return FALSE; + + count = 0; + + r = WriteFile(handle, nt_hdr, nt_hdr_size, &count, NULL); + + if (!r) + return FALSE; + + if (count != nt_hdr_size) + return FALSE; + + return TRUE; + } + + return FALSE; +} /*********************************************************************** * ImageAddCertificate (IMAGEHLP.@) @@ -392,6 +474,9 @@ BOOL WINAPI ImageAddCertificate( if (!IMAGEHLP_SetSecurityDirOffset(FileHandle, sd_VirtualAddr, size)) return FALSE; + if (!IMAGEHLP_RecalculateChecksum(FileHandle)) + return FALSE; + return TRUE; } @@ -564,7 +649,84 @@ BOOL WINAPI ImageGetDigestStream( */ BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index) { - FIXME("(%p, %d): stub\n", FileHandle, Index); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD size = 0, count = 0, sd_VirtualAddr = 0, offset = 0; + DWORD data_size = 0, cert_size = 0, cert_size_padded = 0, ret = 0; + LPVOID cert_data; + BOOL r; + + TRACE("(%p, %d)\n", FileHandle, Index); + + r = ImageEnumerateCertificates(FileHandle, CERT_SECTION_TYPE_ANY, &count, NULL, 0); + + if ((!r) || (count == 0)) + return FALSE; + + if ((!IMAGEHLP_GetSecurityDirOffset(FileHandle, &sd_VirtualAddr, &size)) || + (!IMAGEHLP_GetCertificateOffset(FileHandle, Index, &offset, &cert_size))) + return FALSE; + + /* Ignore any padding we have, too */ + if (cert_size % 8) + cert_size_padded = cert_size + (8 - (cert_size % 8)); + else + cert_size_padded = cert_size; + + data_size = size - (offset - sd_VirtualAddr) - cert_size_padded; + + if (data_size == 0) + { + ret = SetFilePointer(FileHandle, sd_VirtualAddr, NULL, FILE_BEGIN); + + if (ret == INVALID_SET_FILE_POINTER) + return FALSE; + } + else + { + cert_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, data_size); + + if (!cert_data) + return FALSE; + + ret = SetFilePointer(FileHandle, offset + cert_size_padded, NULL, FILE_BEGIN); + + if (ret == INVALID_SET_FILE_POINTER) + goto error; + + /* Read any subsequent certificates */ + r = ReadFile(FileHandle, cert_data, data_size, &count, NULL); + + if ((!r) || (count != data_size)) + goto error; + + SetFilePointer(FileHandle, offset, NULL, FILE_BEGIN); + + /* Write them one index back */ + r = WriteFile(FileHandle, cert_data, data_size, &count, NULL); + + if ((!r) || (count != data_size)) + goto error; + + HeapFree(GetProcessHeap(), 0, cert_data); + } + + /* If security directory is at end of file, trim the file */ + if (GetFileSize(FileHandle, NULL) == sd_VirtualAddr + size) + SetEndOfFile(FileHandle); + + if (count == 1) + r = IMAGEHLP_SetSecurityDirOffset(FileHandle, 0, 0); + else + r = IMAGEHLP_SetSecurityDirOffset(FileHandle, sd_VirtualAddr, size - cert_size_padded); + + if (!r) + return FALSE; + + if (!IMAGEHLP_RecalculateChecksum(FileHandle)) + return FALSE; + + return TRUE; + +error: + HeapFree(GetProcessHeap(), 0, cert_data); + return FALSE; } diff --git a/dlls/imagehlp/modify.c b/dlls/imagehlp/modify.c index 02636bd2322..debccc00f88 100644 --- a/dlls/imagehlp/modify.c +++ b/dlls/imagehlp/modify.c @@ -89,11 +89,14 @@ PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile( LPVOID BaseAddress, DWORD FileLength, LPDWORD HeaderSum, LPDWORD CheckSum) { - PIMAGE_NT_HEADERS Header; + IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *) BaseAddress; + PIMAGE_NT_HEADERS32 Header32; + PIMAGE_NT_HEADERS64 Header64; + DWORD *ChecksumFile; DWORD CalcSum; DWORD HdrSum; - FIXME("(%p, %d, %p, %p): stub\n", + TRACE("(%p, %d, %p, %p)\n", BaseAddress, FileLength, HeaderSum, CheckSum ); @@ -101,8 +104,25 @@ PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile( BaseAddress, (FileLength + 1) / sizeof(WORD)); - Header = RtlImageNtHeader(BaseAddress); - HdrSum = Header->OptionalHeader.CheckSum; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) + return NULL; + + Header32 = (IMAGE_NT_HEADERS32 *)((char *)dos + dos->e_lfanew); + + if (Header32->Signature != IMAGE_NT_SIGNATURE) + return NULL; + + if (Header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) + ChecksumFile = &Header32->OptionalHeader.CheckSum; + else if (Header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) + { + Header64 = (IMAGE_NT_HEADERS64 *)Header32; + ChecksumFile = &Header64->OptionalHeader.CheckSum; + } + else + return NULL; + + HdrSum = *ChecksumFile; /* Subtract image checksum from calculated checksum. */ /* fix low word of checksum */ @@ -129,9 +149,9 @@ PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile( CalcSum += FileLength; *CheckSum = CalcSum; - *HeaderSum = Header->OptionalHeader.CheckSum; + *HeaderSum = *ChecksumFile; - return Header; + return (PIMAGE_NT_HEADERS) Header32; } /*********************************************************************** diff --git a/dlls/imagehlp/tests/integrity.c b/dlls/imagehlp/tests/integrity.c index e89167c4fd4..a551d1f0a3e 100644 --- a/dlls/imagehlp/tests/integrity.c +++ b/dlls/imagehlp/tests/integrity.c @@ -31,6 +31,7 @@ static HMODULE hImageHlp; static char test_dll_path[MAX_PATH]; static BOOL (WINAPI *pImageAddCertificate)(HANDLE, LPWIN_CERTIFICATE, PDWORD); +static BOOL (WINAPI *pImageEnumerateCertificates)(HANDLE, WORD, PDWORD, PDWORD, DWORD); static BOOL (WINAPI *pImageGetCertificateData)(HANDLE, DWORD, LPWIN_CERTIFICATE, PDWORD); static BOOL (WINAPI *pImageGetCertificateHeader)(HANDLE, DWORD, LPWIN_CERTIFICATE); static BOOL (WINAPI *pImageRemoveCertificate)(HANDLE, DWORD); @@ -87,6 +88,8 @@ static char test_cert_data[] = ,0x46,0xCA,0xEB,0xEA,0x67,0x89,0x49,0x7C,0x43,0xA2,0x52,0xD9,0x41,0xCC,0x65 ,0xED,0x2D,0xA1,0x00,0x31,0x00}; +static char test_cert_data_2[] = {0xDE,0xAD,0xBE,0xEF,0x01,0x02,0x03}; + static BOOL copy_dll_file(void) { char sys_dir[MAX_PATH+15]; @@ -116,7 +119,23 @@ static BOOL copy_dll_file(void) return TRUE; } -static void test_add_certificate(void) +static DWORD get_file_size(void) +{ + HANDLE file; + DWORD filesize = 0; + + file = CreateFileA(test_dll_path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) + return 0; + + filesize = GetFileSize(file, NULL); + CloseHandle(file); + + return filesize; +} + +static void test_add_certificate(char *cert_data, int len) { HANDLE hFile; LPWIN_CERTIFICATE cert; @@ -131,7 +150,7 @@ static void test_add_certificate(void) return; } - cert_len = sizeof(WIN_CERTIFICATE) + sizeof(test_cert_data); + cert_len = sizeof(WIN_CERTIFICATE) + len; cert = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cert_len); if (!cert) @@ -144,7 +163,7 @@ static void test_add_certificate(void) cert->dwLength = cert_len; cert->wRevision = WIN_CERT_REVISION_1_0; cert->wCertificateType = WIN_CERT_TYPE_PKCS_SIGNED_DATA; - CopyMemory(cert->bCertificate, test_cert_data, sizeof(test_cert_data)); + CopyMemory(cert->bCertificate, cert_data, len); ok(pImageAddCertificate(hFile, cert, &index), "Unable to add certificate to image, error %x\n", GetLastError()); @@ -152,7 +171,7 @@ static void test_add_certificate(void) CloseHandle(hFile); } -static void test_get_certificate(void) +static void test_get_certificate(char *cert_data, int index) { HANDLE hFile; LPWIN_CERTIFICATE cert; @@ -167,7 +186,7 @@ static void test_get_certificate(void) return; } - ret = pImageGetCertificateData(hFile, 0, NULL, &cert_len); + ret = pImageGetCertificateData(hFile, index, NULL, &cert_len); err = GetLastError(); ok ((ret == FALSE) && (err == ERROR_INSUFFICIENT_BUFFER), "ImageGetCertificateData gave unexpected result; ret=%d / err=%x\n", ret, err); @@ -181,17 +200,17 @@ static void test_get_certificate(void) return; } - ok(ret = pImageGetCertificateData(hFile, 0, cert, &cert_len), "Unable to retrieve certificate; err=%x\n", GetLastError()); - ok(memcmp(cert->bCertificate, test_cert_data, cert_len - sizeof(WIN_CERTIFICATE)) == 0, "Certificate retrieved did not match original\n"); + ok(ret = pImageGetCertificateData(hFile, index, cert, &cert_len), "Unable to retrieve certificate; err=%x\n", GetLastError()); + ok(memcmp(cert->bCertificate, cert_data, cert_len - sizeof(WIN_CERTIFICATE)) == 0, "Certificate retrieved did not match original\n"); HeapFree(GetProcessHeap(), 0, cert); CloseHandle(hFile); } -static void test_remove_certificate(void) +static void test_remove_certificate(int index) { + DWORD orig_count = 0, count = 0; HANDLE hFile; - WIN_CERTIFICATE cert; hFile = CreateFileA(test_dll_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -201,16 +220,21 @@ static void test_remove_certificate(void) return; } - todo_wine ok (pImageRemoveCertificate(hFile, 0), "Unable to remove certificate from file; err=%x\n", GetLastError()); + ok (pImageEnumerateCertificates(hFile, CERT_SECTION_TYPE_ANY, &orig_count, NULL, 0), "Unable to enumerate certificates in file; err=%x\n", GetLastError()); + + ok (pImageRemoveCertificate(hFile, index), "Unable to remove certificate from file; err=%x\n", GetLastError()); /* Test to see if the certificate has actually been removed */ - todo_wine ok(pImageGetCertificateHeader(hFile, 0, &cert) == FALSE, "Certificate header retrieval succeeded when it should have failed\n"); + pImageEnumerateCertificates(hFile, CERT_SECTION_TYPE_ANY, &count, NULL, 0); + ok (count == orig_count - 1, "Certificate count mismatch; orig=%d new=%d\n", orig_count, count); CloseHandle(hFile); } START_TEST(integrity) { + DWORD file_size, file_size_orig; + hImageHlp = LoadLibraryA("imagehlp.dll"); if (!hImageHlp) @@ -225,14 +249,36 @@ START_TEST(integrity) return; } + file_size_orig = get_file_size(); + pImageAddCertificate = (void *) GetProcAddress(hImageHlp, "ImageAddCertificate"); + pImageEnumerateCertificates = (void *) GetProcAddress(hImageHlp, "ImageEnumerateCertificates"); pImageGetCertificateData = (void *) GetProcAddress(hImageHlp, "ImageGetCertificateData"); pImageGetCertificateHeader = (void *) GetProcAddress(hImageHlp, "ImageGetCertificateHeader"); pImageRemoveCertificate = (void *) GetProcAddress(hImageHlp, "ImageRemoveCertificate"); - test_add_certificate(); - test_get_certificate(); - test_remove_certificate(); + test_add_certificate(test_cert_data, sizeof(test_cert_data)); + test_get_certificate(test_cert_data, 0); + test_remove_certificate(0); + + file_size = get_file_size(); + ok(file_size == file_size_orig, "File size different after add and remove (old: %d; new: %d)\n", file_size_orig, file_size); + + /* Try adding multiple certificates */ + test_add_certificate(test_cert_data, sizeof(test_cert_data)); + test_add_certificate(test_cert_data_2, sizeof(test_cert_data_2)); + + test_get_certificate(test_cert_data, 0); + test_get_certificate(test_cert_data_2, 1); + + /* Remove the first one and verify the second certificate is intact */ + test_remove_certificate(0); + test_get_certificate(test_cert_data_2, 0); + + test_remove_certificate(0); + + file_size = get_file_size(); + ok(file_size == file_size_orig, "File size different after add and remove (old: %d; new: %d)\n", file_size_orig, file_size); FreeLibrary(hImageHlp); DeleteFile(test_dll_path); diff --git a/dlls/inetcomm/mimeole.c b/dlls/inetcomm/mimeole.c index 871ffa502af..992949a44ef 100644 --- a/dlls/inetcomm/mimeole.c +++ b/dlls/inetcomm/mimeole.c @@ -1610,6 +1610,7 @@ static HRESULT create_body_offset_list(IStream *stm, const char *boundary, struc } while(1); end: + HeapFree(GetProcessHeap(), 0, nl_boundary); HeapFree(GetProcessHeap(), 0, buf); return hr; } diff --git a/dlls/inetmib1/main.c b/dlls/inetmib1/main.c index 1e567109f83..9aef4d5c5dc 100644 --- a/dlls/inetmib1/main.c +++ b/dlls/inetmib1/main.c @@ -32,10 +32,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(inetmib1); /** * Utility functions */ -static void copyInt(AsnAny *value, void *src) +static DWORD copyInt(AsnAny *value, void *src) { value->asnType = ASN_INTEGER; value->asnValue.number = *(DWORD *)src; + return SNMP_ERRORSTATUS_NOERROR; } static void setStringValue(AsnAny *value, BYTE type, DWORD len, BYTE *str) @@ -45,18 +46,11 @@ static void setStringValue(AsnAny *value, BYTE type, DWORD len, BYTE *str) strValue.asnType = type; strValue.asnValue.string.stream = str; strValue.asnValue.string.length = len; - strValue.asnValue.string.dynamic = TRUE; + strValue.asnValue.string.dynamic = FALSE; SnmpUtilAsnAnyCpy(value, &strValue); } -static void copyLengthPrecededString(AsnAny *value, void *src) -{ - DWORD len = *(DWORD *)src; - - setStringValue(value, ASN_OCTETSTRING, len, (BYTE *)src + sizeof(DWORD)); -} - -typedef void (*copyValueFunc)(AsnAny *value, void *src); +typedef DWORD (*copyValueFunc)(AsnAny *value, void *src); struct structToAsnValue { @@ -75,13 +69,13 @@ static AsnInteger32 mapStructEntryToValue(struct structToAsnValue *map, return SNMP_ERRORSTATUS_NOSUCHNAME; if (!map[id].copy) return SNMP_ERRORSTATUS_NOSUCHNAME; - map[id].copy(&pVarBind->value, (BYTE *)record + map[id].offset); - return SNMP_ERRORSTATUS_NOERROR; + return map[id].copy(&pVarBind->value, (BYTE *)record + map[id].offset); } -static void copyIpAddr(AsnAny *value, void *src) +static DWORD copyIpAddr(AsnAny *value, void *src) { setStringValue(value, ASN_IPADDRESS, sizeof(DWORD), src); + return SNMP_ERRORSTATUS_NOERROR; } static UINT mib2[] = { 1,3,6,1,2,1 }; @@ -168,7 +162,7 @@ static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind, return ret; } -static void copyOperStatus(AsnAny *value, void *src) +static DWORD copyOperStatus(AsnAny *value, void *src) { value->asnType = ASN_INTEGER; /* The IPHlpApi definition of operational status differs from the MIB2 one, @@ -186,6 +180,7 @@ static void copyOperStatus(AsnAny *value, void *src) default: value->asnValue.number = MIB_IF_ADMIN_STATUS_DOWN; }; + return SNMP_ERRORSTATUS_NOERROR; } /* Given an OID and a base OID that it must begin with, finds the item and @@ -550,13 +545,46 @@ static INT setOidWithItemAndInteger(AsnObjectIdentifier *dst, return ret; } +static DWORD copyIfRowDescr(AsnAny *value, void *src) +{ + PMIB_IFROW row = (PMIB_IFROW)((BYTE *)src - + FIELD_OFFSET(MIB_IFROW, dwDescrLen)); + DWORD ret; + + if (row->dwDescrLen) + { + setStringValue(value, ASN_OCTETSTRING, row->dwDescrLen, row->bDescr); + ret = SNMP_ERRORSTATUS_NOERROR; + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + return ret; +} + +static DWORD copyIfRowPhysAddr(AsnAny *value, void *src) +{ + PMIB_IFROW row = (PMIB_IFROW)((BYTE *)src - + FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen)); + DWORD ret; + + if (row->dwPhysAddrLen) + { + setStringValue(value, ASN_OCTETSTRING, row->dwPhysAddrLen, + row->bPhysAddr); + ret = SNMP_ERRORSTATUS_NOERROR; + } + else + ret = SNMP_ERRORSTATUS_NOSUCHNAME; + return ret; +} + static struct structToAsnValue mib2IfEntryMap[] = { { FIELD_OFFSET(MIB_IFROW, dwIndex), copyInt }, - { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyLengthPrecededString }, + { FIELD_OFFSET(MIB_IFROW, dwDescrLen), copyIfRowDescr }, { FIELD_OFFSET(MIB_IFROW, dwType), copyInt }, { FIELD_OFFSET(MIB_IFROW, dwMtu), copyInt }, { FIELD_OFFSET(MIB_IFROW, dwSpeed), copyInt }, - { FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen), copyLengthPrecededString }, + { FIELD_OFFSET(MIB_IFROW, dwPhysAddrLen), copyIfRowPhysAddr }, { FIELD_OFFSET(MIB_IFROW, dwAdminStatus), copyInt }, { FIELD_OFFSET(MIB_IFROW, dwOperStatus), copyOperStatus }, { FIELD_OFFSET(MIB_IFROW, dwLastChange), copyInt }, @@ -883,9 +911,18 @@ static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind, static UINT mib2IpNet[] = { 1,3,6,1,2,1,4,22,1 }; static PMIB_IPNETTABLE ipNetTable; +static DWORD copyIpNetPhysAddr(AsnAny *value, void *src) +{ + PMIB_IPNETROW row = (PMIB_IPNETROW)((BYTE *)src - FIELD_OFFSET(MIB_IPNETROW, + dwPhysAddrLen)); + + setStringValue(value, ASN_OCTETSTRING, row->dwPhysAddrLen, row->bPhysAddr); + return SNMP_ERRORSTATUS_NOERROR; +} + static struct structToAsnValue mib2IpNetMap[] = { { FIELD_OFFSET(MIB_IPNETROW, dwIndex), copyInt }, - { FIELD_OFFSET(MIB_IPNETROW, dwPhysAddrLen), copyLengthPrecededString }, + { FIELD_OFFSET(MIB_IPNETROW, dwPhysAddrLen), copyIpNetPhysAddr }, { FIELD_OFFSET(MIB_IPNETROW, dwAddr), copyIpAddr }, { FIELD_OFFSET(MIB_IPNETROW, dwType), copyInt }, }; diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c index ca965fb0a5b..d8ee1011784 100644 --- a/dlls/iphlpapi/icmp.c +++ b/dlls/iphlpapi/icmp.c @@ -99,6 +99,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(icmp); +WINE_DECLARE_DEBUG_CHANNEL(winediag); typedef struct { @@ -153,7 +154,7 @@ HANDLE WINAPI IcmpCreateFile(VOID) int sid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); if (sid < 0) { - MESSAGE("WARNING: Trying to use ICMP (network ping) will fail unless running as root\n"); + ERR_(winediag)("Failed to use ICMP (network ping), this requires special permissions.\n"); SetLastError(ERROR_ACCESS_DENIED); return INVALID_HANDLE_VALUE; } diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 15ef90552af..9a89431ac01 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1396,7 +1396,7 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, TRACE("\n"); - hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval); + hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 346f8e0e002..4f4a87f960b 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -555,20 +555,6 @@ static const builtin_info_t Function_info = { NULL }; -static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) -{ - FIXME("\n"); - return E_NOTIMPL; -} - -static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) -{ - FIXME("\n"); - return E_NOTIMPL; -} - static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags, BOOL funcprot, DispatchEx *prototype, FunctionInstance **ret) { @@ -675,6 +661,131 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc return S_OK; } +static HRESULT construct_function(script_ctx_t *ctx, DISPPARAMS *dp, jsexcept_t *ei, IDispatch **ret) +{ + function_expression_t *expr; + WCHAR *str = NULL, *ptr; + DWORD argc, len = 0, l; + parser_ctx_t *parser; + DispatchEx *function; + BSTR *params = NULL; + int i=0, j=0; + HRESULT hres = S_OK; + + static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('}; + static const WCHAR function_beginW[] = {')',' ','{','\n'}; + static const WCHAR function_endW[] = {'\n','}',0}; + + argc = arg_cnt(dp); + if(argc) { + params = heap_alloc(argc*sizeof(BSTR)); + if(!params) + return E_OUTOFMEMORY; + + if(argc > 2) + len = (argc-2)*2; /* separating commas */ + for(i=0; i < argc; i++) { + hres = to_string(ctx, get_arg(dp,i), ei, params+i); + if(FAILED(hres)) + break; + len += SysStringLen(params[i]); + } + } + + if(SUCCEEDED(hres)) { + len += (sizeof(function_anonymousW) + sizeof(function_beginW) + sizeof(function_endW)) / sizeof(WCHAR); + str = heap_alloc(len*sizeof(WCHAR)); + if(str) { + memcpy(str, function_anonymousW, sizeof(function_anonymousW)); + ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR); + if(argc > 1) { + while(1) { + l = SysStringLen(params[j]); + memcpy(ptr, params[j], l*sizeof(WCHAR)); + ptr += l; + if(++j == argc-1) + break; + *ptr++ = ','; + *ptr++ = ' '; + } + } + memcpy(ptr, function_beginW, sizeof(function_beginW)); + ptr += sizeof(function_beginW)/sizeof(WCHAR); + if(argc) { + l = SysStringLen(params[argc-1]); + memcpy(ptr, params[argc-1], l*sizeof(WCHAR)); + ptr += l; + } + memcpy(ptr, function_endW, sizeof(function_endW)); + + TRACE("%s\n", debugstr_w(str)); + }else { + hres = E_OUTOFMEMORY; + } + } + + while(--i >= 0) + SysFreeString(params[i]); + heap_free(params); + if(FAILED(hres)) + return hres; + + hres = script_parse(ctx, str, NULL, &parser); + heap_free(str); + if(FAILED(hres)) + return hres; + + if(!parser->source || !parser->source->functions || parser->source->functions->next || parser->source->variables) { + ERR("Invalid parser result!\n"); + parser_release(parser); + return E_UNEXPECTED; + } + expr = parser->source->functions->expr; + + hres = create_source_function(parser, expr->parameter_list, expr->source_elements, NULL, expr->src_str, + expr->src_len, &function); + parser_release(parser); + if(FAILED(hres)) + return hres; + + *ret = (IDispatch*)_IDispatchEx_(function); + return S_OK; +} + +static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + HRESULT hres; + + TRACE("\n"); + + switch(flags) { + case DISPATCH_CONSTRUCT: { + IDispatch *ret; + + hres = construct_function(ctx, dp, ei, &ret); + if(FAILED(hres)) + return hres; + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = ret; + break; + } + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; +} + +static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype) { FunctionInstance *prot, *constr; diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c index bcc16654f7d..ff9807b5576 100644 --- a/dlls/jscript/regexp.c +++ b/dlls/jscript/regexp.c @@ -3301,6 +3301,13 @@ static inline RegExpInstance *regexp_from_vdisp(vdisp_t *vdisp) return (RegExpInstance*)vdisp->u.jsdisp; } +static void set_last_index(RegExpInstance *This, DWORD last_index) +{ + This->last_index = last_index; + VariantClear(&This->last_index_var); + num_set_val(&This->last_index_var, last_index); +} + static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, const WCHAR *str, DWORD len, const WCHAR **cp, match_result_t **parens, DWORD *parens_size, DWORD *parens_cnt, match_result_t *ret) { @@ -3363,6 +3370,7 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, c *cp = result->cp; ret->str = result->cp-matchlen; ret->len = matchlen; + set_last_index(regexp, result->cp-str); return S_OK; } @@ -3437,13 +3445,6 @@ HRESULT regexp_match(script_ctx_t *ctx, DispatchEx *dispex, const WCHAR *str, DW return S_OK; } -static void set_last_index(RegExpInstance *This, DWORD last_index) -{ - This->last_index = last_index; - VariantClear(&This->last_index_var); - num_set_val(&This->last_index_var, last_index); -} - static HRESULT RegExp_source(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -3657,7 +3658,6 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexce } if(hres == S_OK) { - set_last_index(regexp, cp-string); *ret = VARIANT_TRUE; }else { set_last_index(regexp, 0); diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index 97c807f6afc..95ad7737edb 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -1129,6 +1129,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP match_result_t *match_result = NULL; DWORD length, match_cnt, i, match_len = 0; const WCHAR *str, *ptr, *ptr2; + BOOL use_regexp = FALSE; VARIANT *arg, var; DispatchEx *array; BSTR val_str, match_str = NULL; @@ -1153,6 +1154,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP regexp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg)); if(regexp) { if(is_class(regexp, JSCLASS_REGEXP)) { + use_regexp = TRUE; hres = regexp_match(ctx, regexp, str, length, TRUE, &match_result, &match_cnt); jsdisp_release(regexp); if(FAILED(hres)) { @@ -1183,7 +1185,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP if(SUCCEEDED(hres)) { ptr = str; for(i=0;; i++) { - if(match_result) { + if(use_regexp) { if(i == match_cnt) break; ptr2 = match_result[i].str; @@ -1209,7 +1211,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP if(FAILED(hres)) break; - if(match_result) + if(use_regexp) ptr = match_result[i].str + match_result[i].len; else if(match_str) ptr = ptr2 + match_len; @@ -1218,7 +1220,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP } } - if(SUCCEEDED(hres) && (match_str || match_result)) { + if(SUCCEEDED(hres) && (match_str || use_regexp)) { DWORD len = (str+length) - ptr; if(len || match_str) { diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 80bdf88b983..7ad2984624b 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -1431,6 +1431,51 @@ callTest3.apply(null); tmp = Number.prototype.toString.call(3); ok(tmp === "3", "Number.prototype.toString.call(3) = " + tmp); +var func = new Function("return 3;"); + +tmp = func(); +ok(tmp === 3, "func() = " + tmp); +ok(func.call() === 3, "func.call() = " + tmp); +ok(func.length === 0, "func.length = " + func.length); +tmp = func.toString(); +ok(tmp === "function anonymous() {\nreturn 3;\n}", "func.toString() = " + tmp); + +func = new Function("x", "return x+2;"); +tmp = func(1); +ok(tmp === 3, "func(1) = " + tmp); +tmp = func.toString(); +ok(tmp === "function anonymous(x) {\nreturn x+2;\n}", "func.toString() = " + tmp); + +tmp = (new Function("x ", "return x+2;")).toString(); +ok(tmp === "function anonymous(x ) {\nreturn x+2;\n}", "func.toString() = " + tmp); + +func = new Function("x", "y", "return x+y"); +tmp = func(1,3); +ok(tmp === 4, "func(1,3) = " + tmp); +tmp = func.toString(); +ok(tmp === "function anonymous(x, y) {\nreturn x+y\n}", "func.toString() = " + tmp); + +func = new Function(" x, \ty", "\tz", "return x+y+z;"); +tmp = func(1,3,2); +ok(tmp === 6, "func(1,3,2) = " + tmp); +ok(func.length === 3, "func.length = " + func.length); +tmp = func.toString(); +ok(tmp === "function anonymous( x, \ty, \tz) {\nreturn x+y+z;\n}", "func.toString() = " + tmp); + +func = new Function(); +tmp = func(); +ok(tmp === undefined, "func() = " + tmp); +tmp = func.toString(); +ok(tmp == "function anonymous() {\n\n}", "func.toString() = " + tmp); + +func = (function() { + var tmp = 3; + return new Function("return tmp;"); + })(); +tmp = 2; +tmp = func(); +ok(tmp === 2, "func() = " + tmp); + var date = new Date(); date = new Date(100); diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 1359e05eaea..b13091fa476 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -863,6 +863,13 @@ ok(("1" in obj) === false, "1 is in obj"); obj = [1,2,3]; ok((1 in obj) === true, "1 is not in obj"); +obj = new Object(); +try { + obj.prop["test"]; + ok(false, "expected exception"); +}catch(e) {} +ok(!("prop" in obj), "prop in obj"); + ok(isNaN(NaN) === true, "isNaN(NaN) !== true"); ok(isNaN(0.5) === false, "isNaN(0.5) !== false"); ok(isNaN(Infinity) === false, "isNaN(Infinity) !== false"); diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js index 9a14a934dd8..7f5f907b068 100644 --- a/dlls/jscript/tests/regexp.js +++ b/dlls/jscript/tests/regexp.js @@ -96,10 +96,11 @@ ok(m[1] === "test", "m[1] = " + m[1]); b = /a*/.test(); ok(b === true, "/a*/.test() returned " + b); -m = "abcabc".match(/ca/); +m = "abcabc".match(re = /ca/); ok(typeof(m) === "object", "typeof m is not object"); ok(m.length === 1, "m.length is not 1"); ok(m["0"] === "ca", "m[0] is not \"ca\""); +ok(re.lastIndex === 4, "re.lastIndex = " + re.lastIndex); m = "abcabc".match(/ab/); ok(typeof(m) === "object", "typeof m is not object"); @@ -165,8 +166,9 @@ ok(m["0"] === "ab", "m[0] is not \"ab\""); m = "abcabc".match(); ok(m === null, "m is not null"); -r = "- [test] -".replace(/\[([^\[]+)\]/g, "success"); +r = "- [test] -".replace(re = /\[([^\[]+)\]/g, "success"); ok(r === "- success -", "r = " + r + " expected '- success -'"); +ok(re.lastIndex === 8, "re.lastIndex = " + re.lastIndex); r = "[test] [test]".replace(/\[([^\[]+)\]/g, "aa"); ok(r === "aa aa", "r = " + r + "aa aa"); @@ -285,6 +287,41 @@ ok(r.length === 2, "r.length = " + r.length); ok(r[0] === "1", "r[0] = " + r[0]); ok(r[1] === "2", "r[1] = " + r[1]); +re = /,+/; +r = "1,,2,".split(re); +ok(r.length === 2, "r.length = " + r.length); +ok(r[0] === "1", "r[0] = " + r[0]); +ok(r[1] === "2", "r[1] = " + r[1]); +ok(re.lastIndex === 5, "re.lastIndex = " + re.lastIndex); + +re = /,+/g; +r = "1,,2,".split(re); +ok(r.length === 2, "r.length = " + r.length); +ok(r[0] === "1", "r[0] = " + r[0]); +ok(r[1] === "2", "r[1] = " + r[1]); +ok(re.lastIndex === 5, "re.lastIndex = " + re.lastIndex); + +r = "1 12 \t3".split(re = /\s+/).join(";"); +ok(r === "1;12;3", "r = " + r); +ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex); + +r = "123".split(re = /\s+/).join(";"); +ok(r === "123", "r = " + r); +ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex); + +/* another standard violation */ +r = "1 12 \t3".split(re = /(\s)+/g).join(";"); +ok(r === "1;12;3", "r = " + r); +ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex); + +re = /,+/; +re.lastIndex = 4; +r = "1,,2,".split(re); +ok(r.length === 2, "r.length = " + r.length); +ok(r[0] === "1", "r[0] = " + r[0]); +ok(r[1] === "2", "r[1] = " + r[1]); +ok(re.lastIndex === 5, "re.lastIndex = " + re.lastIndex); + re = /abc[^d]/g; ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]'"); @@ -340,8 +377,11 @@ re.lastIndex = 3; re.lastIndex = "test"; ok(re.lastIndex === "test", "re.lastIndex = " + re.lastIndex + " expected 'test'"); m = re.exec(" a a "); -ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 2"); -ok(m.index === 1, "m.index = " + m.index + " expected 1"); +ok(re.lastIndex === 2 || re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 2 or 0"); +if(re.lastIndex != 0) + ok(m.index === 1, "m.index = " + m.index + " expected 1"); +else + ok(m === null, "m = " + m + " expected null"); re.lastIndex = 0; re.lastIndex = 3.9; diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index f1e6370d71d..834d5b9b648 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -2926,31 +2926,31 @@ void LOCALE_Init(void) #ifdef __APPLE__ /* MacOS doesn't set the locale environment variables so we have to do it ourselves */ - CFArrayRef preferred_locales, all_locales; - CFStringRef user_language_string_ref = NULL; char user_locale[50]; - char* p; CFLocaleRef user_locale_ref = CFLocaleCopyCurrent(); - CFStringRef user_locale_string_ref = CFLocaleGetIdentifier( user_locale_ref ); + CFStringRef user_locale_lang_ref = CFLocaleGetValue( user_locale_ref, kCFLocaleLanguageCode ); + CFStringRef user_locale_country_ref = CFLocaleGetValue( user_locale_ref, kCFLocaleCountryCode ); + CFStringRef user_locale_string_ref; + + if (user_locale_country_ref) + { + user_locale_string_ref = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@_%@.UTF-8"), + user_locale_lang_ref, user_locale_country_ref); + } + else + { + user_locale_string_ref = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.UTF-8"), + user_locale_lang_ref); + } CFStringGetCString( user_locale_string_ref, user_locale, sizeof(user_locale), kCFStringEncodingUTF8 ); CFRelease( user_locale_ref ); - /* Strip modifiers because setlocale() can't parse them. */ - if ((p = strchr( user_locale, '@' ))) *p = 0; - if (!strchr( user_locale, '.' )) strcat( user_locale, ".UTF-8" ); + CFRelease( user_locale_string_ref ); + unix_cp = CP_UTF8; /* default to utf-8 even if we don't get a valid locale */ setenv( "LANG", user_locale, 0 ); TRACE( "setting locale to '%s'\n", user_locale ); - - /* We still want to set the retrieve the preferred language as chosen in - System Preferences.app, because it can differ from CFLocaleCopyCurrent(). - */ - all_locales = CFLocaleCopyAvailableLocaleIdentifiers(); - preferred_locales = CFBundleCopyLocalizationsForPreferences( all_locales, NULL ); - if (preferred_locales && CFArrayGetCount( preferred_locales )) - user_language_string_ref = CFArrayGetValueAtIndex( preferred_locales, 0 ); - CFRelease( all_locales ); #endif /* __APPLE__ */ setlocale( LC_ALL, "" ); @@ -2959,19 +2959,28 @@ void LOCALE_Init(void) if (!lcid_LC_MESSAGES) lcid_LC_MESSAGES = lcid_LC_CTYPE; #ifdef __APPLE__ - /* Override lcid_LC_MESSAGES with user_language if LC_MESSAGES is set to default */ - if (lcid_LC_MESSAGES == lcid_LC_CTYPE && user_language_string_ref) - { - struct locale_name locale_name; - WCHAR buffer[128]; - CFStringGetCString( user_language_string_ref, user_locale, sizeof(user_locale), kCFStringEncodingUTF8 ); - strcpynAtoW( buffer, user_locale, sizeof(buffer)/sizeof(WCHAR) ); - parse_locale_name( buffer, &locale_name ); - lcid_LC_MESSAGES = locale_name.lcid; - TRACE( "setting lcid_LC_MESSAGES to '%s'\n", user_locale ); - } - if (preferred_locales) - CFRelease( preferred_locales ); + /* Override lcid_LC_MESSAGES with user's preferred language if LC_MESSAGES is set to default */ + if (!getenv("LC_ALL") && !getenv("LC_MESSAGES")) + { + /* Retrieve the preferred language as chosen in System Preferences. */ + CFArrayRef all_locales = CFLocaleCopyAvailableLocaleIdentifiers(); + CFArrayRef preferred_locales = CFBundleCopyLocalizationsForPreferences( all_locales, NULL ); + CFStringRef user_language_string_ref; + if (preferred_locales && CFArrayGetCount( preferred_locales ) && + (user_language_string_ref = CFArrayGetValueAtIndex( preferred_locales, 0 ))) + { + struct locale_name locale_name; + WCHAR buffer[128]; + CFStringGetCString( user_language_string_ref, user_locale, sizeof(user_locale), kCFStringEncodingUTF8 ); + strcpynAtoW( buffer, user_locale, sizeof(buffer)/sizeof(WCHAR) ); + parse_locale_name( buffer, &locale_name ); + lcid_LC_MESSAGES = locale_name.lcid; + TRACE( "setting lcid_LC_MESSAGES to '%s'\n", user_locale ); + } + CFRelease( all_locales ); + if (preferred_locales) + CFRelease( preferred_locales ); + } #endif NtSetDefaultUILanguage( LANGIDFROMLCID(lcid_LC_MESSAGES) ); diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 48ab3500635..a462a142857 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -469,6 +469,7 @@ static void test_GetDateFormatA(void) LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); LCID lcid_ru = MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL), SORT_DEFAULT); char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE]; + char Broken[BUFFER_SIZE]; char short_day[10], month[10], genitive_month[10]; memset(&curtime, 2, sizeof(SYSTEMTIME)); /* Invalid time */ @@ -584,15 +585,21 @@ static void test_GetDateFormatA(void) STRINGSA("MMMMdd", ""); sprintf(Expected, "%s04", genitive_month); + sprintf(Broken, "%s04", month); ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); - EXPECT_EQA; + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); STRINGSA("MMMMdd ddd", ""); sprintf(Expected, "%s04 %s", genitive_month, short_day); + sprintf(Broken, "%s04 %s", month, short_day); ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); - EXPECT_EQA; + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); STRINGSA("dd dddMMMM", ""); sprintf(Expected, "04 %s%s", short_day, month); @@ -602,16 +609,22 @@ static void test_GetDateFormatA(void) STRINGSA("dd dddMMMM ddd MMMMdd", ""); sprintf(Expected, "04 %s%s %s %s04", short_day, month, short_day, genitive_month); + sprintf(Broken, "04 %s%s %s %s04", short_day, month, short_day, month); ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); - EXPECT_EQA; + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); /* with literal part */ STRINGSA("ddd',' MMMM dd", ""); sprintf(Expected, "%s, %s 04", short_day, genitive_month); + sprintf(Broken, "%s, %s 04", short_day, month); ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); - EXPECT_EQA; + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); } static void test_GetDateFormatW(void) diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in new file mode 100644 index 00000000000..2f9db6ce883 --- /dev/null +++ b/dlls/mmdevapi/Makefile.in @@ -0,0 +1,14 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = mmdevapi.dll +IMPORTS = ole32 user32 advapi32 kernel32 ntdll + +C_SRCS = \ + main.c \ + regsvr.c + +@MAKE_DLL_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/gdi32/gdi_main.c b/dlls/mmdevapi/main.c similarity index 52% copy from dlls/gdi32/gdi_main.c copy to dlls/mmdevapi/main.c index 6734ed5df50..af200dc93fb 100644 --- a/dlls/gdi32/gdi_main.c +++ b/dlls/mmdevapi/main.c @@ -1,7 +1,5 @@ /* - * GDI initialization code - * - * Copyright 2000 Alexandre Julliard + * Copyright 2009 Maarten Lankhorst * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,20 +16,44 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + #include -#include + #include "windef.h" #include "winbase.h" -#include "wingdi.h" -#include "gdi_private.h" +#include "wine/debug.h" -/*********************************************************************** - * GDI initialisation routine - */ -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved) +#include "initguid.h" +#include "ole2.h" +#include "mmdeviceapi.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +HRESULT WINAPI DllCanUnloadNow(void) +{ + FIXME("stub\n"); + return S_FALSE; +} + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - if (reason != DLL_PROCESS_ATTACH) return TRUE; - DisableThreadLibraryCalls(hinstDLL); - LoadLibrary16( "gdi.exe" ); - return GDI_Init(); + FIXME("stub\n"); + return E_NOINTERFACE; } diff --git a/dlls/mmdevapi/mmdevapi.spec b/dlls/mmdevapi/mmdevapi.spec new file mode 100644 index 00000000000..88aaf7c30c9 --- /dev/null +++ b/dlls/mmdevapi/mmdevapi.spec @@ -0,0 +1,19 @@ + 2 stub @ + 3 stub @ + 4 stub @ + 5 stub @ + 6 stub @ + 7 stub @ + 8 stub @ + 9 stub @ +10 stub @ +11 stub @ +12 stub @ +13 stub @ +14 stub @ +15 stub @ + +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject( ptr ptr ptr ) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/dlls/mmdevapi/regsvr.c b/dlls/mmdevapi/regsvr.c new file mode 100644 index 00000000000..265c0a389d8 --- /dev/null +++ b/dlls/mmdevapi/regsvr.c @@ -0,0 +1,181 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * Copyright 2009 Maarten Lankhorst + * + * 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 NONAMELESSUNION +#define NONAMELESSSTRUCT +#define COBJMACROS +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" + +#include "guiddef.h" +#include "objbase.h" +#include "ocidl.h" +#include "mmdeviceapi.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); + +/*********************************************************************** + * interface for self-registering + */ +struct regsvr_coclass +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + LPCSTR ips32; /* can be NULL to omit */ + LPCSTR ips32_tmodel; /* can be NULL to omit */ +}; + +static HRESULT register_coclasses(struct regsvr_coclass const *list); +static HRESULT unregister_coclasses(struct regsvr_coclass const *list); + +/*********************************************************************** + * static string constants + */ +static WCHAR const clsid_keyname[] = { + 'C', 'L', 'S', 'I', 'D', 0 }; +static WCHAR const ips32_keyname[] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + '3', '2', 0 }; +static WCHAR const progid_keyname[] = { + 'P', 'r', 'o', 'g', 'I', 'D', 0 }; +static WCHAR const viprogid_keyname[] = { + 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', + 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', + 0 }; +static char const tmodel_valuename[] = "ThreadingModel"; + +/*********************************************************************** + * register_coclasses + */ +static HRESULT register_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + HKEY clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->name) { + res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips32) { + HKEY ips32_key; + + res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, + &ips32_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, + (CONST BYTE*)list->ips32, + lstrlenA(list->ips32) + 1); + if (res == ERROR_SUCCESS && list->ips32_tmodel) + res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, + (CONST BYTE*)list->ips32_tmodel, + strlen(list->ips32_tmodel) + 1); + RegCloseKey(ips32_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_coclasses + */ +static HRESULT unregister_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->clsid, buf, 39); + res = RegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * coclass list + */ +static struct regsvr_coclass const coclass_list[] = { + { &CLSID_MMDeviceEnumerator, + "MMDeviceEnumerator class", + "mmdevapi.dll", + "both" + }, + { NULL } /* list terminator */ +}; + +HRESULT WINAPI DllRegisterServer(void) +{ + TRACE("\n"); + + return register_coclasses(coclass_list); +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + TRACE("\n"); + + return unregister_coclasses(coclass_list); +} diff --git a/dlls/mpr/wnet.c b/dlls/mpr/wnet.c index cffa3405445..66d165f8b8c 100644 --- a/dlls/mpr/wnet.c +++ b/dlls/mpr/wnet.c @@ -637,7 +637,10 @@ DWORD WINAPI WNetOpenEnumA( DWORD dwScope, DWORD dwType, DWORD dwUsage, if (!lphEnum) ret = WN_BAD_POINTER; else if (!providerTable || providerTable->numProviders == 0) + { + lphEnum = NULL; ret = WN_NO_NETWORK; + } else { if (lpNet) @@ -726,7 +729,10 @@ DWORD WINAPI WNetOpenEnumW( DWORD dwScope, DWORD dwType, DWORD dwUsage, if (!lphEnum) ret = WN_BAD_POINTER; else if (!providerTable || providerTable->numProviders == 0) + { + lphEnum = NULL; ret = WN_NO_NETWORK; + } else { switch (dwScope) diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 291bba53051..eb1c78277ad 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -1146,15 +1146,19 @@ static HRESULT WINAPI HTMLDocument_get_onmouseover(IHTMLDocument2 *iface, VARIAN static HRESULT WINAPI HTMLDocument_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v) { HTMLDocument *This = HTMLDOC_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_doc_event(This, EVENTID_READYSTATECHANGE, &v); } static HRESULT WINAPI HTMLDocument_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p) { HTMLDocument *This = HTMLDOC_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_doc_event(This, EVENTID_READYSTATECHANGE, p); } static HRESULT WINAPI HTMLDocument_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v) @@ -1951,6 +1955,8 @@ static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface) This->basedoc.window->doc_obj = NULL; IHTMLWindow2_Release(HTMLWINDOW2(This->basedoc.window)); } + if(This->basedoc.advise_holder) + IOleAdviseHolder_Release(This->basedoc.advise_holder); if(This->client) IOleObject_SetClientSite(OLEOBJ(&This->basedoc), NULL); diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index c09db52e238..9b01f2648a3 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -94,6 +94,9 @@ static const WCHAR onpasteW[] = {'o','n','p','a','s','t','e',0}; static const WCHAR readystatechangeW[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0}; static const WCHAR onreadystatechangeW[] = {'o','n','r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0}; +static const WCHAR resizeW[] = {'r','e','s','i','z','e',0}; +static const WCHAR onresizeW[] = {'o','n','r','e','s','i','z','e',0}; + static const WCHAR selectstartW[] = {'s','e','l','e','c','t','s','t','a','r','t',0}; static const WCHAR onselectstartW[] = {'o','n','s','e','l','e','c','t','s','t','a','r','t',0}; @@ -162,6 +165,8 @@ static const event_info_t event_info[] = { 0}, {readystatechangeW, onreadystatechangeW, EVENTT_NONE, DISPID_EVMETH_ONREADYSTATECHANGE, 0}, + {resizeW, onresizeW, EVENTT_NONE, DISPID_EVMETH_ONRESIZE, + EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {selectstartW, onselectstartW, EVENTT_MOUSE, DISPID_EVMETH_ONSELECTSTART, 0} }; @@ -1065,6 +1070,7 @@ HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, default: FIXME("not supported vt=%d\n", V_VT(var)); + case VT_EMPTY: return E_NOTIMPL; } diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index d0332eef30c..5de023d0758 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -34,6 +34,7 @@ typedef enum { EVENTID_MOUSEUP, EVENTID_PASTE, EVENTID_READYSTATECHANGE, + EVENTID_RESIZE, EVENTID_SELECTSTART, EVENTID_LAST } eventid_t; diff --git a/dlls/mshtml/htmlframebase.c b/dlls/mshtml/htmlframebase.c index 03b48b64e31..717429882c4 100644 --- a/dlls/mshtml/htmlframebase.c +++ b/dlls/mshtml/htmlframebase.c @@ -31,6 +31,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +static const WCHAR autoW[] = {'a','u','t','o',0}; +static const WCHAR yesW[] = {'y','e','s',0}; +static const WCHAR noW[] = {'n','o',0}; + HRESULT set_frame_doc(HTMLFrameBase *frame, nsIDOMDocument *nsdoc) { nsIDOMWindow *nswindow; @@ -145,8 +149,42 @@ static HRESULT WINAPI HTMLFrameBase_put_name(IHTMLFrameBase *iface, BSTR v) static HRESULT WINAPI HTMLFrameBase_get_name(IHTMLFrameBase *iface, BSTR *p) { HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString nsstr; + const PRUnichar *strdata; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + if(This->nsframe) { + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMHTMLFrameElement_GetName(This->nsframe, &nsstr); + }else if(This->nsiframe) { + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMHTMLIFrameElement_GetName(This->nsiframe, &nsstr); + }else { + ERR("No attached ns frame object\n"); + return E_UNEXPECTED; + } + + if(NS_FAILED(nsres)) { + ERR("GetName failed: 0x%08x\n", nsres); + nsAString_Finish(&nsstr); + return E_FAIL; + } + + nsAString_GetData(&nsstr, &strdata); + if(*strdata) { + *p = SysAllocString(strdata); + if(!*p) { + nsAString_Finish(&nsstr); + return E_OUTOFMEMORY; + } + }else + *p = NULL; + + nsAString_Finish(&nsstr); + + return S_OK; } static HRESULT WINAPI HTMLFrameBase_put_border(IHTMLFrameBase *iface, VARIANT v) @@ -236,15 +274,70 @@ static HRESULT WINAPI HTMLFrameBase_get_noResize(IHTMLFrameBase *iface, VARIANT_ static HRESULT WINAPI HTMLFrameBase_put_scrolling(IHTMLFrameBase *iface, BSTR v) { HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + if(!(!strcmpiW(v, yesW) || !strcmpiW(v, noW) || !strcmpiW(v, autoW))) + return E_INVALIDARG; + + if(This->nsframe) { + nsAString_Init(&nsstr, v); + nsres = nsIDOMHTMLFrameElement_SetScrolling(This->nsframe, &nsstr); + }else if(This->nsiframe) { + nsAString_Init(&nsstr, v); + nsres = nsIDOMHTMLIFrameElement_SetScrolling(This->nsiframe, &nsstr); + }else { + ERR("No attached ns frame object\n"); + return E_UNEXPECTED; + } + nsAString_Finish(&nsstr); + + if(NS_FAILED(nsres)) { + ERR("SetScrolling failed: 0x%08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLFrameBase_get_scrolling(IHTMLFrameBase *iface, BSTR *p) { HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString nsstr; + const PRUnichar *strdata; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + if(This->nsframe) { + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMHTMLFrameElement_GetScrolling(This->nsframe, &nsstr); + }else if(This->nsiframe) { + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMHTMLIFrameElement_GetScrolling(This->nsiframe, &nsstr); + }else { + ERR("No attached ns frame object\n"); + return E_UNEXPECTED; + } + + if(NS_FAILED(nsres)) { + ERR("GetScrolling failed: 0x%08x\n", nsres); + nsAString_Finish(&nsstr); + return E_FAIL; + } + + nsAString_GetData(&nsstr, &strdata); + + if(*strdata) + *p = SysAllocString(strdata); + else + *p = SysAllocString(autoW); + + nsAString_Finish(&nsstr); + + return *p ? S_OK : E_OUTOFMEMORY; } static const IHTMLFrameBaseVtbl HTMLFrameBaseVtbl = { @@ -443,16 +536,31 @@ void HTMLFrameBase_destructor(HTMLFrameBase *This) if(This->content_window) This->content_window->frame_element = NULL; + if(This->nsframe) + nsIDOMHTMLFrameElement_Release(This->nsframe); + if(This->nsiframe) + nsIDOMHTMLIFrameElement_Release(This->nsiframe); + HTMLElement_destructor(&This->element.node); } void HTMLFrameBase_Init(HTMLFrameBase *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, dispex_static_data_t *dispex_data) { + nsresult nsres; + This->lpIHTMLFrameBaseVtbl = &HTMLFrameBaseVtbl; This->lpIHTMLFrameBase2Vtbl = &HTMLFrameBase2Vtbl; HTMLElement_Init(&This->element, doc, nselem, dispex_data); + + nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLFrameElement, (void**)&This->nsframe); + if(NS_FAILED(nsres)) { + nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLIFrameElement, (void**)&This->nsiframe); + if(NS_FAILED(nsres)) + ERR("Could not get nsIDOMHTML[I]Frame interface\n"); + }else + This->nsiframe = NULL; } typedef struct { @@ -492,17 +600,11 @@ static HRESULT HTMLFrameElement_get_document(HTMLDOMNode *iface, IDispatch **p) static HRESULT HTMLFrameElement_bind_to_tree(HTMLDOMNode *iface) { HTMLFrameElement *This = HTMLFRAME_NODE_THIS(iface); - nsIDOMHTMLFrameElement *nsframe; nsIDOMDocument *nsdoc; nsresult nsres; HRESULT hres; - nsres = nsIDOMHTMLElement_QueryInterface(This->framebase.element.nselem, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); - if(NS_FAILED(nsres)) - return E_FAIL; - - nsres = nsIDOMHTMLFrameElement_GetContentDocument(nsframe, &nsdoc); - nsIDOMHTMLFrameElement_Release(nsframe); + nsres = nsIDOMHTMLFrameElement_GetContentDocument(This->framebase.nsframe, &nsdoc); if(NS_FAILED(nsres) || !nsdoc) { ERR("GetContentDocument failed: %08x\n", nsres); return E_FAIL; @@ -531,18 +633,12 @@ static const NodeImplVtbl HTMLFrameElementImplVtbl = { HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { - nsIDOMHTMLFrameElement *nsframe; HTMLFrameElement *ret; - nsresult nsres; ret = heap_alloc_zero(sizeof(HTMLFrameElement)); ret->framebase.element.node.vtbl = &HTMLFrameElementImplVtbl; - nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); - if(NS_FAILED(nsres)) - ERR("Could not get nsIDOMHTMLFrameElement iface: %08x\n", nsres); - HTMLFrameBase_Init(&ret->framebase, doc, nselem, NULL); return &ret->framebase.element; diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c index 2132df35308..ed86dd0394b 100644 --- a/dlls/mshtml/htmliframe.c +++ b/dlls/mshtml/htmliframe.c @@ -33,10 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); typedef struct { HTMLFrameBase framebase; - - LONG ref; - - nsIDOMHTMLIFrameElement *nsiframe; } HTMLIFrame; #define HTMLIFRAME_NODE_THIS(iface) DEFINE_THIS2(HTMLIFrame, framebase.element.node, iface) @@ -52,9 +48,6 @@ static void HTMLIFrame_destructor(HTMLDOMNode *iface) { HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface); - if(This->nsiframe) - nsIDOMHTMLIFrameElement_Release(This->nsiframe); - HTMLFrameBase_destructor(&This->framebase); } @@ -86,7 +79,7 @@ static HRESULT HTMLIFrame_bind_to_tree(HTMLDOMNode *iface) nsresult nsres; HRESULT hres; - nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->nsiframe, &nsdoc); + nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->framebase.nsiframe, &nsdoc); if(NS_FAILED(nsres) || !nsdoc) { ERR("GetContentDocument failed: %08x\n", nsres); return E_FAIL; @@ -134,16 +127,11 @@ static dispex_static_data_t HTMLIFrame_dispex = { HTMLElement *HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLIFrame *ret; - nsresult nsres; ret = heap_alloc_zero(sizeof(HTMLIFrame)); ret->framebase.element.node.vtbl = &HTMLIFrameImplVtbl; - nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLIFrameElement, (void**)&ret->nsiframe); - if(NS_FAILED(nsres)) - ERR("Could not get nsIDOMHTMLIFrameElement iface: %08x\n", nsres); - HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLIFrame_dispex); return &ret->framebase.element; diff --git a/dlls/mshtml/htmltextnode.c b/dlls/mshtml/htmltextnode.c index 799a13755eb..1c2c2daca8b 100644 --- a/dlls/mshtml/htmltextnode.c +++ b/dlls/mshtml/htmltextnode.c @@ -35,6 +35,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); struct HTMLDOMTextNode { HTMLDOMNode node; const IHTMLDOMTextNodeVtbl *lpIHTMLDOMTextNodeVtbl; + + nsIDOMText *nstext; }; #define HTMLTEXT(x) (&(x)->lpIHTMLDOMTextNodeVtbl) @@ -119,8 +121,17 @@ static HRESULT WINAPI HTMLDOMTextNode_toString(IHTMLDOMTextNode *iface, BSTR *St static HRESULT WINAPI HTMLDOMTextNode_get_length(IHTMLDOMTextNode *iface, LONG *p) { HTMLDOMTextNode *This = HTMLTEXT_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRUint32 length = 0; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMText_GetLength(This->nstext, &length); + if(NS_FAILED(nsres)) + ERR("GetLength failed: %08x\n", nsres); + + *p = length; + return S_OK; } static HRESULT WINAPI HTMLDOMTextNode_splitText(IHTMLDOMTextNode *iface, LONG offset, IHTMLDOMNode **pRetNode) @@ -170,6 +181,9 @@ static void HTMLDOMTextNode_destructor(HTMLDOMNode *iface) { HTMLDOMTextNode *This = HTMLTEXT_NODE_THIS(iface); + if(This->nstext) + IHTMLDOMTextNode_Release(This->nstext); + HTMLDOMNode_destructor(&This->node); } @@ -195,7 +209,8 @@ static dispex_static_data_t HTMLDOMTextNode_dispex = { HTMLDOMNode *HTMLDOMTextNode_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode) { - HTMLDOMTextNode *ret ; + HTMLDOMTextNode *ret; + nsresult nsres; ret = heap_alloc_zero(sizeof(*ret)); ret->node.vtbl = &HTMLDOMTextNodeImplVtbl; @@ -204,5 +219,9 @@ HTMLDOMNode *HTMLDOMTextNode_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode) init_dispex(&ret->node.dispex, (IUnknown*)HTMLTEXT(ret), &HTMLDOMTextNode_dispex); HTMLDOMNode_Init(doc, &ret->node, nsnode); + nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMText, (void**)&ret->nstext); + if(NS_FAILED(nsres)) + ERR("Could not get nsIDOMText iface: %08x\n", nsres); + return &ret->node; } diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 8838586cfdc..6bc971c917f 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -893,15 +893,19 @@ static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p) static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - FIXME("(%p)->(v(%d))\n", This, V_VT(&v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_window_event(This, EVENTID_RESIZE, &v); } static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_window_event(This, EVENTID_RESIZE, p); } static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 2a778084eb9..1beaf550ac6 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -338,6 +338,8 @@ struct HTMLDocument { ConnectionPoint cp_htmldocevents; ConnectionPoint cp_htmldocevents2; ConnectionPoint cp_propnotif; + + IOleAdviseHolder *advise_holder; }; static inline HRESULT htmldoc_query_interface(HTMLDocument *This, REFIID riid, void **ppv) @@ -377,12 +379,14 @@ struct HTMLDocumentObj { HWND hwnd; HWND tooltips_hwnd; + BOOL request_uiactivate; BOOL in_place_active; BOOL ui_active; BOOL window_active; BOOL has_key_path; BOOL container_locked; BOOL focus; + INT download_state; USERMODE usermode; LPWSTR mime; @@ -500,6 +504,9 @@ struct HTMLFrameBase { const IHTMLFrameBase2Vtbl *lpIHTMLFrameBase2Vtbl; HTMLWindow *content_window; + + nsIDOMHTMLFrameElement *nsframe; + nsIDOMHTMLIFrameElement *nsiframe; }; typedef struct _mutation_queue_t { diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 7c4c09b0fa7..46f057f079a 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -185,17 +185,19 @@ static void handle_docobj_load(HTMLDocumentObj *doc) hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); if(SUCCEEDED(hres)) { - VARIANT state, progress; - - V_VT(&progress) = VT_I4; - V_I4(&progress) = 0; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER, - &progress, NULL); - - V_VT(&state) = VT_I4; - V_I4(&state) = 0; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, - &state, NULL); + if(doc->download_state) { + VARIANT state, progress; + + V_VT(&progress) = VT_I4; + V_I4(&progress) = 0; + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, + OLECMDEXECOPT_DONTPROMPTUSER, &progress, NULL); + + V_VT(&state) = VT_I4; + V_I4(&state) = 0; + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, + OLECMDEXECOPT_DONTPROMPTUSER, &state, NULL); + } IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL); IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL); @@ -203,6 +205,7 @@ static void handle_docobj_load(HTMLDocumentObj *doc) IOleCommandTarget_Release(olecmd); } + doc->download_state = 0; } static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event) diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c index e9cb2040a0a..872d766489d 100644 --- a/dlls/mshtml/oleobj.c +++ b/dlls/mshtml/oleobj.c @@ -250,6 +250,9 @@ static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption) IOleInPlaceObjectWindowless_InPlaceDeactivate(INPLACEWIN(This)); HTMLDocument_LockContainer(This->doc_obj, FALSE); + + if(This->advise_holder) + IOleAdviseHolder_SendOnClose(This->advise_holder); return S_OK; } @@ -380,22 +383,46 @@ static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection) { HTMLDocument *This = OLEOBJ_THIS(iface); - FIXME("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection); - return E_NOTIMPL; + TRACE("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection); + + if(!pdwConnection) + return E_INVALIDARG; + + if(!pAdvSink) { + *pdwConnection = 0; + return E_INVALIDARG; + } + + if(!This->advise_holder) { + CreateOleAdviseHolder(&This->advise_holder); + if(!This->advise_holder) + return E_OUTOFMEMORY; + } + + return IOleAdviseHolder_Advise(This->advise_holder, pAdvSink, pdwConnection); } static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection) { HTMLDocument *This = OLEOBJ_THIS(iface); - FIXME("(%p)->(%d)\n", This, dwConnection); - return E_NOTIMPL; + TRACE("(%p)->(%d)\n", This, dwConnection); + + if(!This->advise_holder) + return OLE_E_NOCONNECTION; + + return IOleAdviseHolder_Unadvise(This->advise_holder, dwConnection); } static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise) { HTMLDocument *This = OLEOBJ_THIS(iface); - FIXME("(%p)->(%p)\n", This, ppenumAdvise); - return E_NOTIMPL; + + if(!This->advise_holder) { + *ppenumAdvise = NULL; + return S_OK; + } + + return IOleAdviseHolder_EnumAdvise(This->advise_holder, ppenumAdvise); } static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus) diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 2ea0e5df72f..eaff9ddbd61 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -40,6 +40,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +typedef struct { + task_t header; + HTMLDocumentObj *doc; + BOOL set_download; +} download_proc_task_t; + static BOOL use_gecko_script(LPCWSTR url) { static const WCHAR fileW[] = {'f','i','l','e',':'}; @@ -118,7 +124,8 @@ static void set_progress_proc(task_t *_task) static void set_downloading_proc(task_t *_task) { - HTMLDocumentObj *doc = ((docobj_task_t*)_task)->doc; + download_proc_task_t *task = (download_proc_task_t*)_task; + HTMLDocumentObj *doc = task->doc; IOleCommandTarget *olecmd; HRESULT hres; @@ -130,16 +137,20 @@ static void set_downloading_proc(task_t *_task) if(!doc->client) return; - hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); - if(SUCCEEDED(hres)) { - VARIANT var; + if(task->set_download) { + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + if(SUCCEEDED(hres)) { + VARIANT var; - V_VT(&var) = VT_I4; - V_I4(&var) = 1; + V_VT(&var) = VT_I4; + V_I4(&var) = 1; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, - &var, NULL); - IOleCommandTarget_Release(olecmd); + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, + OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL); + IOleCommandTarget_Release(olecmd); + } + + doc->download_state = 1; } if(doc->hostui) { @@ -153,11 +164,12 @@ static void set_downloading_proc(task_t *_task) } } -static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc) +static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BOOL set_download) { nsChannelBSC *bscallback; LPOLESTR url = NULL; docobj_task_t *task; + download_proc_task_t *download_task; HRESULT hres; nsresult nsres; @@ -248,9 +260,10 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc) push_task(&task->header, set_progress_proc, This->doc_obj->basedoc.task_magic); } - task = heap_alloc(sizeof(docobj_task_t)); - task->doc = This->doc_obj; - push_task(&task->header, set_downloading_proc, This->doc_obj->basedoc.task_magic); + download_task = heap_alloc(sizeof(download_proc_task_t)); + download_task->doc = This->doc_obj; + download_task->set_download = set_download; + push_task(&download_task->header, set_downloading_proc, This->doc_obj->basedoc.task_magic); if(This->doc_obj->nscontainer) { This->doc_obj->nscontainer->bscallback = bscallback; @@ -363,7 +376,7 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva TRACE("(%p)->(%x %p %p %08x)\n", This, fFullyAvailable, pimkName, pibc, grfMode); - hres = set_moniker(This, pimkName, pibc); + hres = set_moniker(This, pimkName, pibc, TRUE); if(FAILED(hres)) return hres; @@ -624,7 +637,7 @@ static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM return hres; } - hres = set_moniker(This, mon, NULL); + hres = set_moniker(This, mon, NULL, TRUE); IMoniker_Release(mon); if(FAILED(hres)) return hres; @@ -669,8 +682,45 @@ static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface) { HTMLDocument *This = PERSTRINIT_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + IMoniker *mon; + HGLOBAL body; + LPSTREAM stream; + HRESULT hres; + + static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; + static const WCHAR html_bodyW[] = {'<','H','T','M','L','>','<','/','H','T','M','L','>',0}; + + TRACE("(%p)\n", This); + + body = GlobalAlloc(0, sizeof(html_bodyW)); + if(!body) + return E_OUTOFMEMORY; + memcpy(body, html_bodyW, sizeof(html_bodyW)); + + hres = CreateURLMoniker(NULL, about_blankW, &mon); + if(FAILED(hres)) { + WARN("CreateURLMoniker failed: %08x\n", hres); + GlobalFree(body); + return hres; + } + + hres = set_moniker(This, mon, NULL, FALSE); + IMoniker_Release(mon); + if(FAILED(hres)) { + GlobalFree(body); + return hres; + } + + hres = CreateStreamOnHGlobal(body, TRUE, &stream); + if(FAILED(hres)) { + GlobalFree(body); + return hres; + } + + hres = channelbsc_load_stream(This->window->bscallback, stream); + + IStream_Release(stream); + return hres; } #undef PERSTRINIT_THIS diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 7df0dd6e9f3..efd2605de39 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -895,7 +895,7 @@ BOOL find_global_prop(HTMLWindow *window, BSTR name, DWORD flags, ScriptHost **r hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); if(SUCCEEDED(hres)) { - hres = IDispatchEx_GetDispID(dispex, name, flags, ret_id); + hres = IDispatchEx_GetDispID(dispex, name, flags & (~fdexNameEnsure), ret_id); IDispatchEx_Release(dispex); }else { FIXME("No IDispatchEx\n"); diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 367bbeeea36..e32e2fdc303 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -65,8 +65,9 @@ static const char cond_comment_str[] = "" ""; static const char frameset_str[] = - "frameset test" + "frameset test" "" + "" ""; static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0}; @@ -656,6 +657,17 @@ static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk) return anchor; } +#define get_text_iface(u) _get_text_iface(__LINE__,u) +static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk) +{ + IHTMLDOMTextNode *text; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres); + return text; +} + #define test_node_name(u,n) _test_node_name(__LINE__,u,n) static void _test_node_name(unsigned line, IUnknown *unk, const char *exname) { @@ -1737,6 +1749,19 @@ static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select, _test_elem3_get_disabled(line, (IUnknown*)select, exb); } +#define test_text_length(u,l) _test_text_length(__LINE__,u,l) +static void _test_text_length(unsigned line, IUnknown *unk, LONG l) +{ + IHTMLDOMTextNode *text = _get_text_iface(line, unk); + LONG length; + HRESULT hres; + + hres = IHTMLDOMTextNode_get_length(text, &length); + ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres); + ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l); + IHTMLDOMTextNode_Release(text); +} + #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b) static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b) { @@ -5717,6 +5742,7 @@ static void test_create_elems(IHTMLDocument2 *doc) node = test_create_text(doc, "test"); test_ifaces((IUnknown*)node, text_iids); test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]"); + test_text_length((IUnknown*)node, 4); V_VT(&var) = VT_NULL; node2 = test_node_insertbefore((IUnknown*)body, node, &var); @@ -5899,8 +5925,10 @@ static void test_frameset(IHTMLDocument2 *doc) IHTMLWindow2 *window; IHTMLFramesCollection2 *frames; IHTMLElement *elem; + IHTMLFrameBase *fbase; LONG length; VARIANT index_var, result_var; + BSTR str; HRESULT hres; window = get_doc_window(doc); @@ -5916,7 +5944,7 @@ static void test_frameset(IHTMLDocument2 *doc) /* test result length */ hres = IHTMLFramesCollection2_get_length(frames, &length); ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres); - ok(length == 2, "IHTMLFramesCollection2_get_length should have been 2, was: %d\n", length); + ok(length == 3, "IHTMLFramesCollection2_get_length should have been 3, was: %d\n", length); /* test first frame */ V_VT(&index_var) = VT_I4; @@ -5939,8 +5967,8 @@ static void test_frameset(IHTMLDocument2 *doc) } VariantClear(&result_var); - /* fail on third frame */ - V_I4(&index_var) = 2; + /* fail on next frame */ + V_I4(&index_var) = 3; hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var); ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have" "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres); @@ -5973,7 +6001,7 @@ static void test_frameset(IHTMLDocument2 *doc) /* test result length */ hres = IHTMLWindow2_get_length(window, &length); ok(hres == S_OK, "IHTMLWindow2_get_length failed: 0x%08x\n", hres); - ok(length == 2, "IHTMLWindow2_get_length should have been 2, was: %d\n", length); + ok(length == 3, "IHTMLWindow2_get_length should have been 3, was: %d\n", length); /* test first frame */ V_VT(&index_var) = VT_I4; @@ -5996,8 +6024,8 @@ static void test_frameset(IHTMLDocument2 *doc) } VariantClear(&result_var); - /* fail on third frame */ - V_I4(&index_var) = 2; + /* fail on next frame */ + V_I4(&index_var) = 3; hres = IHTMLWindow2_item(window, &index_var, &result_var); ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLWindow2_item should have" "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres); @@ -6026,6 +6054,57 @@ static void test_frameset(IHTMLDocument2 *doc) /* getElementById with node name attributes */ elem = get_doc_elem_by_id(doc, "nm1"); test_elem_id((IUnknown*)elem, "fr1"); + + /* get/put scrolling */ + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase); + ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres); + + hres = IHTMLFrameBase_get_scrolling(fbase, &str); + ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres); + ok(!strcmp_wa(str, "auto"), "get_scrolling should have given 'auto', gave: %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + str = a2bstr("no"); + hres = IHTMLFrameBase_put_scrolling(fbase, str); + ok(hres == S_OK, "IHTMLFrameBase_put_scrolling failed: 0x%08x\n", hres); + SysFreeString(str); + + hres = IHTMLFrameBase_get_scrolling(fbase, &str); + ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres); + ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + str = a2bstr("junk"); + hres = IHTMLFrameBase_put_scrolling(fbase, str); + ok(hres == E_INVALIDARG, "IHTMLFrameBase_put_scrolling should have failed " + "with E_INVALIDARG, instead: 0x%08x\n", hres); + SysFreeString(str); + + hres = IHTMLFrameBase_get_scrolling(fbase, &str); + ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres); + ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + /* get_name */ + hres = IHTMLFrameBase_get_name(fbase, &str); + ok(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres); + ok(!strcmp_wa(str, "nm1"), "get_name should have given 'nm1', gave: %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IHTMLFrameBase_Release(fbase); + IHTMLElement_Release(elem); + + /* get_name with no name attr */ + elem = get_doc_elem_by_id(doc, "fr3"); + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase); + ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres); + + hres = IHTMLFrameBase_get_name(fbase, &str); + ok(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres); + ok(str == NULL, "get_name should have given 'null', gave: %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IHTMLFrameBase_Release(fbase); IHTMLElement_Release(elem); } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 46bbd4fd931..84bfae25347 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -342,7 +342,7 @@ static void _test_attached_event_args(unsigned line, DISPID id, WORD wFlags, DIS IHTMLEventObj_Release(event); } -#define get_event_src(t) _get_event_src(__LINE__) +#define get_event_src() _get_event_src(__LINE__) static IHTMLElement *_get_event_src(unsigned line) { IHTMLEventObj *event = _get_event_obj(line); @@ -1082,6 +1082,10 @@ static void test_onclick(IHTMLDocument2 *doc) ok(hres == S_OK, "get_onclick failed: %08x\n", hres); ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v)); + V_VT(&v) = VT_EMPTY; + hres = IHTMLElement_put_onclick(div, v); + ok(hres == E_NOTIMPL, "put_onclick failed: %08x\n", hres); + V_VT(&v) = VT_DISPATCH; V_DISPATCH(&v) = (IDispatch*)&div_onclick_obj; hres = IHTMLElement_put_onclick(div, v); @@ -1770,12 +1774,23 @@ static void set_client_site(IHTMLDocument2 *doc, BOOL set) static IHTMLDocument2 *create_document(void) { IHTMLDocument2 *doc; + IHTMLDocument5 *doc5; HRESULT hres; hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IHTMLDocument2, (void**)&doc); ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres); + if (FAILED(hres)) + return NULL; + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5); + if(FAILED(hres)) { + win_skip("Could not get IHTMLDocument5 interface, probably too old IE\n"); + IHTMLDocument2_Release(doc); + return NULL; + } + IHTMLDocument5_Release(doc5); return doc; } @@ -1786,12 +1801,13 @@ static void run_test(const char *str, testfunc_t test) { IHTMLDocument2 *doc; IHTMLElement *body = NULL; - ULONG ref; MSG msg; HRESULT hres; xy_todo = FALSE; doc = create_document(); + if (!doc) + return; set_client_site(doc, TRUE); doc_load_string(doc, str); do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); @@ -1820,8 +1836,7 @@ static void run_test(const char *str, testfunc_t test) } set_client_site(doc, FALSE); - ref = IHTMLDocument2_Release(doc); - ok(!ref, "ref = %d\n", ref); + IHTMLDocument2_Release(doc); } static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index ab1a0e000af..f543dccef6d 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -150,12 +150,13 @@ DEFINE_EXPECT(Frame_EnableModeless_TRUE); DEFINE_EXPECT(Frame_EnableModeless_FALSE); DEFINE_EXPECT(Frame_GetWindow); DEFINE_EXPECT(TranslateUrl); +DEFINE_EXPECT(Advise_Close); static IUnknown *doc_unk; static IMoniker *doc_mon; static BOOL expect_LockContainer_fLock; static BOOL expect_InPlaceUIWindow_SetActiveObject_active = TRUE; -static BOOL ipsex; +static BOOL ipsex, ipsw; static BOOL set_clientsite = FALSE, container_locked = FALSE; static BOOL readystate_set_loading = FALSE, readystate_set_interactive = FALSE, load_from_stream; static BOOL editmode = FALSE, show_failed; @@ -1487,22 +1488,23 @@ static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = { static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl }; -static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv) +static HRESULT WINAPI InPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv) { return QueryInterface(riid, ppv); } -static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface) +static ULONG WINAPI InPlaceSiteWindowless_AddRef(IOleInPlaceSiteWindowless *iface) { return 2; } -static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface) +static ULONG WINAPI InPlaceSiteWindowless_Release(IOleInPlaceSiteWindowless *iface) { return 1; } -static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd) +static HRESULT WINAPI InPlaceSiteWindowless_GetWindow( + IOleInPlaceSiteWindowless *iface, HWND *phwnd) { CHECK_EXPECT2(GetWindow); ok(phwnd != NULL, "phwnd = NULL\n"); @@ -1510,33 +1512,38 @@ static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwn return S_OK; } -static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode) +static HRESULT WINAPI InPlaceSiteWindowless_ContextSensitiveHelp( + IOleInPlaceSiteWindowless *iface, BOOL fEnterMode) { ok(0, "unexpected call\n"); return E_NOTIMPL; } -static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_CanInPlaceActivate( + IOleInPlaceSiteWindowless *iface) { CHECK_EXPECT(CanInPlaceActivate); return S_OK; } -static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceActivate( + IOleInPlaceSiteWindowless *iface) { CHECK_EXPECT(OnInPlaceActivate); inplace_deactivated = FALSE; return S_OK; } -static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_OnUIActivate( + IOleInPlaceSiteWindowless *iface) { CHECK_EXPECT(OnUIActivate); return S_OK; } -static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface, - IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, +static HRESULT WINAPI InPlaceSiteWindowless_GetWindowContext( + IOleInPlaceSiteWindowless *iface, IOleInPlaceFrame **ppFrame, + IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) { static const RECT rect = {0,0,500,500}; @@ -1567,45 +1574,52 @@ static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface, return S_OK; } -static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtant) +static HRESULT WINAPI InPlaceSiteWindowless_Scroll( + IOleInPlaceSiteWindowless *iface, SIZE scrollExtent) { ok(0, "unexpected call\n"); return E_NOTIMPL; } -static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable) +static HRESULT WINAPI InPlaceSiteWindowless_OnUIDeactivate( + IOleInPlaceSiteWindowless *iface, BOOL fUndoable) { CHECK_EXPECT(OnUIDeactivate); ok(!fUndoable, "fUndoable = TRUE\n"); return S_OK; } -static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceDeactivate( + IOleInPlaceSiteWindowless *iface) { CHECK_EXPECT(OnInPlaceDeactivate); inplace_deactivated = TRUE; return S_OK; } -static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_DiscardUndoState( + IOleInPlaceSiteWindowless *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } -static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_DeactivateAndUndo( + IOleInPlaceSiteWindowless *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } -static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect) +static HRESULT WINAPI InPlaceSiteWindowless_OnPosRectChange( + IOleInPlaceSiteWindowless *iface, LPCRECT lprcPosRect) { ok(0, "unexpected call\n"); return E_NOTIMPL; } -static HRESULT WINAPI InPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface, BOOL *pfNoRedraw, DWORD dwFlags) +static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceActivateEx( + IOleInPlaceSiteWindowless *iface, BOOL *pfNoRedraw, DWORD dwFlags) { CHECK_EXPECT(OnInPlaceActivateEx); @@ -1616,7 +1630,8 @@ static HRESULT WINAPI InPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface return S_OK; } -static HRESULT WINAPI InPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw) +static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceDeactivateEx( + IOleInPlaceSiteWindowless *iface, BOOL fNoRedraw) { CHECK_EXPECT(OnInPlaceDeactivateEx); @@ -1625,34 +1640,134 @@ static HRESULT WINAPI InPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *ifa return S_OK; } -static HRESULT WINAPI InPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx *iface) +static HRESULT WINAPI InPlaceSiteWindowless_RequestUIActivate( + IOleInPlaceSiteWindowless *iface) { - CHECK_EXPECT(RequestUIActivate); + CHECK_EXPECT2(RequestUIActivate); return S_OK; } -static const IOleInPlaceSiteExVtbl InPlaceSiteVtbl = { - InPlaceSite_QueryInterface, - InPlaceSite_AddRef, - InPlaceSite_Release, - InPlaceSite_GetWindow, - InPlaceSite_ContextSensitiveHelp, - InPlaceSite_CanInPlaceActivate, - InPlaceSite_OnInPlaceActivate, - InPlaceSite_OnUIActivate, - InPlaceSite_GetWindowContext, - InPlaceSite_Scroll, - InPlaceSite_OnUIDeactivate, - InPlaceSite_OnInPlaceDeactivate, - InPlaceSite_DiscardUndoState, - InPlaceSite_DeactivateAndUndo, - InPlaceSite_OnPosRectChange, - InPlaceSiteEx_OnInPlaceActivateEx, - InPlaceSiteEx_OnInPlaceDeactivateEx, - InPlaceSiteEx_RequestUIActivate +static HRESULT WINAPI InPlaceSiteWindowless_CanWindowlessActivate( + IOleInPlaceSiteWindowless *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_GetCapture( + IOleInPlaceSiteWindowless *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_SetCapture( + IOleInPlaceSiteWindowless *iface, BOOL fCapture) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_GetFocus( + IOleInPlaceSiteWindowless *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_SetFocus( + IOleInPlaceSiteWindowless *iface, BOOL fFocus) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_GetDC( + IOleInPlaceSiteWindowless *iface, LPCRECT pRect, + DWORD grfFlags, HDC *phDC) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_ReleaseDC( + IOleInPlaceSiteWindowless *iface, HDC hDC) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_InvalidateRect( + IOleInPlaceSiteWindowless *iface, LPCRECT pRect, BOOL fErase) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_InvalidateRgn( + IOleInPlaceSiteWindowless *iface, HRGN hRGN, BOOL fErase) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_ScrollRect( + IOleInPlaceSiteWindowless *iface, INT dx, INT dy, + LPCRECT pRectScroll, LPCRECT pRectClip) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_AdjustRect( + IOleInPlaceSiteWindowless *iface, LPRECT prc) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSiteWindowless_OnDefWindowMessage( + IOleInPlaceSiteWindowless *iface, UINT msg, + WPARAM wParam, LPARAM lParam, LRESULT *plResult) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IOleInPlaceSiteWindowlessVtbl InPlaceSiteWindowlessVtbl = { + InPlaceSiteWindowless_QueryInterface, + InPlaceSiteWindowless_AddRef, + InPlaceSiteWindowless_Release, + InPlaceSiteWindowless_GetWindow, + InPlaceSiteWindowless_ContextSensitiveHelp, + InPlaceSiteWindowless_CanInPlaceActivate, + InPlaceSiteWindowless_OnInPlaceActivate, + InPlaceSiteWindowless_OnUIActivate, + InPlaceSiteWindowless_GetWindowContext, + InPlaceSiteWindowless_Scroll, + InPlaceSiteWindowless_OnUIDeactivate, + InPlaceSiteWindowless_OnInPlaceDeactivate, + InPlaceSiteWindowless_DiscardUndoState, + InPlaceSiteWindowless_DeactivateAndUndo, + InPlaceSiteWindowless_OnPosRectChange, + InPlaceSiteWindowless_OnInPlaceActivateEx, + InPlaceSiteWindowless_OnInPlaceDeactivateEx, + InPlaceSiteWindowless_RequestUIActivate, + InPlaceSiteWindowless_CanWindowlessActivate, + InPlaceSiteWindowless_GetCapture, + InPlaceSiteWindowless_SetCapture, + InPlaceSiteWindowless_GetFocus, + InPlaceSiteWindowless_SetFocus, + InPlaceSiteWindowless_GetDC, + InPlaceSiteWindowless_ReleaseDC, + InPlaceSiteWindowless_InvalidateRect, + InPlaceSiteWindowless_InvalidateRgn, + InPlaceSiteWindowless_ScrollRect, + InPlaceSiteWindowless_AdjustRect, + InPlaceSiteWindowless_OnDefWindowMessage }; -static IOleInPlaceSiteEx InPlaceSiteEx = { &InPlaceSiteVtbl }; +static IOleInPlaceSiteWindowless InPlaceSiteWindowless = { &InPlaceSiteWindowlessVtbl }; static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) { @@ -1757,7 +1872,7 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres); if(SUCCEEDED(hres)) { - hres = IOleDocument_CreateView(document, (IOleInPlaceSite*)&InPlaceSiteEx, NULL, 0, &view); + hres = IOleDocument_CreateView(document, (IOleInPlaceSite*)&InPlaceSiteWindowless, NULL, 0, &view); ok(hres == S_OK, "CreateView failed: %08x\n", hres); if(SUCCEEDED(hres)) { @@ -1768,16 +1883,16 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite); ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres); - ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteEx, "inplacesite=%p, expected %p\n", - inplacesite, &InPlaceSiteEx); + ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteWindowless, "inplacesite=%p, expected %p\n", + inplacesite, &InPlaceSiteWindowless); - hres = IOleDocumentView_SetInPlaceSite(view, (IOleInPlaceSite*)&InPlaceSiteEx); + hres = IOleDocumentView_SetInPlaceSite(view, (IOleInPlaceSite*)&InPlaceSiteWindowless); ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres); hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite); ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres); - ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteEx, "inplacesite=%p, expected %p\n", - inplacesite, &InPlaceSiteEx); + ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteWindowless, "inplacesite=%p, expected %p\n", + inplacesite, &InPlaceSiteWindowless); hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobj); ok(hres == S_OK, "Could not get IOleInPlaceActiveObject: %08x\n", hres); @@ -2255,6 +2370,8 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt); ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut); ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn); + readystate_set_loading = FALSE; + readystate_set_interactive = FALSE; load_state = LD_COMPLETE; return S_OK; case OLECMDID_SETDOWNLOADSTATE: @@ -2547,6 +2664,62 @@ static const IServiceProviderVtbl ServiceProviderVtbl = { static IServiceProvider ServiceProvider = { &ServiceProviderVtbl }; +static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, + REFIID riid, void **ppv) +{ + return QueryInterface(riid, ppv); +} + +static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface) +{ + return 2; +} + +static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface) +{ + return 1; +} + +static void WINAPI AdviseSink_OnDataChange(IAdviseSink *iface, + FORMATETC *pFormatetc, STGMEDIUM *pStgmed) +{ + ok(0, "unexpected call\n"); +} + +static void WINAPI AdviseSink_OnViewChange(IAdviseSink *iface, + DWORD dwAspect, LONG lindex) +{ + ok(0, "unexpected call\n"); +} + +static void WINAPI AdviseSink_OnRename(IAdviseSink *iface, IMoniker *pmk) +{ + ok(0, "unexpected call\n"); +} + +static void WINAPI AdviseSink_OnSave(IAdviseSink *iface) +{ + ok(0, "unexpected call\n"); +} + +static void WINAPI AdviseSink_OnClose(IAdviseSink *iface) +{ + CHECK_EXPECT(Advise_Close); +} + +static const IAdviseSinkVtbl AdviseSinkVtbl = { + AdviseSink_QueryInterface, + AdviseSink_AddRef, + AdviseSink_Release, + AdviseSink_OnDataChange, + AdviseSink_OnViewChange, + AdviseSink_OnRename, + AdviseSink_OnSave, + AdviseSink_OnClose +}; + +static IAdviseSink AdviseSink = { &AdviseSinkVtbl }; + DEFINE_GUID(IID_unk1, 0xD48A6EC6,0x6A4A,0x11CF,0x94,0xA7,0x44,0x45,0x53,0x54,0x00,0x00); /* HTMLWindow2 ? */ DEFINE_GUID(IID_IThumbnailView, 0x7BB0B520,0xB1A7,0x11D2,0xBB,0x23,0x00,0xC0,0x4F,0x79,0xAB,0xCD); DEFINE_GUID(IID_IRenMailEditor, 0x000670BA,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); @@ -2566,7 +2739,7 @@ static HRESULT QueryInterface(REFIID riid, void **ppv) else if(IsEqualGUID(&IID_IOleContainer, riid)) *ppv = &OleContainer; else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid)) - *ppv = &InPlaceSiteEx; + *ppv = &InPlaceSiteWindowless; else if(IsEqualGUID(&IID_IOleCommandTarget , riid)) *ppv = &OleCommandTarget; else if(IsEqualGUID(&IID_IDispatch, riid)) @@ -2574,7 +2747,9 @@ static HRESULT QueryInterface(REFIID riid, void **ppv) else if(IsEqualGUID(&IID_IServiceProvider, riid)) *ppv = &ServiceProvider; else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid)) - *ppv = ipsex ? &InPlaceSiteEx : NULL; + *ppv = ipsex ? &InPlaceSiteWindowless : NULL; + else if(IsEqualGUID(&IID_IOleInPlaceSiteWindowless, riid)) + *ppv = ipsw ? &InPlaceSiteWindowless : NULL; else if(IsEqualGUID(&IID_IOleControlSite, riid)) *ppv = &OleControlSite; else if(IsEqualGUID(&IID_IDocHostShowUI, riid)) @@ -2889,6 +3064,7 @@ static void test_Load(IPersistMoniker *persist, IMoniker *mon) #define DWL_CSS 0x0002 #define DWL_TRYCSS 0x0004 #define DWL_HTTP 0x0008 +#define DWL_EMPTY 0x0010 static void test_download(DWORD flags) { @@ -2905,7 +3081,8 @@ static void test_download(DWORD flags) if((flags & DWL_VERBDONE) && !load_from_stream) SET_EXPECT(GetHostInfo); SET_EXPECT(SetStatusText); - SET_EXPECT(Exec_SETDOWNLOADSTATE_1); + if(!(flags & DWL_EMPTY)) + SET_EXPECT(Exec_SETDOWNLOADSTATE_1); SET_EXPECT(GetDropTarget); if(flags & DWL_TRYCSS) SET_EXPECT(Exec_ShellDocView_84); @@ -2930,7 +3107,8 @@ static void test_download(DWORD flags) SET_EXPECT(OnChanged_1005); SET_EXPECT(OnChanged_READYSTATE); SET_EXPECT(Exec_SETPROGRESSPOS); - SET_EXPECT(Exec_SETDOWNLOADSTATE_0); + if(!(flags & DWL_EMPTY)) + SET_EXPECT(Exec_SETDOWNLOADSTATE_0); SET_EXPECT(Exec_ShellDocView_103); SET_EXPECT(Exec_ShellDocView_105); SET_EXPECT(Exec_ShellDocView_140); @@ -2951,7 +3129,8 @@ static void test_download(DWORD flags) if((flags & DWL_VERBDONE) && !load_from_stream) CHECK_CALLED(GetHostInfo); CHECK_CALLED(SetStatusText); - CHECK_CALLED(Exec_SETDOWNLOADSTATE_1); + if(!(flags & DWL_EMPTY)) + CHECK_CALLED(Exec_SETDOWNLOADSTATE_1); CHECK_CALLED(GetDropTarget); if(flags & DWL_TRYCSS) SET_CALLED(Exec_ShellDocView_84); @@ -2976,7 +3155,8 @@ static void test_download(DWORD flags) CHECK_CALLED(OnChanged_1005); CHECK_CALLED(OnChanged_READYSTATE); CHECK_CALLED(Exec_SETPROGRESSPOS); - CHECK_CALLED(Exec_SETDOWNLOADSTATE_0); + if(!(flags & DWL_EMPTY)) + CHECK_CALLED(Exec_SETDOWNLOADSTATE_0); SET_CALLED(Exec_ShellDocView_103); SET_CALLED(Exec_ShellDocView_105); SET_CALLED(Exec_ShellDocView_140); @@ -3625,6 +3805,54 @@ static void test_Close(IUnknown *unk, BOOL set_client) IOleObject_Release(oleobj); } +static void test_Advise(IUnknown *unk) +{ + IOleObject *oleobj = NULL; + IEnumSTATDATA *enum_advise = (void*)0xdeadbeef; + DWORD conn; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); + ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IOleObject_Unadvise(oleobj, 0); + ok(hres == OLE_E_NOCONNECTION, "Unadvise returned: %08x\n", hres); + + hres = IOleObject_EnumAdvise(oleobj, &enum_advise); + ok(hres == S_OK, "EnumAdvise returned: %08x\n", hres); + ok(enum_advise == NULL, "enum_advise != NULL\n"); + + conn = -1; + hres = IOleObject_Advise(oleobj, NULL, &conn); + /* Old IE returns S_OK and sets conn to 1 */ + ok(hres == E_INVALIDARG || hres == S_OK, "Advise returned: %08x\n", hres); + ok(conn == 0 || conn == 1, "conn = %d\n", conn); + + hres = IOleObject_Advise(oleobj, &AdviseSink, NULL); + ok(hres == E_INVALIDARG, "Advise returned: %08x\n", hres); + + hres = IOleObject_Advise(oleobj, &AdviseSink, &conn); + ok(hres == S_OK, "Advise returned: %08x\n", hres); + ok(conn == 1, "conn = %d\n", conn); + + hres = IOleObject_Advise(oleobj, &AdviseSink, &conn); + ok(hres == S_OK, "Advise returned: %08x\n", hres); + ok(conn == 2, "conn = %d\n", conn); + + hres = IOleObject_Unadvise(oleobj, 1); + ok(hres == S_OK, "Unadvise returned: %08x\n", hres); + + hres = IOleObject_Unadvise(oleobj, 1); + ok(hres == OLE_E_NOCONNECTION, "Unadvise returned: %08x\n", hres); + + hres = IOleObject_Unadvise(oleobj, 2); + ok(hres == S_OK, "Unadvise returned: %08x\n", hres); + + IOleObject_Release(oleobj); +} + static void test_OnFrameWindowActivate(IUnknown *unk) { IOleInPlaceActiveObject *inplaceact; @@ -3940,6 +4168,36 @@ static void test_StreamLoad(IUnknown *unk) IPersistStreamInit_Release(init); } +static void test_StreamInitNew(IUnknown *unk) +{ + IPersistStreamInit *init; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IPersistStreamInit, (void**)&init); + ok(hres == S_OK, "QueryInterface(IID_IPersistStreamInit) failed: %08x\n", hres); + if(FAILED(hres)) + return; + + SET_EXPECT(Invoke_AMBIENT_SILENT); + SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); + SET_EXPECT(Exec_ShellDocView_37); + SET_EXPECT(OnChanged_READYSTATE); + readystate_set_loading = TRUE; + + hres = IPersistStreamInit_InitNew(init); + ok(hres == S_OK, "Load failed: %08x\n", hres); + + CHECK_CALLED(Invoke_AMBIENT_SILENT); + CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); + CHECK_CALLED(Exec_ShellDocView_37); + CHECK_CALLED(OnChanged_READYSTATE); + + test_timer(EXPECT_SETTITLE); + test_GetCurMoniker(unk, NULL, about_blank_url); + + IPersistStreamInit_Release(init); +} + static void test_QueryInterface(IUnknown *unk) { IUnknown *qi; @@ -4009,6 +4267,7 @@ static void test_HTMLDocument(BOOL do_load) doc_unk = unk; test_QueryInterface(unk); + test_Advise(unk); test_IsDirty(unk, S_FALSE); test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); test_external(unk, FALSE); @@ -4253,6 +4512,7 @@ static void test_HTMLDocument_StreamLoad(void) { IOleObject *oleobj; IUnknown *unk; + DWORD conn; HRESULT hres; ULONG ref; @@ -4269,6 +4529,9 @@ static void test_HTMLDocument_StreamLoad(void) hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres); + hres = IOleObject_Advise(oleobj, &AdviseSink, &conn); + ok(hres == S_OK, "Advise failed: %08x\n", hres); + test_readyState(unk); test_IsDirty(unk, S_FALSE); test_ConnectionPointContainer(unk); @@ -4285,7 +4548,64 @@ static void test_HTMLDocument_StreamLoad(void) test_UIDeactivate(); test_InPlaceDeactivate(unk, TRUE); + SET_EXPECT(Advise_Close); test_Close(unk, FALSE); + CHECK_CALLED(Advise_Close); + test_IsDirty(unk, S_FALSE); + + if(view) { + IOleDocumentView_Release(view); + view = NULL; + } + + + ref = IUnknown_Release(unk); + ok(ref == 0, "ref=%d, expected 0\n", ref); +} + +static void test_HTMLDocument_StreamInitNew(void) +{ + IOleObject *oleobj; + IUnknown *unk; + DWORD conn; + HRESULT hres; + ULONG ref; + + trace("Testing HTMLDocument (IPersistStreamInit)...\n"); + + init_test(LD_DOLOAD); + load_from_stream = TRUE; + + hres = create_document(&unk); + if(FAILED(hres)) + return; + doc_unk = unk; + + hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); + ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres); + + hres = IOleObject_Advise(oleobj, &AdviseSink, &conn); + ok(hres == S_OK, "Advise failed: %08x\n", hres); + + test_readyState(unk); + test_IsDirty(unk, S_FALSE); + test_ConnectionPointContainer(unk); + test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH); + test_DoVerb(oleobj); + test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); + + IOleObject_Release(oleobj); + + test_GetCurMoniker(unk, NULL, NULL); + test_StreamInitNew(unk); + test_download(DWL_VERBDONE|DWL_TRYCSS|DWL_EMPTY); + test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); + + test_UIDeactivate(); + test_InPlaceDeactivate(unk, TRUE); + SET_EXPECT(Advise_Close); + test_Close(unk, FALSE); + CHECK_CALLED(Advise_Close); test_IsDirty(unk, S_FALSE); if(view) { @@ -4329,6 +4649,7 @@ static void test_editing_mode(BOOL do_load) { IUnknown *unk; IOleObject *oleobj; + DWORD conn; HRESULT hres; ULONG ref; @@ -4345,6 +4666,9 @@ static void test_editing_mode(BOOL do_load) hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres); + hres = IOleObject_Advise(oleobj, &AdviseSink, &conn); + ok(hres == S_OK, "Advise failed: %08x\n", hres); + test_readyState(unk); test_ConnectionPointContainer(unk); test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH); @@ -4395,7 +4719,9 @@ static void test_editing_mode(BOOL do_load) test_UIDeactivate(); test_InPlaceDeactivate(unk, TRUE); + SET_EXPECT(Advise_Close); test_Close(unk, FALSE); + CHECK_CALLED(Advise_Close); if(view) { IOleDocumentView_Release(view); @@ -4406,6 +4732,156 @@ static void test_editing_mode(BOOL do_load) ok(ref == 0, "ref=%d, expected 0\n", ref); } +void test_UIActivate(BOOL do_load, BOOL use_ipsex, BOOL use_ipsw) +{ + IUnknown *unk; + IOleObject *oleobj; + IOleInPlaceSite *inplacesite; + HRESULT hres; + ULONG ref; + + trace("Running OleDocumentView_UIActivate tests (%d %d %d)\n", do_load, use_ipsex, use_ipsw); + + init_test(do_load ? LD_DOLOAD : LD_NO); + + hres = create_document(&unk); + if(FAILED(hres)) + return; + doc_unk = unk; + + ipsex = use_ipsex; + ipsw = use_ipsw; + + hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); + ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres); + + hres = IUnknown_QueryInterface(unk, &IID_IOleDocumentView, (void**)&view); + ok(hres == S_OK, "QueryInterface(IID_IOleDocumentView) failed: %08x\n", hres); + + SET_EXPECT(Invoke_AMBIENT_USERMODE); + SET_EXPECT(GetHostInfo); + SET_EXPECT(Invoke_AMBIENT_DLCONTROL); + SET_EXPECT(Invoke_AMBIENT_SILENT); + SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); + SET_EXPECT(Invoke_AMBIENT_USERAGENT); + SET_EXPECT(Invoke_AMBIENT_PALETTE); + SET_EXPECT(GetOptionKeyPath); + SET_EXPECT(GetOverrideKeyPath); + SET_EXPECT(GetWindow); + SET_EXPECT(QueryStatus_SETPROGRESSTEXT); + SET_EXPECT(Exec_SETPROGRESSMAX); + SET_EXPECT(Exec_SETPROGRESSPOS); + + hres = IOleObject_SetClientSite(oleobj, &ClientSite); + ok(hres == S_OK, "SetClientSite failed: %08x\n", hres); + + CHECK_CALLED(Invoke_AMBIENT_USERMODE); + CHECK_CALLED(GetHostInfo); + CHECK_CALLED(Invoke_AMBIENT_DLCONTROL); + CHECK_CALLED(Invoke_AMBIENT_SILENT); + CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); + CHECK_CALLED(Invoke_AMBIENT_USERAGENT); + CHECK_CALLED(Invoke_AMBIENT_PALETTE); + CHECK_CALLED(GetOptionKeyPath); + CHECK_CALLED(GetOverrideKeyPath); + CHECK_CALLED(GetWindow); + CHECK_CALLED(QueryStatus_SETPROGRESSTEXT); + CHECK_CALLED(Exec_SETPROGRESSMAX); + CHECK_CALLED(Exec_SETPROGRESSPOS); + + hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite); + ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres); + ok(inplacesite == NULL, "inplacesite = %p, expected NULL\n", inplacesite); + + SET_EXPECT(GetContainer); + SET_EXPECT(LockContainer); + SET_EXPECT(CanInPlaceActivate); + SET_EXPECT(GetWindowContext); + SET_EXPECT(GetWindow); + if(use_ipsex) { + SET_EXPECT(OnInPlaceActivateEx); + SET_EXPECT(RequestUIActivate); + } + else + SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(OnUIActivate); + SET_EXPECT(SetStatusText); + SET_EXPECT(Exec_SETPROGRESSMAX); + SET_EXPECT(Exec_SETPROGRESSPOS); + SET_EXPECT(ShowUI); + SET_EXPECT(InPlaceUIWindow_SetActiveObject); + SET_EXPECT(InPlaceFrame_SetBorderSpace); + SET_EXPECT(OnFocus_TRUE); + SET_EXPECT(SetActiveObject); + expect_LockContainer_fLock = TRUE; + + hres = IOleDocumentView_UIActivate(view, TRUE); + ok(hres == S_OK, "UIActivate failed: %08x\n", hres); + + CHECK_CALLED(GetContainer); + CHECK_CALLED(LockContainer); + CHECK_CALLED(CanInPlaceActivate); + CHECK_CALLED(GetWindowContext); + CHECK_CALLED(GetWindow); + if(use_ipsex) { + CHECK_CALLED(OnInPlaceActivateEx); + SET_EXPECT(RequestUIActivate); + } + else + CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(OnUIActivate); + CHECK_CALLED(SetStatusText); + CHECK_CALLED(Exec_SETPROGRESSMAX); + CHECK_CALLED(Exec_SETPROGRESSPOS); + CHECK_CALLED(ShowUI); + CHECK_CALLED(InPlaceUIWindow_SetActiveObject); + CHECK_CALLED(InPlaceFrame_SetBorderSpace); + CHECK_CALLED(OnFocus_TRUE); + CHECK_CALLED(SetActiveObject); + container_locked = TRUE; + + SET_EXPECT(SetActiveObject_null); + SET_EXPECT(InPlaceUIWindow_SetActiveObject); + SET_EXPECT(HideUI); + SET_EXPECT(OnUIDeactivate); + + hres = IOleDocumentView_UIActivate(view, FALSE); + ok(hres == S_OK, "UIActivate failed: %08x\n", hres); + + CHECK_CALLED(SetActiveObject_null); + CHECK_CALLED(InPlaceUIWindow_SetActiveObject); + CHECK_CALLED(HideUI); + CHECK_CALLED(OnUIDeactivate); + + hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite); + ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres); + ok(inplacesite != NULL, "inplacesite = NULL\n"); + IOleInPlaceSite_Release(inplacesite); + + SET_EXPECT(OnFocus_FALSE); + if(use_ipsex) + SET_EXPECT(OnInPlaceDeactivateEx); + else + SET_EXPECT(OnInPlaceDeactivate); + + test_CloseView(); + + CHECK_CALLED(OnFocus_FALSE); + if(use_ipsex) + CHECK_CALLED(OnInPlaceDeactivateEx); + else + CHECK_CALLED(OnInPlaceDeactivate); + + test_Close(unk, TRUE); + + IOleObject_Release(oleobj); + IOleDocumentView_Release(view); + view = NULL; + + ref = IUnknown_Release(unk); + ok(ref == 0, "ref=%d, expected 0\n", ref); +} + static void register_protocol(void) { IInternetSession *session; @@ -4479,9 +4955,16 @@ START_TEST(htmldoc) test_HTMLDocument(FALSE); test_HTMLDocument(TRUE); test_HTMLDocument_StreamLoad(); + test_HTMLDocument_StreamInitNew(); test_editing_mode(FALSE); test_editing_mode(TRUE); test_HTMLDocument_http(); + test_UIActivate(FALSE, FALSE, FALSE); + test_UIActivate(FALSE, TRUE, FALSE); + test_UIActivate(FALSE, TRUE, TRUE); + test_UIActivate(TRUE, FALSE, FALSE); + test_UIActivate(TRUE, TRUE, FALSE); + test_UIActivate(TRUE, TRUE, TRUE); } test_HTMLDoc_ISupportErrorInfo(); test_IPersistHistory(); diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 22ed48e420f..d8dce6af3a6 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -115,6 +115,7 @@ DEFINE_EXPECT(funcDisp); DEFINE_EXPECT(script_divid_d); DEFINE_EXPECT(script_testprop_d); DEFINE_EXPECT(script_testprop_i); +DEFINE_EXPECT(script_testprop2_d); DEFINE_EXPECT(AXQueryInterface_IActiveScript); DEFINE_EXPECT(AXQueryInterface_IObjectSafety); DEFINE_EXPECT(AXGetInterfaceSafetyOptions); @@ -124,6 +125,7 @@ DEFINE_EXPECT(AXSetInterfaceSafetyOptions); #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}" #define DISPID_SCRIPT_TESTPROP 0x100000 +#define DISPID_SCRIPT_TESTPROP2 0x100001 static const GUID CLSID_TestScript = {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}}; @@ -394,6 +396,13 @@ static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW return S_OK; } + if(!strcmp_wa(bstrName, "testProp2")) { + CHECK_EXPECT(script_testprop2_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_SCRIPT_TESTPROP2; + return S_OK; + } + if(!strcmp_wa(bstrName, "divid")) { CHECK_EXPECT(script_divid_d); ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); @@ -1212,6 +1221,16 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac CHECK_CALLED(GetScriptDispatch); CHECK_CALLED(script_testprop_i); + SET_EXPECT(GetScriptDispatch); + SET_EXPECT(script_testprop2_d); + tmp = a2bstr("testProp2"); + hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + ok(id != DISPID_SCRIPT_TESTPROP2, "id == DISPID_SCRIPT_TESTPROP2\n"); + CHECK_CALLED(GetScriptDispatch); + CHECK_CALLED(script_testprop2_d); + SysFreeString(tmp); + test_global_id(); test_security(); diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index 0d1d0552823..271a1675107 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -342,6 +342,14 @@ static HRESULT activate_window(HTMLDocumentObj *This) IOleInPlaceFrame_Release(This->frame); This->frame = pIPFrame; + if(!This->request_uiactivate) { + hres = IOleInPlaceSite_QueryInterface(This->ipsite, &IID_IOleInPlaceSiteEx, (void**)&ipsiteex); + if(SUCCEEDED(hres)) { + IOleInPlaceSiteEx_RequestUIActivate(ipsiteex); + IOleInPlaceSiteEx_Release(ipsiteex); + } + } + This->window_active = TRUE; return S_OK; @@ -466,6 +474,7 @@ static HRESULT WINAPI OleDocumentView_SetInPlaceSite(IOleDocumentView *iface, IO IOleInPlaceSite_Release(This->doc_obj->ipsite); This->doc_obj->ipsite = pIPSite; + This->doc_obj->request_uiactivate = TRUE; return S_OK; } @@ -557,6 +566,10 @@ static HRESULT WINAPI OleDocumentView_Show(IOleDocumentView *iface, BOOL fShow) ShowWindow(This->doc_obj->hwnd, SW_SHOW); }else { ShowWindow(This->doc_obj->hwnd, SW_HIDE); + + if(This->doc_obj->in_place_active) + IOleInPlaceObjectWindowless_InPlaceDeactivate(INPLACEWIN(This)); + if(This->doc_obj->ip_window) { IOleInPlaceUIWindow_Release(This->doc_obj->ip_window); This->doc_obj->ip_window = NULL; @@ -574,8 +587,35 @@ static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL f TRACE("(%p)->(%x)\n", This, fUIActivate); if(!This->doc_obj->ipsite) { - FIXME("This->ipsite = NULL\n"); - return E_FAIL; + IOleClientSite *cs = This->doc_obj->client; + IOleInPlaceSite *ips; + + if(!cs) { + WARN("this->ipsite = NULL\n"); + return E_UNEXPECTED; + } + + hres = IOleClientSite_QueryInterface(cs, &IID_IOleInPlaceSiteWindowless, (void**)&ips); + if(SUCCEEDED(hres)) + This->doc_obj->ipsite = ips; + else { + hres = IOleClientSite_QueryInterface(cs, &IID_IOleInPlaceSiteEx, (void**)&ips); + if(SUCCEEDED(hres)) + This->doc_obj->ipsite = ips; + else { + hres = IOleClientSite_QueryInterface(cs, &IID_IOleInPlaceSite, (void**)&ips); + if(SUCCEEDED(hres)) + This->doc_obj->ipsite = ips; + else { + WARN("this->ipsite = NULL\n"); + return E_NOINTERFACE; + } + } + } + + IOleClientSite_AddRef(This->doc_obj->ipsite); + This->doc_obj->request_uiactivate = FALSE; + HTMLDocument_LockContainer(This->doc_obj, TRUE); } if(fUIActivate) { diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 0755f428675..ef30dda2e0d 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -5288,6 +5288,11 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options) goto done; } + /* file->dest may be shorter after the reallocation, so add a NULL + * terminator. This is needed for the call to strrchrW, as there will no + * longer be a NULL terminator within the bounds of the allocation in this case. + */ + file->dest[size - 1] = '\0'; lstrcpyW(strrchrW(file->dest, '\\') + 1, file->destname); while (!list_empty(&files.entry)) diff --git a/dlls/msi/automation.c b/dlls/msi/automation.c index 3b6dd2debe2..3b403842152 100644 --- a/dlls/msi/automation.c +++ b/dlls/msi/automation.c @@ -1534,6 +1534,761 @@ static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYT } } +static HRESULT InstallerImpl_CreateRecord(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + HRESULT hr; + VARIANTARG varg0; + MSIHANDLE hrec; + IDispatch* dispatch; + + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + V_VT(pVarResult) = VT_DISPATCH; + + hrec = MsiCreateRecord(V_I4(&varg0)); + if (!hrec) + return DISP_E_EXCEPTION; + + hr = create_automation_object(hrec, NULL, (LPVOID*)&dispatch, + &DIID_Record, RecordImpl_Invoke, NULL, 0); + if (SUCCEEDED(hr)) + V_DISPATCH(pVarResult) = dispatch; + + return hr; +} + +static HRESULT InstallerImpl_OpenPackage(AutomationObject* This, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + HRESULT hr; + MSIHANDLE hpkg; + IDispatch* dispatch; + VARIANTARG varg0, varg1; + + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + if (pDispParams->cArgs == 0) + return DISP_E_TYPEMISMATCH; + + if (V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1]) != VT_BSTR) + return DISP_E_TYPEMISMATCH; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + VariantInit(&varg1); + if (pDispParams->cArgs == 2) + { + hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr); + if (FAILED(hr)) + goto done; + } + else + { + V_VT(&varg1) = VT_I4; + V_I4(&varg1) = 0; + } + + V_VT(pVarResult) = VT_DISPATCH; + + ret = MsiOpenPackageExW(V_BSTR(&varg0), V_I4(&varg1), &hpkg); + if (ret != ERROR_SUCCESS) + { + hr = DISP_E_EXCEPTION; + goto done; + } + + hr = create_session(hpkg, (IDispatch *)This, &dispatch); + if (SUCCEEDED(hr)) + V_DISPATCH(pVarResult) = dispatch; + +done: + VariantClear(&varg0); + VariantClear(&varg1); + return hr; +} + +static HRESULT InstallerImpl_OpenProduct(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + HRESULT hr; + VARIANTARG varg0; + + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + FIXME("%s\n", debugstr_w(V_BSTR(&varg0))); + + VariantInit(pVarResult); + + VariantClear(&varg0); + return S_OK; +} + +static HRESULT InstallerImpl_OpenDatabase(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + HRESULT hr; + MSIHANDLE hdb; + IDispatch* dispatch; + VARIANTARG varg0, varg1; + + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + VariantInit(&varg1); + hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); + if (FAILED(hr)) + goto done; + + V_VT(pVarResult) = VT_DISPATCH; + + ret = MsiOpenDatabaseW(V_BSTR(&varg0), V_BSTR(&varg1), &hdb); + if (ret != ERROR_SUCCESS) + { + hr = DISP_E_EXCEPTION; + goto done; + } + + hr = create_automation_object(hdb, NULL, (LPVOID *)&dispatch, + &DIID_Database, DatabaseImpl_Invoke, NULL, 0); + if (SUCCEEDED(hr)) + V_DISPATCH(pVarResult) = dispatch; + +done: + VariantClear(&varg0); + VariantClear(&varg1); + return hr; +} + +static HRESULT InstallerImpl_SummaryInformation(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_UILevel(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + HRESULT hr; + VARIANTARG varg0; + INSTALLUILEVEL ui; + + if (!(wFlags & DISPATCH_PROPERTYPUT) && !(wFlags & DISPATCH_PROPERTYGET)) + return DISP_E_MEMBERNOTFOUND; + + if (wFlags & DISPATCH_PROPERTYPUT) + { + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + ui = MsiSetInternalUI(V_I4(&varg0), NULL); + if (ui == INSTALLUILEVEL_NOCHANGE) + return DISP_E_EXCEPTION; + } + else if (wFlags & DISPATCH_PROPERTYGET) + { + ui = MsiSetInternalUI(INSTALLUILEVEL_NOCHANGE, NULL); + if (ui == INSTALLUILEVEL_NOCHANGE) + return DISP_E_EXCEPTION; + + V_VT(pVarResult) = VT_I4; + V_I4(pVarResult) = ui; + } + + return S_OK; +} + +static HRESULT InstallerImpl_EnableLog(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_InstallProduct(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + HRESULT hr; + VARIANTARG varg0, varg1; + + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + VariantInit(&varg1); + hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); + if (FAILED(hr)) + goto done; + + ret = MsiInstallProductW(V_BSTR(&varg0), V_BSTR(&varg1)); + if (ret != ERROR_SUCCESS) + { + hr = DISP_E_EXCEPTION; + goto done; + } + +done: + VariantClear(&varg0); + VariantClear(&varg1); + return hr; +} + +static HRESULT InstallerImpl_Version(WORD wFlags, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + HRESULT hr; + DLLVERSIONINFO verinfo; + WCHAR version[MAX_PATH]; + + static const WCHAR format[] = { + '%','d','.','%','d','.','%','d','.','%','d',0}; + + if (!(wFlags & DISPATCH_PROPERTYGET)) + return DISP_E_MEMBERNOTFOUND; + + verinfo.cbSize = sizeof(DLLVERSIONINFO); + hr = DllGetVersion(&verinfo); + if (FAILED(hr)) + return hr; + + sprintfW(version, format, verinfo.dwMajorVersion, verinfo.dwMinorVersion, + verinfo.dwBuildNumber, verinfo.dwPlatformID); + + V_VT(pVarResult) = VT_BSTR; + V_BSTR(pVarResult) = SysAllocString(version); + return S_OK; +} + +static HRESULT InstallerImpl_LastErrorRecord(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_RegistryValue(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + HKEY hkey = NULL; + HRESULT hr; + UINT posValue; + DWORD type, size; + LPWSTR szString = NULL; + VARIANTARG varg0, varg1, varg2; + + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + VariantInit(&varg1); + hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); + if (FAILED(hr)) + goto done; + + /* Save valuePos so we can save puArgErr if we are unable to do our type + * conversions. + */ + posValue = 2; + VariantInit(&varg2); + hr = DispGetParam_CopyOnly(pDispParams, &posValue, &varg2); + if (FAILED(hr)) + goto done; + + if (V_I4(&varg0) >= REG_INDEX_CLASSES_ROOT && + V_I4(&varg0) <= REG_INDEX_DYN_DATA) + { + V_I4(&varg0) |= (UINT_PTR)HKEY_CLASSES_ROOT; + } + + ret = RegOpenKeyW((HKEY)(UINT_PTR)V_I4(&varg0), V_BSTR(&varg1), &hkey); + + /* Only VT_EMPTY case can do anything if the key doesn't exist. */ + if (ret != ERROR_SUCCESS && V_VT(&varg2) != VT_EMPTY) + { + hr = DISP_E_BADINDEX; + goto done; + } + + /* Third parameter can be VT_EMPTY, VT_I4, or VT_BSTR */ + switch (V_VT(&varg2)) + { + /* Return VT_BOOL clarifying whether registry key exists or not. */ + case VT_EMPTY: + V_VT(pVarResult) = VT_BOOL; + V_BOOL(pVarResult) = (ret == ERROR_SUCCESS); + break; + + /* Return the value of specified key if it exists. */ + case VT_BSTR: + ret = RegQueryValueExW(hkey, V_BSTR(&varg2), + NULL, NULL, NULL, &size); + if (ret != ERROR_SUCCESS) + { + hr = DISP_E_BADINDEX; + goto done; + } + + szString = msi_alloc(size); + if (!szString) + { + hr = E_OUTOFMEMORY; + goto done; + } + + ret = RegQueryValueExW(hkey, V_BSTR(&varg2), NULL, + &type, (LPBYTE)szString, &size); + if (ret != ERROR_SUCCESS) + { + msi_free(szString); + hr = DISP_E_BADINDEX; + goto done; + } + + variant_from_registry_value(pVarResult, type, + (LPBYTE)szString, size); + msi_free(szString); + break; + + /* Try to make it into VT_I4, can use VariantChangeType for this. */ + default: + hr = VariantChangeType(&varg2, &varg2, 0, VT_I4); + if (FAILED(hr)) + { + if (hr == DISP_E_TYPEMISMATCH) + *puArgErr = posValue; + + goto done; + } + + /* Retrieve class name or maximum value name or subkey name size. */ + if (!V_I4(&varg2)) + ret = RegQueryInfoKeyW(hkey, NULL, &size, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL); + else if (V_I4(&varg2) > 0) + ret = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &size, NULL, NULL, NULL); + else /* V_I4(&varg2) < 0 */ + ret = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, &size, + NULL, NULL, NULL, NULL, NULL, NULL); + + if (ret != ERROR_SUCCESS) + goto done; + + szString = msi_alloc(++size * sizeof(WCHAR)); + if (!szString) + { + hr = E_OUTOFMEMORY; + goto done; + } + + if (!V_I4(&varg2)) + ret = RegQueryInfoKeyW(hkey, szString, &size,NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL); + else if (V_I4(&varg2) > 0) + ret = RegEnumValueW(hkey, V_I4(&varg2)-1, szString, + &size, 0, 0, NULL, NULL); + else /* V_I4(&varg2) < 0 */ + ret = RegEnumKeyW(hkey, -1 - V_I4(&varg2), szString, size); + + if (ret == ERROR_SUCCESS) + { + V_VT(pVarResult) = VT_BSTR; + V_BSTR(pVarResult) = SysAllocString(szString); + } + + msi_free(szString); + } + +done: + VariantClear(&varg0); + VariantClear(&varg1); + VariantClear(&varg2); + RegCloseKey(hkey); + return hr; +} + +static HRESULT InstallerImpl_Environment(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_FileAttributes(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_FileSize(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_FileVersion(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + if (!(wFlags & DISPATCH_METHOD)) + return DISP_E_MEMBERNOTFOUND; + + FIXME("\n"); + + VariantInit(pVarResult); + return S_OK; +} + +static HRESULT InstallerImpl_ProductState(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + HRESULT hr; + VARIANTARG varg0; + + if (!(wFlags & DISPATCH_PROPERTYGET)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + V_VT(pVarResult) = VT_I4; + V_I4(pVarResult) = MsiQueryProductStateW(V_BSTR(&varg0)); + + VariantClear(&varg0); + return S_OK; +} + +static HRESULT InstallerImpl_ProductInfo(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + HRESULT hr; + DWORD size; + LPWSTR str; + VARIANTARG varg0, varg1; + + if (!(wFlags & DISPATCH_PROPERTYGET)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + VariantInit(&varg1); + hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); + if (FAILED(hr)) + goto done; + + V_VT(pVarResult) = VT_BSTR; + V_BSTR(pVarResult) = NULL; + + ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), NULL, &size); + if (ret != ERROR_SUCCESS) + { + hr = DISP_E_EXCEPTION; + goto done; + } + + str = msi_alloc(++size * sizeof(WCHAR)); + if (!str) + { + hr = E_OUTOFMEMORY; + goto done; + } + + ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), str, &size); + msi_free(str); + + if (ret != ERROR_SUCCESS) + { + hr = DISP_E_EXCEPTION; + goto done; + } + + V_BSTR(pVarResult) = SysAllocString(str); + hr = S_OK; + +done: + VariantClear(&varg0); + VariantClear(&varg1); + return hr; +} + +static void cleanup_products(IDispatch* dispatch, ULONG count) +{ + UINT i; + ListData* ldata = private_data((AutomationObject *)dispatch); + + for (i = 0; i < count - 1; i++) + VariantClear(&ldata->pVars[i]); + + ldata->ulCount = 0; + msi_free(ldata->pVars); + + IDispatch_Release(dispatch); +} + +static HRESULT InstallerImpl_Products(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + HRESULT hr; + ULONG idx = 0; + ListData *ldata; + IDispatch *dispatch; + WCHAR product[GUID_SIZE]; + + if (!(wFlags & DISPATCH_PROPERTYGET)) + return DISP_E_MEMBERNOTFOUND; + + /* Find number of products. */ + while ((ret = MsiEnumProductsW(idx, product)) == ERROR_SUCCESS) + idx++; + + if (ret != ERROR_NO_MORE_ITEMS) + return DISP_E_EXCEPTION; + + V_VT(pVarResult) = VT_DISPATCH; + hr = create_automation_object(0, NULL, (LPVOID*)&dispatch, + &DIID_StringList, ListImpl_Invoke, + ListImpl_Free, sizeof(ListData)); + if (FAILED(hr)) + return hr; + + V_DISPATCH(pVarResult) = dispatch; + + /* Save product strings. */ + ldata = private_data((AutomationObject *)dispatch); + ldata->ulCount = 0; + ldata->pVars = msi_alloc_zero(sizeof(VARIANT) * idx); + if (!ldata->pVars) + { + IDispatch_Release(dispatch); + return E_OUTOFMEMORY; + } + + ldata->ulCount = idx; + for (idx = 0; idx < ldata->ulCount; idx++) + { + ret = MsiEnumProductsW(idx, product); + if (ret != ERROR_SUCCESS) + { + cleanup_products(dispatch, idx - 1); + return DISP_E_EXCEPTION; + } + + VariantInit(&ldata->pVars[idx]); + V_VT(&ldata->pVars[idx]) = VT_BSTR; + V_BSTR(&ldata->pVars[idx]) = SysAllocString(product); + } + + return S_OK; +} + +static HRESULT InstallerImpl_RelatedProducts(WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + UINT ret; + ULONG idx; + HRESULT hr; + ListData *ldata; + VARIANTARG varg0; + IDispatch* dispatch; + WCHAR product[GUID_SIZE]; + + if (!(wFlags & DISPATCH_PROPERTYGET)) + return DISP_E_MEMBERNOTFOUND; + + VariantInit(&varg0); + hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); + if (FAILED(hr)) + return hr; + + /* Find number of related products. */ + idx = 0; + do + { + ret = MsiEnumRelatedProductsW(V_BSTR(&varg0), 0, idx, product); + if (ret == ERROR_SUCCESS) + idx++; + } while (ret == ERROR_SUCCESS); + + if (ret != ERROR_NO_MORE_ITEMS) + { + hr = DISP_E_EXCEPTION; + goto done; + } + + V_VT(pVarResult) = VT_DISPATCH; + + hr = create_automation_object(0, NULL, (LPVOID*)&dispatch, + &DIID_StringList, ListImpl_Invoke, + ListImpl_Free, sizeof(ListData)); + if (FAILED(hr)) + goto done; + + V_DISPATCH(pVarResult) = dispatch; + + /* Save product strings. */ + ldata = private_data((AutomationObject *)dispatch); + ldata->pVars = msi_alloc(sizeof(VARIANT) * idx); + if (!ldata->pVars) + { + IDispatch_Release(dispatch); + hr = E_OUTOFMEMORY; + goto done; + } + + ldata->ulCount = idx; + for (idx = 0; idx < ldata->ulCount; idx++) + { + ret = MsiEnumRelatedProductsW(V_BSTR(&varg0), 0, idx, product); + if (ret != ERROR_SUCCESS) + { + cleanup_products(dispatch, idx - 1); + hr = DISP_E_EXCEPTION; + goto done; + } + + VariantInit(&ldata->pVars[idx]); + V_VT(&ldata->pVars[idx]) = VT_BSTR; + V_BSTR(&ldata->pVars[idx]) = SysAllocString(product); + } + + hr = S_OK; + +done: + VariantClear(&varg0); + return hr; +} + static HRESULT WINAPI InstallerImpl_Invoke( AutomationObject* This, DISPID dispIdMember, @@ -1545,405 +2300,93 @@ static HRESULT WINAPI InstallerImpl_Invoke( EXCEPINFO* pExcepInfo, UINT* puArgErr) { - MSIHANDLE msiHandle; - IDispatch *pDispatch = NULL; - UINT ret; - VARIANTARG varg0, varg1, varg2; - HRESULT hr; - LPWSTR szString = NULL; - DWORD dwSize = 0; - INSTALLUILEVEL ui; - - VariantInit(&varg0); - VariantInit(&varg1); - VariantInit(&varg2); - switch (dispIdMember) { case DISPID_INSTALLER_CREATERECORD: - if (wFlags & DISPATCH_METHOD) - { - hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); - if (FAILED(hr)) return hr; - V_VT(pVarResult) = VT_DISPATCH; - if ((msiHandle = MsiCreateRecord(V_I4(&varg0)))) - { - if (SUCCEEDED(hr = create_automation_object(msiHandle, NULL, (LPVOID*)&pDispatch, &DIID_Record, RecordImpl_Invoke, NULL, 0))) - V_DISPATCH(pVarResult) = pDispatch; - else - ERR("Failed to create Record object, hresult 0x%08x\n", hr); - } - else - { - ERR("MsiCreateRecord failed\n"); - return DISP_E_EXCEPTION; - } - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_CreateRecord(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); case DISPID_INSTALLER_OPENPACKAGE: - if (wFlags & DISPATCH_METHOD) - { - hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); - if (FAILED(hr)) return hr; - hr = DispGetParam(pDispParams, 1, VT_I4, &varg1, puArgErr); - if (FAILED(hr)) - { - VariantClear(&varg0); - return hr; - } - V_VT(pVarResult) = VT_DISPATCH; - if ((ret = MsiOpenPackageExW(V_BSTR(&varg0), V_I4(&varg1), &msiHandle)) == ERROR_SUCCESS) - { - if (SUCCEEDED(hr = create_session(msiHandle, (IDispatch *)This, &pDispatch))) - V_DISPATCH(pVarResult) = pDispatch; - else - ERR("Failed to create Session object, hresult 0x%08x\n", hr); - } - else - { - VariantClear(&varg0); - ERR("MsiOpenPackageEx returned %d\n", ret); - return DISP_E_EXCEPTION; - } - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_OpenPackage(This, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); - case DISPID_INSTALLER_OPENDATABASE: - if (wFlags & DISPATCH_METHOD) - { - hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); - if (FAILED(hr)) return hr; + case DISPID_INSTALLER_OPENPRODUCT: + return InstallerImpl_OpenProduct(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); - hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); - if (FAILED(hr)) - { - VariantClear(&varg0); - return hr; - } + case DISPID_INSTALLER_OPENDATABASE: + return InstallerImpl_OpenDatabase(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); - V_VT(pVarResult) = VT_DISPATCH; - if ((ret = MsiOpenDatabaseW(V_BSTR(&varg0), V_BSTR(&varg1), &msiHandle)) == ERROR_SUCCESS) - { - hr = create_automation_object(msiHandle, NULL, (LPVOID *)&pDispatch, - &DIID_Database, DatabaseImpl_Invoke, NULL, 0); - if (SUCCEEDED(hr)) - V_DISPATCH(pVarResult) = pDispatch; - else - ERR("Failed to create Database object: 0x%08x\n", hr); - } - else - { - VariantClear(&varg0); - VariantClear(&varg1); - ERR("MsiOpenDatabase returned %d\n", ret); - return DISP_E_EXCEPTION; - } - } - else return DISP_E_MEMBERNOTFOUND; - break; + case DISPID_INSTALLER_SUMMARYINFORMATION: + return InstallerImpl_SummaryInformation(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr); case DISPID_INSTALLER_UILEVEL: - if (wFlags & DISPATCH_PROPERTYPUT) - { - hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); - if (FAILED(hr)) return hr; - if ((ui = MsiSetInternalUI(V_I4(&varg0), NULL) == INSTALLUILEVEL_NOCHANGE)) - { - ERR("MsiSetInternalUI failed\n"); - return DISP_E_EXCEPTION; - } - } - else if (wFlags & DISPATCH_PROPERTYGET) - { - if ((ui = MsiSetInternalUI(INSTALLUILEVEL_NOCHANGE, NULL) == INSTALLUILEVEL_NOCHANGE)) - { - ERR("MsiSetInternalUI failed\n"); - return DISP_E_EXCEPTION; - } + return InstallerImpl_UILevel(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); - V_VT(pVarResult) = VT_I4; - V_I4(pVarResult) = ui; - } - else return DISP_E_MEMBERNOTFOUND; - break; + case DISPID_INSTALLER_ENABLELOG: + return InstallerImpl_EnableLog(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); case DISPID_INSTALLER_INSTALLPRODUCT: - if (wFlags & DISPATCH_METHOD) - { - hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); - if (FAILED(hr)) return hr; - hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); - if (FAILED(hr)) - { - VariantClear(&varg0); - return hr; - } - if ((ret = MsiInstallProductW(V_BSTR(&varg0), V_BSTR(&varg1))) != ERROR_SUCCESS) - { - VariantClear(&varg1); - VariantClear(&varg0); - ERR("MsiInstallProduct returned %d\n", ret); - return DISP_E_EXCEPTION; - } - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_InstallProduct(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr); case DISPID_INSTALLER_VERSION: - if (wFlags & DISPATCH_PROPERTYGET) { - DLLVERSIONINFO verinfo; - WCHAR version[MAX_PATH]; + return InstallerImpl_Version(wFlags, pVarResult, + pExcepInfo, puArgErr); - static const WCHAR format[] = {'%','d','.','%','d','.','%','d','.','%','d',0}; - - verinfo.cbSize = sizeof(DLLVERSIONINFO); - hr = DllGetVersion(&verinfo); - if (FAILED(hr)) return hr; - - sprintfW(version, format, verinfo.dwMajorVersion, verinfo.dwMinorVersion, - verinfo.dwBuildNumber, verinfo.dwPlatformID); - - V_VT(pVarResult) = VT_BSTR; - V_BSTR(pVarResult) = SysAllocString(version); - } - else return DISP_E_MEMBERNOTFOUND; - break; + case DISPID_INSTALLER_LASTERRORRECORD: + return InstallerImpl_LastErrorRecord(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr); case DISPID_INSTALLER_REGISTRYVALUE: - if (wFlags & DISPATCH_METHOD) { - HKEY hkey; - DWORD dwType; - UINT posValue = 2; /* Save valuePos so we can save puArgErr if we are unable to do our type conversions */ - - hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr); - if (FAILED(hr)) return hr; - hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); - if (FAILED(hr)) return hr; - hr = DispGetParam_CopyOnly(pDispParams, &posValue, &varg2); - if (FAILED(hr)) - { - VariantClear(&varg1); - return hr; - } - - if (V_I4(&varg0) >= REG_INDEX_CLASSES_ROOT && - V_I4(&varg0) <= REG_INDEX_DYN_DATA) - V_I4(&varg0) |= (UINT_PTR)HKEY_CLASSES_ROOT; - - ret = RegOpenKeyW((HKEY)(UINT_PTR)V_I4(&varg0), V_BSTR(&varg1), &hkey); - - /* Third parameter can be VT_EMPTY, VT_I4, or VT_BSTR */ - switch (V_VT(&varg2)) - { - case VT_EMPTY: /* Return VT_BOOL as to whether or not registry key exists */ - V_VT(pVarResult) = VT_BOOL; - V_BOOL(pVarResult) = (ret == ERROR_SUCCESS); - break; - - case VT_BSTR: /* Return value of specified key if it exists */ - if (ret == ERROR_SUCCESS && - (ret = RegQueryValueExW(hkey, V_BSTR(&varg2), NULL, NULL, NULL, &dwSize)) == ERROR_SUCCESS) - { - if (!(szString = msi_alloc(dwSize))) - ERR("Out of memory\n"); - else if ((ret = RegQueryValueExW(hkey, V_BSTR(&varg2), NULL, &dwType, (LPBYTE)szString, &dwSize)) == ERROR_SUCCESS) - variant_from_registry_value(pVarResult, dwType, (LPBYTE)szString, dwSize); - } - - if (ret != ERROR_SUCCESS) - { - msi_free(szString); - VariantClear(&varg2); - VariantClear(&varg1); - return DISP_E_BADINDEX; - } - break; + return InstallerImpl_RegistryValue(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr); - default: /* Try to make it into VT_I4, can use VariantChangeType for this */ - hr = VariantChangeType(&varg2, &varg2, 0, VT_I4); - if (SUCCEEDED(hr) && ret != ERROR_SUCCESS) hr = DISP_E_BADINDEX; /* Conversion fine, but couldn't find key */ - if (FAILED(hr)) - { - if (hr == DISP_E_TYPEMISMATCH) *puArgErr = posValue; - VariantClear(&varg2); /* Unknown type, so let's clear it */ - VariantClear(&varg1); - return hr; - } + case DISPID_INSTALLER_ENVIRONMENT: + return InstallerImpl_Environment(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); - /* Retrieve class name or maximum value name or subkey name size */ - if (!V_I4(&varg2)) - ret = RegQueryInfoKeyW(hkey, NULL, &dwSize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - else if (V_I4(&varg2) > 0) - ret = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwSize, NULL, NULL, NULL); - else /* V_I4(&varg2) < 0 */ - ret = RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, &dwSize, NULL, NULL, NULL, NULL, NULL, NULL); + case DISPID_INSTALLER_FILEATTRIBUTES: + return InstallerImpl_FileAttributes(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr); - if (ret == ERROR_SUCCESS) - { - if (!(szString = msi_alloc(++dwSize * sizeof(WCHAR)))) - ERR("Out of memory\n"); - else if (!V_I4(&varg2)) - ret = RegQueryInfoKeyW(hkey, szString, &dwSize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - else if (V_I4(&varg2) > 0) - ret = RegEnumValueW(hkey, V_I4(&varg2)-1, szString, &dwSize, 0, 0, NULL, NULL); - else /* V_I4(&varg2) < 0 */ - ret = RegEnumKeyW(hkey, -1 - V_I4(&varg2), szString, dwSize); - - if (szString && ret == ERROR_SUCCESS) - { - V_VT(pVarResult) = VT_BSTR; - V_BSTR(pVarResult) = SysAllocString(szString); - } - } - } + case DISPID_INSTALLER_FILESIZE: + return InstallerImpl_FileSize(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); - msi_free(szString); - RegCloseKey(hkey); - } - else return DISP_E_MEMBERNOTFOUND; - break; + case DISPID_INSTALLER_FILEVERSION: + return InstallerImpl_FileVersion(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); case DISPID_INSTALLER_PRODUCTSTATE: - if (wFlags & DISPATCH_PROPERTYGET) { - hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); - if (FAILED(hr)) return hr; - V_VT(pVarResult) = VT_I4; - V_I4(pVarResult) = MsiQueryProductStateW(V_BSTR(&varg0)); - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_ProductState(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); case DISPID_INSTALLER_PRODUCTINFO: - if (wFlags & DISPATCH_PROPERTYGET) { - hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); - if (FAILED(hr)) return hr; - hr = DispGetParam(pDispParams, 1, VT_BSTR, &varg1, puArgErr); - if (FAILED(hr)) - { - VariantClear(&varg0); - return hr; - } - V_VT(pVarResult) = VT_BSTR; - V_BSTR(pVarResult) = NULL; - if ((ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), NULL, &dwSize)) == ERROR_SUCCESS) - { - if (!(szString = msi_alloc((++dwSize)*sizeof(WCHAR)))) - ERR("Out of memory\n"); - else if ((ret = MsiGetProductInfoW(V_BSTR(&varg0), V_BSTR(&varg1), szString, &dwSize)) == ERROR_SUCCESS) - V_BSTR(pVarResult) = SysAllocString(szString); - msi_free(szString); - } - if (ret != ERROR_SUCCESS) - { - ERR("MsiGetProductInfo returned %d\n", ret); - VariantClear(&varg1); - VariantClear(&varg0); - return DISP_E_EXCEPTION; - } - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_ProductInfo(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); case DISPID_INSTALLER_PRODUCTS: - if (wFlags & DISPATCH_PROPERTYGET) - { - ListData *ldata = NULL; - ULONG idx = 0; - WCHAR szProductBuf[GUID_SIZE]; - - /* Find number of products */ - while ((ret = MsiEnumProductsW(idx, szProductBuf)) == ERROR_SUCCESS) idx++; - if (ret != ERROR_NO_MORE_ITEMS) - { - ERR("MsiEnumProducts returned %d\n", ret); - return DISP_E_EXCEPTION; - } - - V_VT(pVarResult) = VT_DISPATCH; - if (SUCCEEDED(hr = create_automation_object(0, NULL, (LPVOID*)&pDispatch, &DIID_StringList, ListImpl_Invoke, ListImpl_Free, sizeof(ListData)))) - { - V_DISPATCH(pVarResult) = pDispatch; - - /* Save product strings */ - ldata = private_data((AutomationObject *)pDispatch); - if (!(ldata->pVars = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*idx))) - ERR("Out of memory\n"); - else - { - ldata->ulCount = idx; - for (idx = 0; idx < ldata->ulCount; idx++) - { - ret = MsiEnumProductsW(idx, szProductBuf); - VariantInit(&ldata->pVars[idx]); - V_VT(&ldata->pVars[idx]) = VT_BSTR; - V_BSTR(&ldata->pVars[idx]) = SysAllocString(szProductBuf); - } - } - } - else - ERR("Failed to create StringList object, hresult 0x%08x\n", hr); - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_Products(wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); case DISPID_INSTALLER_RELATEDPRODUCTS: - if (wFlags & DISPATCH_PROPERTYGET) - { - ListData *ldata = NULL; - ULONG idx = 0; - WCHAR szProductBuf[GUID_SIZE]; - - hr = DispGetParam(pDispParams, 0, VT_BSTR, &varg0, puArgErr); - if (FAILED(hr)) return hr; - - /* Find number of related products */ - while ((ret = MsiEnumRelatedProductsW(V_BSTR(&varg0), 0, idx, szProductBuf)) == ERROR_SUCCESS) idx++; - if (ret != ERROR_NO_MORE_ITEMS) - { - VariantClear(&varg0); - ERR("MsiEnumRelatedProducts returned %d\n", ret); - return DISP_E_EXCEPTION; - } - - V_VT(pVarResult) = VT_DISPATCH; - if (SUCCEEDED(hr = create_automation_object(0, NULL, (LPVOID*)&pDispatch, &DIID_StringList, ListImpl_Invoke, ListImpl_Free, sizeof(ListData)))) - { - V_DISPATCH(pVarResult) = pDispatch; - - /* Save product strings */ - ldata = private_data((AutomationObject *)pDispatch); - if (!(ldata->pVars = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*idx))) - ERR("Out of memory\n"); - else - { - ldata->ulCount = idx; - for (idx = 0; idx < ldata->ulCount; idx++) - { - ret = MsiEnumRelatedProductsW(V_BSTR(&varg0), 0, idx, szProductBuf); - VariantInit(&ldata->pVars[idx]); - V_VT(&ldata->pVars[idx]) = VT_BSTR; - V_BSTR(&ldata->pVars[idx]) = SysAllocString(szProductBuf); - } - } - } - else - ERR("Failed to create StringList object, hresult 0x%08x\n", hr); - } - else return DISP_E_MEMBERNOTFOUND; - break; + return InstallerImpl_RelatedProducts(wFlags, pDispParams, + pVarResult, pExcepInfo, + puArgErr); - default: + default: return DISP_E_MEMBERNOTFOUND; } - - VariantClear(&varg2); - VariantClear(&varg1); - VariantClear(&varg0); - - return S_OK; } /* Wrapper around create_automation_object to create an installer object. */ diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 5b23f55b189..0e1a23bfaea 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -698,6 +698,7 @@ extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, BOOL preserve_case ); /* record internals */ +extern void MSI_CloseRecord( MSIOBJECTHDR * ); extern UINT MSI_RecordSetIStream( MSIRECORD *, UINT, IStream *); extern UINT MSI_RecordGetIStream( MSIRECORD *, UINT, IStream **); extern const WCHAR *MSI_RecordGetString( const MSIRECORD *, UINT ); diff --git a/dlls/msi/msiserver.idl b/dlls/msi/msiserver.idl index 753cbb06886..8e4936868d6 100644 --- a/dlls/msi/msiserver.idl +++ b/dlls/msi/msiserver.idl @@ -152,21 +152,48 @@ library WindowsInstaller Session* OpenPackage( [in] VARIANT PackagePath, [in, optional, defaultvalue(0)] long Options); + [id(DISPID_INSTALLER_OPENPRODUCT)] + Session* OpenProduct( + [in] BSTR ProductCode); + [id(DISPID_INSTALLER_SUMMARYINFORMATION)] + SummaryInfo* SummaryInformation( + [in] BSTR PackagePath, + [in, optional, defaultvalue(0)] long UpdateCount); [id(DISPID_INSTALLER_OPENDATABASE)] Database *OpenDatabase( [in] BSTR DatabasePath, [in] VARIANT OpenMode); + [id(DISPID_INSTALLER_ENABLELOG)] + void EnableLog( + [in] BSTR LogMode, + [in] BSTR LogFile); [id(DISPID_INSTALLER_INSTALLPRODUCT)] void InstallProduct( [in] BSTR PackagePath, [in, optional, defaultvalue("0")] BSTR PropertyValues); [id(DISPID_INSTALLER_VERSION)] BSTR Version(); + [id(DISPID_INSTALLER_LASTERRORRECORD)] + Record* LastErrorRecord(); [id(DISPID_INSTALLER_REGISTRYVALUE), propget] BSTR RegistryValue( [in] VARIANT Root, [in] BSTR Key, [in, optional] VARIANT Value); + [id(DISPID_INSTALLER_ENVIRONMENT), propget] + BSTR Environment([in] BSTR Variable); + [id(DISPID_INSTALLER_ENVIRONMENT), propput] + void Environment( + [in] BSTR Variable, + [in] BSTR rhs); + [id(DISPID_INSTALLER_FILEATTRIBUTES)] + long FileAttributes([in] BSTR FilePath); + [id(DISPID_INSTALLER_FILESIZE)] + long FileSize([in] BSTR FilePath); + [id(DISPID_INSTALLER_FILEVERSION)] + BSTR FileVersion( + [in] BSTR FilePath, + [in, optional] VARIANT Language); [id(DISPID_INSTALLER_PRODUCTSTATE), propget] MsiInstallState ProductState( [in] BSTR Product); diff --git a/dlls/msi/msiserver_dispids.h b/dlls/msi/msiserver_dispids.h index e6078fd6d67..d98d784940a 100644 --- a/dlls/msi/msiserver_dispids.h +++ b/dlls/msi/msiserver_dispids.h @@ -18,11 +18,19 @@ #define DISPID_INSTALLER_CREATERECORD 1 #define DISPID_INSTALLER_OPENPACKAGE 2 +#define DISPID_INSTALLER_OPENPRODUCT 3 #define DISPID_INSTALLER_OPENDATABASE 4 +#define DISPID_INSTALLER_SUMMARYINFORMATION 5 #define DISPID_INSTALLER_UILEVEL 6 +#define DISPID_INSTALLER_ENABLELOG 7 #define DISPID_INSTALLER_INSTALLPRODUCT 8 #define DISPID_INSTALLER_VERSION 9 +#define DISPID_INSTALLER_LASTERRORRECORD 10 #define DISPID_INSTALLER_REGISTRYVALUE 11 +#define DISPID_INSTALLER_ENVIRONMENT 12 +#define DISPID_INSTALLER_FILEATTRIBUTES 13 +#define DISPID_INSTALLER_FILESIZE 15 +#define DISPID_INSTALLER_FILEVERSION 16 #define DISPID_INSTALLER_PRODUCTSTATE 17 #define DISPID_INSTALLER_PRODUCTINFO 18 #define DISPID_INSTALLER_PRODUCTS 35 diff --git a/dlls/msi/record.c b/dlls/msi/record.c index 68eab694370..45adbac8471 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -64,7 +64,7 @@ static void MSI_FreeField( MSIFIELD *field ) } } -static void MSI_CloseRecord( MSIOBJECTHDR *arg ) +void MSI_CloseRecord( MSIOBJECTHDR *arg ) { MSIRECORD *rec = (MSIRECORD *) arg; UINT i; diff --git a/dlls/msi/table.c b/dlls/msi/table.c index fa32a04a21e..7c341a7cdf3 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -1042,17 +1042,22 @@ static UINT get_tablecolumns( MSIDATABASE *db, static void msi_update_table_columns( MSIDATABASE *db, LPCWSTR name ) { MSITABLE *table; + LPWSTR tablename; UINT size, offset, old_count; UINT n; - table = find_cached_table( db, name ); + /* We may free name in msi_free_colinfo. */ + tablename = strdupW( name ); + + table = find_cached_table( db, tablename ); old_count = table->col_count; + msi_free_colinfo( table->colinfo, table->col_count ); msi_free( table->colinfo ); table->colinfo = NULL; - table_get_column_info( db, name, &table->colinfo, &table->col_count ); + table_get_column_info( db, tablename, &table->colinfo, &table->col_count ); if (!table->col_count) - return; + goto done; size = msi_table_get_row_size( db, table->colinfo, table->col_count ); offset = table->colinfo[table->col_count - 1].offset; @@ -1063,6 +1068,9 @@ static void msi_update_table_columns( MSIDATABASE *db, LPCWSTR name ) if (old_count < table->col_count) memset( &table->data[n][offset], 0, size - offset ); } + +done: + msi_free(tablename); } /* try to find the table name in the _Tables table */ @@ -1754,15 +1762,14 @@ static UINT TABLE_delete_row( struct tagMSIVIEW *view, UINT row ) tv->columns[i].hash_table = NULL; } - if ( row == num_rows - 1 ) - return ERROR_SUCCESS; - for (i = row + 1; i < num_rows; i++) { memcpy(tv->table->data[i - 1], tv->table->data[i], tv->row_size); tv->table->data_persistent[i - 1] = tv->table->data_persistent[i]; } + msi_free(tv->table->data[num_rows - 1]); + return ERROR_SUCCESS; } @@ -1828,6 +1835,9 @@ static UINT msi_refresh_record( struct tagMSIVIEW *view, MSIRECORD *rec, UINT ro if (r != ERROR_SUCCESS) return r; + /* Close the original record */ + MSI_CloseRecord(&rec->hdr); + count = MSI_RecordGetFieldCount(rec); for (i = 0; i < count; i++) MSI_RecordCopyField(curr, i + 1, rec, i + 1); diff --git a/dlls/msi/tests/automation.c b/dlls/msi/tests/automation.c index b792fa722bd..8a0eede3066 100644 --- a/dlls/msi/tests/automation.c +++ b/dlls/msi/tests/automation.c @@ -34,8 +34,8 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); -static const char *msifile = "winetest.msi"; -static const WCHAR szMsifile[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0}; +static const char *msifile = "winetest-automation.msi"; +static const WCHAR szMsifile[] = {'w','i','n','e','t','e','s','t','-','a','u','t','o','m','a','t','i','o','n','.','m','s','i',0}; static const WCHAR szMSITEST[] = { 'M','S','I','T','E','S','T',0 }; static const WCHAR szProductCode[] = { '{','F','1','C','3','A','F','5','0','-','8','B','5','6','-','4','A','6','9','-','A','0','0','C','-','0','0','7','7','3','F','E','4','2','F','3','0','}',0 }; static const WCHAR szUpgradeCode[] = { '{','C','E','0','6','7','E','8','D','-','2','E','1','A','-','4','3','6','7','-','B','7','3','4','-','4','E','B','2','B','D','A','D','6','5','6','5','}',0 }; @@ -271,6 +271,27 @@ static void create_database(const CHAR *name, const msi_table *tables, int num_t MsiCloseHandle(db); } +static BOOL create_package(LPWSTR path) +{ + DWORD len; + + /* Prepare package */ + create_database(msifile, tables, + sizeof(tables) / sizeof(msi_table), summary_info, + sizeof(summary_info) / sizeof(msi_summary_info)); + + len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, + CURR_DIR, -1, path, MAX_PATH); + ok(len, "MultiByteToWideChar returned error %d\n", GetLastError()); + if (!len) + return FALSE; + + /* lstrcatW does not work on win95 */ + path[len - 1] = '\\'; + memcpy(&path[len], szMsifile, sizeof(szMsifile)); + return TRUE; +} + /* * Installation helpers */ @@ -456,35 +477,32 @@ static void test_dispid(void) ok(dispid == 1, "Expected 1, got %d\n", dispid); dispid = get_dispid(pInstaller, "OpenPackage"); ok(dispid == 2, "Expected 2, got %d\n", dispid); + dispid = get_dispid(pInstaller, "OpenProduct"); + ok(dispid == 3, "Expected 3, got %d\n", dispid); dispid = get_dispid(pInstaller, "OpenDatabase"); ok(dispid == 4, "Expected 4, got %d\n", dispid); + dispid = get_dispid(pInstaller, "SummaryInformation"); + ok(dispid == 5, "Expected 5, got %d\n", dispid); dispid = get_dispid( pInstaller, "UILevel" ); ok(dispid == 6, "Expected 6, got %d\n", dispid); + dispid = get_dispid(pInstaller, "EnableLog"); + ok(dispid == 7, "Expected 7, got %d\n", dispid); dispid = get_dispid(pInstaller, "InstallProduct"); ok(dispid == 8, "Expected 8, got %d\n", dispid); dispid = get_dispid(pInstaller, "Version"); ok(dispid == 9, "Expected 9, got %d\n", dispid); + dispid = get_dispid(pInstaller, "LastErrorRecord"); + ok(dispid == 10, "Expected 10, got %d\n", dispid); dispid = get_dispid(pInstaller, "RegistryValue"); ok(dispid == 11, "Expected 11, got %d\n", dispid); - todo_wine - { - dispid = get_dispid(pInstaller, "OpenProduct"); - ok(dispid == 3, "Expected 3, got %d\n", dispid); - dispid = get_dispid(pInstaller, "SummaryInformation"); - ok(dispid == 5, "Expected 5, got %d\n", dispid); - dispid = get_dispid(pInstaller, "EnableLog"); - ok(dispid == 7, "Expected 7, got %d\n", dispid); - dispid = get_dispid(pInstaller, "LastErrorRecord"); - ok(dispid == 10, "Expected 10, got %d\n", dispid); - dispid = get_dispid(pInstaller, "Environment"); - ok(dispid == 12, "Expected 12, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileAttributes"); - ok(dispid == 13, "Expected 13, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileSize"); - ok(dispid == 15, "Expected 15, got %d\n", dispid); - dispid = get_dispid(pInstaller, "FileVersion"); - ok(dispid == 16, "Expected 16, got %d\n", dispid); - } + dispid = get_dispid(pInstaller, "Environment"); + ok(dispid == 12, "Expected 12, got %d\n", dispid); + dispid = get_dispid(pInstaller, "FileAttributes"); + ok(dispid == 13, "Expected 13, got %d\n", dispid); + dispid = get_dispid(pInstaller, "FileSize"); + ok(dispid == 15, "Expected 15, got %d\n", dispid); + dispid = get_dispid(pInstaller, "FileVersion"); + ok(dispid == 16, "Expected 16, got %d\n", dispid); dispid = get_dispid(pInstaller, "ProductState"); ok(dispid == 17, "Expected 17, got %d\n", dispid); dispid = get_dispid(pInstaller, "ProductInfo"); @@ -592,7 +610,8 @@ static void test_dispatch(void) DISPID dispid; OLECHAR *name; VARIANT varresult; - VARIANTARG vararg[2]; + VARIANTARG vararg[3]; + WCHAR path[MAX_PATH]; DISPPARAMS dispparams = {NULL, NULL, 0, 0}; /* Test getting ID of a function name that does not exist */ @@ -620,24 +639,159 @@ static void test_dispatch(void) /* Try with NULL params */ hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - todo_wine ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); /* Try one empty parameter */ dispparams.rgvarg = vararg; dispparams.cArgs = 1; VariantInit(&vararg[0]); hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - todo_wine ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); - /* Try one parameter, function requires two */ + /* Try two empty parameters */ + dispparams.cArgs = 2; + VariantInit(&vararg[0]); + VariantInit(&vararg[1]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + + /* Try one parameter, the required BSTR. Second parameter is optional. + * NOTE: The specified package does not exist, which is why the call fails. + */ + dispparams.cArgs = 1; VariantInit(&vararg[0]); V_VT(&vararg[0]) = VT_BSTR; V_BSTR(&vararg[0]) = SysAllocString(szMsifile); hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); VariantClear(&vararg[0]); + /* Provide the required BSTR and an empty second parameter. + * NOTE: The specified package does not exist, which is why the call fails. + */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szMsifile); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[1]); + + /* Provide the required BSTR and two empty parameters. + * NOTE: The specified package does not exist, which is why the call fails. + */ + dispparams.cArgs = 3; + VariantInit(&vararg[2]); + V_VT(&vararg[2]) = VT_BSTR; + V_BSTR(&vararg[2]) = SysAllocString(szMsifile); + VariantInit(&vararg[1]); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[2]); + + /* Provide the required BSTR and a second parameter with the wrong type. */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(szMsifile); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szMsifile); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[0]); + VariantClear(&vararg[1]); + + /* Create a proper installer package. */ + create_package(path); + + /* Try one parameter, the required BSTR. Second parameter is optional. + * Proper installer package exists. Path to the package is relative. + */ + dispparams.cArgs = 1; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(szMsifile); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + todo_wine ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned 0x%08x\n", hr); + ok_exception(hr, szOpenPackageException); + VariantClear(&vararg[0]); + if (hr != DISP_E_EXCEPTION) + VariantClear(&varresult); + + /* Try one parameter, the required BSTR. Second parameter is optional. + * Proper installer package exists. Path to the package is absolute. + */ + dispparams.cArgs = 1; + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(path); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[0]); + VariantClear(&varresult); + + /* Provide the required BSTR and an empty second parameter. Proper + * installation package exists. + */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(path); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[1]); + VariantClear(&varresult); + + /* Provide the required BSTR and two empty parameters. Proper + * installation package exists. + */ + dispparams.cArgs = 3; + VariantInit(&vararg[2]); + V_VT(&vararg[2]) = VT_BSTR; + V_BSTR(&vararg[2]) = SysAllocString(path); + VariantInit(&vararg[1]); + VariantInit(&vararg[0]); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[2]); + VariantClear(&varresult); + + /* Provide the required BSTR and a second parameter with the wrong type. */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(path); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_BSTR; + V_BSTR(&vararg[0]) = SysAllocString(path); + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[0]); + VariantClear(&vararg[1]); + + /* Provide the required BSTR and a second parameter that can be coerced to + * VT_I4. + */ + dispparams.cArgs = 2; + VariantInit(&vararg[1]); + V_VT(&vararg[1]) = VT_BSTR; + V_BSTR(&vararg[1]) = SysAllocString(path); + VariantInit(&vararg[0]); + V_VT(&vararg[0]) = VT_I2; + V_BSTR(&vararg[0]) = 0; + hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); + ok(hr == S_OK, "IDispatch::Invoke returned 0x%08x\n", hr); + VariantClear(&vararg[1]); + VariantClear(&varresult); + + DeleteFileW(path); /* Test invoking a method as a DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT */ VariantInit(&vararg[0]); @@ -2353,7 +2507,6 @@ static void test_Installer(void) static WCHAR szIntegerDataException[] = { 'I','n','t','e','g','e','r','D','a','t','a',',','F','i','e','l','d',0 }; WCHAR szPath[MAX_PATH]; HRESULT hr; - UINT len; IDispatch *pSession = NULL, *pDatabase = NULL, *pRecord = NULL, *pStringList = NULL; int iValue, iCount; @@ -2404,17 +2557,7 @@ static void test_Installer(void) IDispatch_Release(pRecord); } - /* Prepare package */ - create_database(msifile, tables, sizeof(tables) / sizeof(msi_table), - summary_info, sizeof(summary_info) / sizeof(msi_summary_info)); - - len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, CURR_DIR, -1, szPath, MAX_PATH); - ok(len, "MultiByteToWideChar returned error %d\n", GetLastError()); - if (!len) return; - - /* lstrcatW does not work on win95 */ - szPath[len - 1] = '\\'; - memcpy(&szPath[len], szMsifile, sizeof(szMsifile)); + create_package(szPath); /* Installer::OpenPackage */ hr = Installer_OpenPackage(szPath, 0, &pSession); diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 041e8605bd0..bafa0dbb77d 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -31,9 +31,10 @@ #include "wine/test.h" -static const char *msifile = "winetest.msi"; -static const char *msifile2 = "winetst2.msi"; -static const char *mstfile = "winetst.mst"; +static const char *msifile = "winetest-db.msi"; +static const char *msifile2 = "winetst2-db.msi"; +static const char *mstfile = "winetst-db.mst"; +static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','-','d','b','.','m','s','i',0}; static void test_msidatabase(void) { @@ -5569,8 +5570,6 @@ static void test_defaultdatabase(void) MSIHANDLE hdb; IStorage *stg = NULL; - static const WCHAR msifileW[] = {'w','i','n','e','t','e','s','t','.','m','s','i',0}; - DeleteFile(msifile); r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb); diff --git a/dlls/msi/tests/format.c b/dlls/msi/tests/format.c index 2b2661cfddb..3d4029cb0ac 100644 --- a/dlls/msi/tests/format.c +++ b/dlls/msi/tests/format.c @@ -27,7 +27,7 @@ #include "wine/test.h" -static const char msifile[] = "winetest.msi"; +static const char msifile[] = "winetest-format.msi"; static UINT run_query( MSIHANDLE hdb, const char *query ) { @@ -315,17 +315,16 @@ static MSIHANDLE helper_createpackage( const char *szName ) static void test_createpackage(void) { - static const CHAR filename[] = "winetest.msi"; MSIHANDLE hPackage = 0; UINT res; - hPackage = helper_createpackage( filename ); + hPackage = helper_createpackage( msifile ); ok ( hPackage != 0, " Failed to create package\n"); res = MsiCloseHandle( hPackage); ok( res == ERROR_SUCCESS , "Failed to close package\n" ); - DeleteFile( filename ); + DeleteFile( msifile ); } static void test_formatrecord(void) @@ -1620,14 +1619,13 @@ static void test_formatrecord(void) static void test_formatrecord_package(void) { - static const CHAR filename[] = "winetest.msi"; char buffer[100]; MSIHANDLE hrec; MSIHANDLE package; UINT r; DWORD sz=100; - package = helper_createpackage( filename ); + package = helper_createpackage( msifile ); ok(package!=0, "Unable to create package\n"); hrec = MsiCreateRecord(12); @@ -2117,7 +2115,7 @@ static void test_formatrecord_package(void) r = MsiCloseHandle(package); ok(r==ERROR_SUCCESS, "Unable to close package\n"); - DeleteFile( filename ); + DeleteFile( msifile ); } static void test_formatrecord_tables(void) @@ -2383,12 +2381,11 @@ static void test_formatrecord_tables(void) static void test_processmessage(void) { - static const CHAR filename[] = "winetest.msi"; MSIHANDLE hrec; MSIHANDLE package; int r; - package = helper_createpackage( filename ); + package = helper_createpackage( msifile ); ok(package!=0, "Unable to create package\n"); hrec = MsiCreateRecord(3); @@ -2403,7 +2400,7 @@ static void test_processmessage(void) MsiCloseHandle(hrec); MsiCloseHandle(package); - DeleteFile(filename); + DeleteFile(msifile); } START_TEST(format) diff --git a/dlls/msi/tests/msi.c b/dlls/msi/tests/msi.c index 8da34990006..e249965c17a 100644 --- a/dlls/msi/tests/msi.c +++ b/dlls/msi/tests/msi.c @@ -2517,8 +2517,7 @@ static void test_MsiGetFileVersion(void) r = MsiGetFileVersionA(path, version, &versz, lang, &langsz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz); - ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang); ok(!lstrcmpA(version, vercheck), "Expected %s, got %s\n", vercheck, version); @@ -2536,8 +2535,7 @@ static void test_MsiGetFileVersion(void) lstrcpyA(lang, "lang"); r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang); /* check neither version nor language */ r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL); @@ -2553,7 +2551,7 @@ static void test_MsiGetFileVersion(void) langsz = MAX_PATH; r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz); /* pcchVersionBuf not big enough */ versz = 5; @@ -2571,7 +2569,7 @@ static void test_MsiGetFileVersion(void) ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); ok(!strncmp(lang, langcheck, 2), "Expected first character of %s, got %s\n", langcheck, lang); - ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz); + ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz); HeapFree(GetProcessHeap(), 0, vercheck); HeapFree(GetProcessHeap(), 0, langcheck); diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 903e2acc216..979de1af3d0 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -30,7 +30,7 @@ #include "wine/test.h" -static const char msifile[] = "winetest.msi"; +static const char msifile[] = "winetest-package.msi"; char CURR_DIR[MAX_PATH]; static UINT (WINAPI *pMsiApplyMultiplePatchesA)(LPCSTR, LPCSTR, LPCSTR); @@ -2341,9 +2341,9 @@ static void test_states(void) MSIHANDLE hdb; INSTALLSTATE state, action; - static const CHAR msifile2[] = "winetest2.msi"; - static const CHAR msifile3[] = "winetest3.msi"; - static const CHAR msifile4[] = "winetest4.msi"; + static const CHAR msifile2[] = "winetest2-package.msi"; + static const CHAR msifile3[] = "winetest3-package.msi"; + static const CHAR msifile4[] = "winetest4-package.msi"; hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); @@ -11601,7 +11601,8 @@ static void test_MsiGetProductProperty(void) ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); lstrcpyA(val, path); - lstrcatA(val, "\\winetest.msi"); + lstrcatA(val, "\\"); + lstrcatA(val, msifile); res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ, (const BYTE *)val, lstrlenA(val) + 1); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); diff --git a/dlls/msi/tests/record.c b/dlls/msi/tests/record.c index e8dd6f55596..2c8f5bfd495 100644 --- a/dlls/msi/tests/record.c +++ b/dlls/msi/tests/record.c @@ -24,7 +24,7 @@ #include "wine/test.h" -static const char *msifile = "winetest.msi"; +static const char *msifile = "winetest-record.msi"; static BOOL create_temp_file(char *name) { @@ -604,6 +604,7 @@ static void test_fieldzero(void) r = MsiRecordIsNull(rec, 0); ok(r == FALSE, "Expected FALSE, got %d\n", r); + MsiCloseHandle(rec); MsiCloseHandle(hdb); DeleteFileA(msifile); } diff --git a/dlls/msi/tests/suminfo.c b/dlls/msi/tests/suminfo.c index f0e7fddc8d2..a0b225b6bd9 100644 --- a/dlls/msi/tests/suminfo.c +++ b/dlls/msi/tests/suminfo.c @@ -63,9 +63,12 @@ #define PID_MSISOURCE PID_WORDCOUNT #define PID_MSIRESTRICT PID_CHARCOUNT +const char *msifile = "winetest-suminfo.msi"; +static const WCHAR msifileW[] = { + 'w','i','n','e','t','e','s','t','-','s','u','m','i','n','f','o','.','m','s','i',0 }; + static void test_suminfo(void) { - const char *msifile = "winetest.msi"; MSIHANDLE hdb = 0, hsuminfo; UINT r, count, type; DWORD sz; @@ -284,8 +287,6 @@ static void test_create_database_binary(void) static const CLSID FMTID_SummaryInformation = { 0xf29f85e0, 0x4ff9, 0x1068, {0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9}}; DWORD mode = STGM_CREATE | STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE; - static const WCHAR msifile[] = { - 'w','i','n','e','t','e','s','t','.','m','s','i',0 }; IPropertySetStorage *pss = NULL; IPropertyStorage *ps = NULL; IStorage *stg = NULL; @@ -295,7 +296,7 @@ static void test_create_database_binary(void) PROPVARIANT propvar[10]; USHORT data[2] = { 0, 0 }; - r = StgCreateDocfile( msifile, mode, 0, &stg ); + r = StgCreateDocfile( msifileW, mode, 0, &stg ); ok( r == S_OK, "failed to create database\n"); r = IStorage_SetClass( stg, &CLSID_MsiDatabase ); @@ -386,7 +387,6 @@ static void test_create_database_binary(void) static void test_summary_binary(void) { - const char *msifile = "winetest.msi"; MSIHANDLE hdb = 0, hsuminfo = 0; UINT r, type, count; INT ival; diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c index e652985ef8f..e164555af57 100644 --- a/dlls/msvcrt/tests/file.c +++ b/dlls/msvcrt/tests/file.c @@ -439,6 +439,7 @@ static void test_fgetc( void ) ok(ich == ret, "Second fgetc expected %x got %x\n", ich, ret); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_fputc( void ) @@ -463,6 +464,7 @@ static void test_fputc( void ) fclose(tempfh); unlink(tempf); + free(tempf); } static void test_flsbuf( void ) @@ -517,6 +519,7 @@ static void test_flsbuf( void ) fclose(tempfh); unlink(tempf); + free(tempf); } static void test_fgetwc( void ) @@ -634,6 +637,7 @@ static void test_fgetwc( void ) free(mytextW); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_ctrlz( void ) @@ -681,6 +685,7 @@ static void test_ctrlz( void ) ok(feof(tempfh), "did not get EOF\n"); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_file_put_get( void ) @@ -730,6 +735,7 @@ static void test_file_put_get( void ) free(mytextW); fclose(tempfh); unlink(tempf); + free(tempf); } static void test_file_write_read( void ) @@ -806,6 +812,7 @@ static void test_file_write_read( void ) ret = unlink(tempf); ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno); + free(tempf); tempf=_tempnam(".","wne"); tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0); @@ -833,6 +840,7 @@ static void test_file_write_read( void ) "Can't chmod '%s' to read-write: %d\n", tempf, errno); ret = unlink(tempf); ok( ret == 0 ,"Can't unlink '%s': %d\n", tempf, errno); + free(tempf); } static void test_file_inherit_child(const char* fd_s) @@ -1080,6 +1088,7 @@ static void test_chsize( void ) _close( fd ); _unlink( tempfile ); + free( tempfile ); } static void test_fopen_fclose_fcloseall( void ) diff --git a/dlls/msvcrt/tests/signal.c b/dlls/msvcrt/tests/signal.c index b2c16d5be2c..d33498bd537 100644 --- a/dlls/msvcrt/tests/signal.c +++ b/dlls/msvcrt/tests/signal.c @@ -24,16 +24,14 @@ static int test_value = 0; -typedef void (sighandler_type)(int); - -static void sighandler(int signum) +static void __cdecl sighandler(int signum) { ++test_value; } static void test_signal(void) { - sighandler_type *old; + void (__cdecl *old)(int); int res; old = signal(SIGBREAK, sighandler); diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index ed6c8c6c0aa..82f4c5678f2 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1118,7 +1118,8 @@ static inline HRESULT VARIANT_from_xmlChar(xmlChar *str, VARIANT *v, BSTR type) if(!V_BSTR(&src)) return E_OUTOFMEMORY; - hres = VariantChangeType(v, &src, 0, V_VT(v)); + hres = VariantChangeTypeEx(v, &src, MAKELCID(MAKELANGID( + LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v)); VariantClear(&src); return hres; } diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index de78b6550ce..87ad9b563d6 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -3085,6 +3085,8 @@ static void test_xmlTypes(void) IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1; VARIANT var; + VariantInit(&var); + hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (LPVOID*)&pElement); ok(hr == E_NOINTERFACE, "ret %08x\n", hr); @@ -3155,7 +3157,8 @@ static void test_xmlTypes(void) /* test get nodeValue */ hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var); ok(hr == S_OK, "ret %08x\n", hr ); - ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n"); + ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var)); + ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n"); VariantClear(&var); /* test get data */ diff --git a/dlls/netapi32/access.c b/dlls/netapi32/access.c index 0044035bb61..71702597792 100644 --- a/dlls/netapi32/access.c +++ b/dlls/netapi32/access.c @@ -494,7 +494,7 @@ static void ACCESS_QueryAdminDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD p PNET_DISPLAY_USER usr; /* set up buffer */ - name_sz = lstrlenW(sAdminUserName); + name_sz = lstrlenW(sAdminUserName) + 1; comment_sz = 1; full_name_sz = 1; @@ -533,7 +533,7 @@ static void ACCESS_QueryGuestDisplayInformation(PNET_DISPLAY_USER *buf, PDWORD p PNET_DISPLAY_USER usr; /* set up buffer */ - name_sz = lstrlenW(sGuestUserName); + name_sz = lstrlenW(sGuestUserName) + 1; comment_sz = 1; full_name_sz = 1; diff --git a/dlls/netapi32/tests/apibuf.c b/dlls/netapi32/tests/apibuf.c index 3400726ca58..af4d39d2cdb 100644 --- a/dlls/netapi32/tests/apibuf.c +++ b/dlls/netapi32/tests/apibuf.c @@ -59,6 +59,8 @@ static void run_apibuf_tests(void) /* border reallocate cases */ ok(pNetApiBufferReallocate(0, 1500, &p) == NERR_Success, "Reallocate with OldBuffer = NULL failed\n"); ok(p != NULL, "No memory got allocated\n"); + ok(pNetApiBufferFree(p) == NERR_Success, "NetApiBufferFree failed\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"); diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 82953c2145f..5e68837088a 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -71,6 +71,7 @@ #include "ntdll_misc.h" #include "wine/unicode.h" #include "wine/server.h" +#include "wine/list.h" #include "wine/library.h" #include "wine/debug.h" @@ -249,6 +250,54 @@ static inline unsigned int max_dir_info_size( FILE_INFORMATION_CLASS class ) } +/* support for a directory queue for filesystem searches */ + +struct dir_name +{ + struct list entry; + char name[1]; +}; + +static struct list dir_queue = LIST_INIT( dir_queue ); + +static NTSTATUS add_dir_to_queue( const char *name ) +{ + int len = strlen( name ) + 1; + struct dir_name *dir = RtlAllocateHeap( GetProcessHeap(), 0, + FIELD_OFFSET( struct dir_name, name[len] )); + if (!dir) return STATUS_NO_MEMORY; + strcpy( dir->name, name ); + list_add_tail( &dir_queue, &dir->entry ); + return STATUS_SUCCESS; +} + +static NTSTATUS next_dir_in_queue( char *name ) +{ + struct list *head = list_head( &dir_queue ); + if (head) + { + struct dir_name *dir = LIST_ENTRY( head, struct dir_name, entry ); + strcpy( name, dir->name ); + list_remove( &dir->entry ); + RtlFreeHeap( GetProcessHeap(), 0, dir ); + return STATUS_SUCCESS; + } + return STATUS_OBJECT_NAME_NOT_FOUND; +} + +static void flush_dir_queue(void) +{ + struct list *head; + + while ((head = list_head( &dir_queue ))) + { + struct dir_name *dir = LIST_ENTRY( head, struct dir_name, entry ); + list_remove( &dir->entry ); + RtlFreeHeap( GetProcessHeap(), 0, dir ); + } +} + + /*********************************************************************** * get_default_com_device * @@ -2218,81 +2267,134 @@ static inline int get_dos_prefix_len( const UNICODE_STRING *name ) /****************************************************************************** + * find_file_id + * + * Recursively search directories from the dir queue for a given inode. + */ +static NTSTATUS find_file_id( ANSI_STRING *unix_name, ULONGLONG file_id, dev_t dev ) +{ + unsigned int pos; + DIR *dir; + struct dirent *de; + NTSTATUS status; + struct stat st; + + while (!(status = next_dir_in_queue( unix_name->Buffer ))) + { + if (!(dir = opendir( unix_name->Buffer ))) continue; + TRACE( "searching %s for %s\n", unix_name->Buffer, wine_dbgstr_longlong(file_id) ); + pos = strlen( unix_name->Buffer ); + if (pos + MAX_DIR_ENTRY_LEN >= unix_name->MaximumLength/sizeof(WCHAR)) + { + char *new = RtlReAllocateHeap( GetProcessHeap(), 0, unix_name->Buffer, + unix_name->MaximumLength * 2 ); + if (!new) + { + closedir( dir ); + return STATUS_NO_MEMORY; + } + unix_name->MaximumLength *= 2; + unix_name->Buffer = new; + } + unix_name->Buffer[pos++] = '/'; + while ((de = readdir( dir ))) + { + if (!strcmp( de->d_name, "." ) || !strcmp( de->d_name, ".." )) continue; + strcpy( unix_name->Buffer + pos, de->d_name ); + if (lstat( unix_name->Buffer, &st ) == -1) continue; + if (st.st_dev != dev) continue; + if (st.st_ino == file_id) + { + closedir( dir ); + return STATUS_SUCCESS; + } + if (!S_ISDIR( st.st_mode )) continue; + if ((status = add_dir_to_queue( unix_name->Buffer )) != STATUS_SUCCESS) + { + closedir( dir ); + return status; + } + } + closedir( dir ); + } + return status; +} + + +/****************************************************************************** * file_id_to_unix_file_name * * Lookup a file from its file id instead of its name. */ -NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret ) +NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name ) { enum server_fd_type type; int old_cwd, root_fd, needs_close; - char *unix_name; - int unix_len; NTSTATUS status; ULONGLONG file_id; struct stat st, root_st; - DIR *dir; - struct dirent *de; if (attr->ObjectName->Length != sizeof(ULONGLONG)) return STATUS_OBJECT_PATH_SYNTAX_BAD; if (!attr->RootDirectory) return STATUS_INVALID_PARAMETER; memcpy( &file_id, attr->ObjectName->Buffer, sizeof(file_id) ); - unix_len = MAX_DIR_ENTRY_LEN + 1; - if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, unix_len ))) + unix_name->MaximumLength = 2 * MAX_DIR_ENTRY_LEN + 4; + if (!(unix_name->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, unix_name->MaximumLength ))) return STATUS_NO_MEMORY; - unix_name[0] = 0; + strcpy( unix_name->Buffer, "." ); - if (!(status = server_get_unix_fd( attr->RootDirectory, FILE_READ_DATA, &root_fd, - &needs_close, &type, NULL ))) + if ((status = server_get_unix_fd( attr->RootDirectory, 0, &root_fd, &needs_close, &type, NULL ))) + goto done; + + if (type != FD_TYPE_DIR) { - if (type != FD_TYPE_DIR) + status = STATUS_OBJECT_TYPE_MISMATCH; + goto done; + } + + fstat( root_fd, &root_st ); + if (root_st.st_ino == file_id) /* shortcut for "." */ + { + status = STATUS_SUCCESS; + goto done; + } + + RtlEnterCriticalSection( &dir_section ); + if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1) + { + /* shortcut for ".." */ + if (!stat( "..", &st ) && st.st_dev == root_st.st_dev && st.st_ino == file_id) { - if (needs_close) close( root_fd ); - status = STATUS_OBJECT_TYPE_MISMATCH; + strcpy( unix_name->Buffer, ".." ); + status = STATUS_SUCCESS; } else { - fstat( root_fd, &root_st ); - RtlEnterCriticalSection( &dir_section ); - if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1) - { - if (!(dir = opendir( "." ))) status = FILE_GetNtStatus(); - else - { - while ((de = readdir( dir ))) - { - if (stat( de->d_name, &st ) == -1) continue; - if (st.st_dev == root_st.st_dev && st.st_ino == file_id) - { - strcpy( unix_name, de->d_name ); - break; - } - } - closedir( dir ); - if (!unix_name[0]) status = STATUS_OBJECT_NAME_NOT_FOUND; - } - if (fchdir( old_cwd ) == -1) chdir( "/" ); - } - else status = FILE_GetNtStatus(); - RtlLeaveCriticalSection( &dir_section ); - if (old_cwd != -1) close( old_cwd ); - if (needs_close) close( root_fd ); + status = add_dir_to_queue( "." ); + if (!status) + status = find_file_id( unix_name, file_id, root_st.st_dev ); + if (!status) /* get rid of "./" prefix */ + memmove( unix_name->Buffer, unix_name->Buffer + 2, strlen(unix_name->Buffer) - 1 ); + flush_dir_queue(); } + if (fchdir( old_cwd ) == -1) chdir( "/" ); } + else status = FILE_GetNtStatus(); + RtlLeaveCriticalSection( &dir_section ); + if (old_cwd != -1) close( old_cwd ); +done: if (status == STATUS_SUCCESS) { - TRACE( "%s -> %s\n", wine_dbgstr_longlong(file_id), debugstr_a(unix_name) ); - unix_name_ret->Buffer = unix_name; - unix_name_ret->Length = strlen(unix_name); - unix_name_ret->MaximumLength = unix_len; + TRACE( "%s -> %s\n", wine_dbgstr_longlong(file_id), debugstr_a(unix_name->Buffer) ); + unix_name->Length = strlen( unix_name->Buffer ); } else { - TRACE( "%s not found in %s\n", wine_dbgstr_longlong(file_id), unix_name ); - RtlFreeHeap( GetProcessHeap(), 0, unix_name ); + TRACE( "%s not found in dir %p\n", wine_dbgstr_longlong(file_id), attr->RootDirectory ); + RtlFreeHeap( GetProcessHeap(), 0, unix_name->Buffer ); } + if (needs_close) close( root_fd ); return status; } diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 1af41168513..00c54c24cf6 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -105,7 +105,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT ANSI_STRING unix_name; int created = FALSE; - TRACE("handle=%p access=%08x name=%s objattr=%08x root=%p sec=%p io=%p alloc_size=%p\n" + TRACE("handle=%p access=%08x name=%s objattr=%08x root=%p sec=%p io=%p alloc_size=%p " "attr=%08x sharing=%08x disp=%d options=%08x ea=%p.0x%08x\n", handle, access, debugstr_us(attr->ObjectName), attr->Attributes, attr->RootDirectory, attr->SecurityDescriptor, io, alloc_size, diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c index 60c01588d2b..c16b46106ed 100644 --- a/dlls/ntdll/tests/directory.c +++ b/dlls/ntdll/tests/directory.c @@ -43,6 +43,7 @@ static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PV static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR); static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* ); static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); +static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING ); static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, LPCSTR src, DWORD srclen ); static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirection)( BOOLEAN enable ); @@ -221,6 +222,7 @@ static void test_NtQueryDirectoryFile(void) pNtClose(dirh); done: tear_down_attribute_test(testdirA); + pRtlFreeUnicodeString(&ntdirname); } static void test_redirection(void) @@ -281,6 +283,7 @@ START_TEST(directory) pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); + pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll,"RtlMultiByteToUnicodeN"); pRtlWow64EnableFsRedirection = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirection"); pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirectionEx"); diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 39e71a55847..398f1985df6 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -43,13 +43,14 @@ static BOOL (WINAPI * pGetVolumePathNameW)(LPCWSTR, LPWSTR, DWORD); static UINT (WINAPI *pGetSystemWow64DirectoryW)( LPWSTR, UINT ); -static NTSTATUS (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING ); +static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING ); static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* ); static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * ); static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG, ULONG, PLARGE_INTEGER ); +static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG); static NTSTATUS (WINAPI *pNtOpenFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG); static NTSTATUS (WINAPI *pNtDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes); static NTSTATUS (WINAPI *pNtReadFile)(HANDLE hFile, HANDLE hEvent, @@ -152,10 +153,88 @@ static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved ) ok( !reserved, "reserved is not 0: %x\n", reserved ); } +static void create_file_test(void) +{ + NTSTATUS status; + HANDLE dir; + WCHAR path[MAX_PATH]; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + UNICODE_STRING nameW; + UINT len; + + len = GetCurrentDirectoryW( MAX_PATH, path ); + pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + /* try various open modes and options on directories */ + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + CloseHandle( dir ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, + "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN_IF, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + CloseHandle( dir ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_SUPERSEDE, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OVERWRITE, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OVERWRITE_IF, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( status == STATUS_INVALID_PARAMETER, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, 0, NULL, 0 ); + ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + CloseHandle( dir ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, 0, NULL, 0 ); + ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, + "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN_IF, 0, NULL, 0 ); + ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + CloseHandle( dir ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_SUPERSEDE, 0, NULL, 0 ); + ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, + "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OVERWRITE, 0, NULL, 0 ); + ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, + "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + + status = pNtCreateFile( &dir, GENERIC_READ, &attr, &io, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OVERWRITE_IF, 0, NULL, 0 ); + ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_ACCESS_DENIED, + "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); +} + static void open_file_test(void) { NTSTATUS status; - HANDLE dir, handle; + HANDLE dir, root, handle; WCHAR path[MAX_PATH]; BYTE data[8192]; OBJECT_ATTRIBUTES attr; @@ -175,6 +254,14 @@ static void open_file_test(void) status = pNtOpenFile( &dir, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + pRtlFreeUnicodeString( &nameW ); + + path[3] = 0; /* root of the drive */ + pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); + status = pNtOpenFile( &root, GENERIC_READ, &attr, &io, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE ); + ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status ); + pRtlFreeUnicodeString( &nameW ); /* test opening system dir with RootDirectory set to windows dir */ GetSystemDirectoryW( path, MAX_PATH ); @@ -226,6 +313,7 @@ static void open_file_test(void) nameW.Buffer = (WCHAR *)&info->FileId; nameW.Length = sizeof(info->FileId); info->FileName[info->FileNameLength/sizeof(WCHAR)] = 0; + attr.RootDirectory = dir; status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_BY_FILE_ID | @@ -250,6 +338,16 @@ static void open_file_test(void) "mismatched write time for %s\n", wine_dbgstr_w(info->FileName)); } CloseHandle( handle ); + + /* try same thing from drive root */ + attr.RootDirectory = root; + status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN_BY_FILE_ID | + ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) ); + ok( status == STATUS_SUCCESS || status == STATUS_NOT_IMPLEMENTED, + "open %s failed %x\n", wine_dbgstr_w(info->FileName), status ); + if (!status) CloseHandle( handle ); } next: if (!info->NextEntryOffset) break; @@ -258,6 +356,7 @@ static void open_file_test(void) } CloseHandle( dir ); + CloseHandle( root ); } static void delete_file_test(void) @@ -1111,22 +1210,20 @@ static void test_file_name_information(void) hr, STATUS_BUFFER_OVERFLOW); ok(U(io).Status == STATUS_BUFFER_OVERFLOW, "io.Status is %#x, expected %#x.\n", U(io).Status, STATUS_BUFFER_OVERFLOW); - ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %u, expected %u.\n", - info->FileNameLength, lstrlenW( expected ) * sizeof(WCHAR)); + ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %u\n", info->FileNameLength); ok(info->FileName[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info->FileName[2]); ok(CharLowerW((LPWSTR)(UINT_PTR)info->FileName[1]) == CharLowerW((LPWSTR)(UINT_PTR)expected[1]), "info->FileName[1] is %p, expected %p.\n", CharLowerW((LPWSTR)(UINT_PTR)info->FileName[1]), CharLowerW((LPWSTR)(UINT_PTR)expected[1])); - ok(io.Information == sizeof(*info), "io.Information is %lu, expected %u.\n", io.Information, sizeof(*info)); + ok(io.Information == sizeof(*info), "io.Information is %lu\n", io.Information); memset( info, 0xcc, info_size ); hr = pNtQueryInformationFile( h, &io, info, info_size, FileNameInformation ); ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#x, expected %#x.\n", hr, STATUS_SUCCESS); ok(U(io).Status == STATUS_SUCCESS, "io.Status is %#x, expected %#x.\n", U(io).Status, STATUS_SUCCESS); - ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %u, expected %u.\n", - info->FileNameLength, lstrlenW( expected ) * sizeof(WCHAR)); - ok(info->FileName[info->FileNameLength / sizeof(WCHAR)] == 0xcccc, "info->FileName[%u] is %#x, expected 0xcccc.\n", - info->FileNameLength / sizeof(WCHAR), info->FileName[info->FileNameLength / sizeof(WCHAR)]); + ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %u\n", info->FileNameLength); + ok(info->FileName[info->FileNameLength / sizeof(WCHAR)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n", + info->FileName[info->FileNameLength / sizeof(WCHAR)]); info->FileName[info->FileNameLength / sizeof(WCHAR)] = '\0'; ok(!lstrcmpiW( info->FileName, expected ), "info->FileName is %s, expected %s.\n", wine_dbgstr_w( info->FileName ), wine_dbgstr_w( expected )); @@ -1244,35 +1341,30 @@ static void test_file_all_name_information(void) ok(U(io).Status == STATUS_BUFFER_OVERFLOW, "io.Status is %#x, expected %#x.\n", U(io).Status, STATUS_BUFFER_OVERFLOW); ok(info->NameInformation.FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), - "info->NameInformation.FileNameLength is %u, expected %u.\n", - info->NameInformation.FileNameLength, lstrlenW( expected ) * sizeof(WCHAR)); + "info->NameInformation.FileNameLength is %u\n", info->NameInformation.FileNameLength ); ok(info->NameInformation.FileName[2] == 0xcccc, "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info->NameInformation.FileName[2]); ok(CharLowerW((LPWSTR)(UINT_PTR)info->NameInformation.FileName[1]) == CharLowerW((LPWSTR)(UINT_PTR)expected[1]), "info->NameInformation.FileName[1] is %p, expected %p.\n", CharLowerW((LPWSTR)(UINT_PTR)info->NameInformation.FileName[1]), CharLowerW((LPWSTR)(UINT_PTR)expected[1])); - ok(io.Information == sizeof(*info), "io.Information is %lu, expected %u.\n", io.Information, sizeof(*info)); + ok(io.Information == sizeof(*info), "io.Information is %lu\n", io.Information); memset( info, 0xcc, info_size ); hr = pNtQueryInformationFile( h, &io, info, info_size, FileAllInformation ); ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#x, expected %#x.\n", hr, STATUS_SUCCESS); ok(U(io).Status == STATUS_SUCCESS, "io.Status is %#x, expected %#x.\n", U(io).Status, STATUS_SUCCESS); ok(info->NameInformation.FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), - "info->NameInformation.FileNameLength is %u, expected %u.\n", - info->NameInformation.FileNameLength, lstrlenW( expected ) * sizeof(WCHAR)); + "info->NameInformation.FileNameLength is %u\n", info->NameInformation.FileNameLength ); ok(info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] == 0xcccc, - "info->NameInformation.FileName[%u] is %#x, expected 0xcccc.\n", - info->NameInformation.FileNameLength / sizeof(WCHAR), - info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)]); + "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n", + info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)]); info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] = '\0'; ok(!lstrcmpiW( info->NameInformation.FileName, expected ), "info->NameInformation.FileName is %s, expected %s.\n", wine_dbgstr_w( info->NameInformation.FileName ), wine_dbgstr_w( expected )); ok(io.Information == FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + info->NameInformation.FileNameLength, - "io.Information is %lu, expected %u.\n", - io.Information, - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + info->NameInformation.FileNameLength); + "io.Information is %lu\n", io.Information ); CloseHandle( h ); HeapFree( GetProcessHeap(), 0, info ); @@ -1344,6 +1436,7 @@ START_TEST(file) pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll, "RtlWow64EnableFsRedirectionEx"); pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile"); + pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile"); pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile"); pNtDeleteFile = (void *)GetProcAddress(hntdll, "NtDeleteFile"); pNtReadFile = (void *)GetProcAddress(hntdll, "NtReadFile"); @@ -1360,6 +1453,7 @@ START_TEST(file) pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile"); pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile"); + create_file_test(); open_file_test(); delete_file_test(); read_file_test(); diff --git a/dlls/ntdll/tests/rtlstr.c b/dlls/ntdll/tests/rtlstr.c index ad9c5a18810..d9ba0c9eaea 100644 --- a/dlls/ntdll/tests/rtlstr.c +++ b/dlls/ntdll/tests/rtlstr.c @@ -46,6 +46,7 @@ static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(long, UNICODE_STRING *, UNI static BOOLEAN (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN); static NTSTATUS (WINAPI *pRtlFindCharInUnicodeString)(int, const UNICODE_STRING *, const UNICODE_STRING *, USHORT *); static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING); +static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); static VOID (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR); static VOID (WINAPI *pRtlInitString)(PSTRING, LPCSTR); static VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING, LPCWSTR); @@ -65,7 +66,6 @@ static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*); static BOOLEAN (WINAPI *pRtlIsTextUnicode)(LPVOID, INT, INT *); /*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/ -/*static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);*/ /*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/ /*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/ /*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/ @@ -114,6 +114,7 @@ static void InitFunctionPtrs(void) pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString"); pRtlFindCharInUnicodeString = (void *)GetProcAddress(hntdll, "RtlFindCharInUnicodeString"); pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString"); + pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString"); pRtlInitString = (void *)GetProcAddress(hntdll, "RtlInitString"); pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); @@ -467,6 +468,7 @@ static void test_RtlDuplicateUnicodeString(void) ok(memcmp(dest_str.Buffer, res_str.Buffer, dupl_ustr[test_num].res_buf_size) == 0, "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination \"%s\" expected \"%s\"\n", test_num, dupl_ustr[test_num].add_nul, dest_ansi_str.Buffer, dupl_ustr[test_num].res_buf); + if(result == STATUS_SUCCESS) pRtlFreeUnicodeString(&dest_str); } else { ok(dest_str.Buffer == NULL && dupl_ustr[test_num].res_buf == NULL, "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination %p expected %p\n", @@ -794,6 +796,8 @@ static void test_RtlUnicodeStringToAnsiString(void) ok(memcmp(ansi_str.Buffer, ustr2astr[test_num].res_buf, ustr2astr[test_num].res_buf_size) == 0, "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has ansi \"%s\" expected \"%s\"\n", test_num, ustr2astr[test_num].doalloc, ansi_str.Buffer, ustr2astr[test_num].res_buf); + if(result == STATUS_SUCCESS && ustr2astr[test_num].doalloc) + pRtlFreeAnsiString(&ansi_str); } } @@ -1850,6 +1854,7 @@ static void test_RtlStringFromGUID(void) ret = pRtlStringFromGUID(&IID_Endianess, &str); ok(ret == 0, "expected ret=0, got 0x%0x\n", ret); ok(str.Buffer && !lstrcmpiW(str.Buffer, szGuid), "Endianess broken\n"); + pRtlFreeUnicodeString(&str); } START_TEST(rtlstr) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index f568eeee044..9731069e815 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -230,7 +230,7 @@ static void VIRTUAL_DumpView( FILE_VIEW *view ) /*********************************************************************** * VIRTUAL_Dump */ -#if WINE_VM_DEBUG +#ifdef WINE_VM_DEBUG static void VIRTUAL_Dump(void) { sigset_t sigset; diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 06971ad3d02..63d6fc9ebed 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -374,6 +374,16 @@ void WINAPI IoFreeIrp( IRP *irp ) /*********************************************************************** + * IoAllocateErrorLogEntry (NTOSKRNL.EXE.@) + */ +PVOID WINAPI IoAllocateErrorLogEntry( PVOID IoObject, UCHAR EntrySize ) +{ + FIXME( "stub: %p, %u\n", IoObject, EntrySize ); + return NULL; +} + + +/*********************************************************************** * IoAllocateMdl (NTOSKRNL.EXE.@) */ PMDL WINAPI IoAllocateMdl( PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN ChargeQuota, PIRP Irp ) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index b85fcb9bd83..f6402af3e8b 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -310,7 +310,7 @@ @ stub IoAllocateAdapterChannel @ stub IoAllocateController @ stdcall IoAllocateDriverObjectExtension(ptr ptr long ptr) -@ stub IoAllocateErrorLogEntry +@ stdcall IoAllocateErrorLogEntry(ptr long) @ stdcall IoAllocateIrp(long long) @ stdcall IoAllocateMdl(ptr long long long ptr) @ stdcall IoAllocateWorkItem(ptr) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 58e8f0d6a57..583a9cbcd00 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -2062,6 +2062,7 @@ HRESULT WINAPI CoRegisterClassObject( DWORD flags, LPDWORD lpdwRegister) { + static LONG next_cookie; RegisteredClass* newClass; LPUNKNOWN foundObject; HRESULT hr; @@ -2115,11 +2116,8 @@ HRESULT WINAPI CoRegisterClassObject( newClass->pMarshaledData = NULL; newClass->RpcRegistration = NULL; - /* - * Use the address of the chain node as the cookie since we are sure it's - * unique. FIXME: not on 64-bit platforms. - */ - newClass->dwCookie = (DWORD)newClass; + if (!(newClass->dwCookie = InterlockedIncrement( &next_cookie ))) + newClass->dwCookie = InterlockedIncrement( &next_cookie ); /* * Since we're making a copy of the object pointer, we have to increase its diff --git a/dlls/ole32/errorinfo.c b/dlls/ole32/errorinfo.c index f69635bc493..39751ab6551 100644 --- a/dlls/ole32/errorinfo.c +++ b/dlls/ole32/errorinfo.c @@ -237,6 +237,10 @@ static ULONG WINAPI IErrorInfoImpl_Release( if (!ref) { TRACE("-- destroying IErrorInfo(%p)\n",This); + + ERRORINFO_SysFreeString(This->bstrSource); + ERRORINFO_SysFreeString(This->bstrDescription); + ERRORINFO_SysFreeString(This->bstrHelpFile); HeapFree(GetProcessHeap(),0,This); return 0; } diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 9a344653248..0daa4ab815d 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -1358,7 +1358,7 @@ void RPC_ExecuteCall(struct dispatch_params *params) handlecall = IMessageFilter_HandleInComingCall(COM_CurrentApt()->filter, calltype, - (HTASK)GetCurrentProcessId(), + UlongToHandle(GetCurrentProcessId()), 0 /* FIXME */, &interface_info); TRACE("IMessageFilter_HandleInComingCall returned %d\n", handlecall); diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c index 53555942faf..bfecbc72bd1 100644 --- a/dlls/ole32/stg_stream.c +++ b/dlls/ole32/stg_stream.c @@ -75,21 +75,6 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This) This->parentStorage = 0; /* - * Make sure we clean-up the block chain stream objects that we were using. - */ - if (This->bigBlockChain != 0) - { - BlockChainStream_Destroy(This->bigBlockChain); - This->bigBlockChain = 0; - } - - if (This->smallBlockChain != 0) - { - SmallBlockChainStream_Destroy(This->smallBlockChain); - This->smallBlockChain = 0; - } - - /* * Finally, free the memory used-up by the class. */ HeapFree(GetProcessHeap(), 0, This); @@ -180,73 +165,6 @@ static ULONG WINAPI StgStreamImpl_Release( } /*** - * This method will open the block chain pointed by the directory entry - * that describes the stream. - * If the stream's size is null, no chain is opened. - */ -static void StgStreamImpl_OpenBlockChain( - StgStreamImpl* This) -{ - DirEntry currentEntry; - BOOL readSuccessful; - - /* - * Make sure no old object is left over. - */ - if (This->smallBlockChain != 0) - { - SmallBlockChainStream_Destroy(This->smallBlockChain); - This->smallBlockChain = 0; - } - - if (This->bigBlockChain != 0) - { - BlockChainStream_Destroy(This->bigBlockChain); - This->bigBlockChain = 0; - } - - /* - * Read the information from the directory entry. - */ - readSuccessful = StorageImpl_ReadDirEntry(This->parentStorage->ancestorStorage, - This->dirEntry, - ¤tEntry); - - if (readSuccessful) - { - This->streamSize = currentEntry.size; - - /* - * This code supports only streams that are <32 bits in size. - */ - assert(This->streamSize.u.HighPart == 0); - - if(currentEntry.startingBlock == BLOCK_END_OF_CHAIN) - { - assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) ); - } - else - { - if ( (This->streamSize.u.HighPart == 0) && - (This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) - { - This->smallBlockChain = SmallBlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->dirEntry); - } - else - { - This->bigBlockChain = BlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->dirEntry); - } - } - } -} - -/*** * This method is part of the ISequentialStream interface. * * It reads a block of information from the stream at the current @@ -264,7 +182,6 @@ static HRESULT WINAPI StgStreamImpl_Read( StgStreamImpl* const This=(StgStreamImpl*)iface; ULONG bytesReadBuffer; - ULONG bytesToReadFromBuffer; HRESULT res; TRACE("(%p, %p, %d, %p)\n", @@ -283,60 +200,21 @@ static HRESULT WINAPI StgStreamImpl_Read( if (pcbRead==0) pcbRead = &bytesReadBuffer; - /* - * Using the known size of the stream, calculate the number of bytes - * to read from the block chain - */ - bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); - - /* - * Depending on the type of chain that was opened when the stream was constructed, - * we delegate the work to the method that reads the block chains. - */ - if (This->smallBlockChain!=0) - { - res = SmallBlockChainStream_ReadAt(This->smallBlockChain, - This->currentPosition, - bytesToReadFromBuffer, - pv, - pcbRead); + res = StorageBaseImpl_StreamReadAt(This->parentStorage, + This->dirEntry, + This->currentPosition, + cb, + pv, + pcbRead); - } - else if (This->bigBlockChain!=0) - { - res = BlockChainStream_ReadAt(This->bigBlockChain, - This->currentPosition, - bytesToReadFromBuffer, - pv, - pcbRead); - } - else + if (SUCCEEDED(res)) { /* - * Small and big block chains are both NULL. This case will happen - * when a stream starts with BLOCK_END_OF_CHAIN and has size zero. + * Advance the pointer for the number of positions read. */ - - *pcbRead = 0; - res = S_OK; - goto end; + This->currentPosition.u.LowPart += *pcbRead; } - if (SUCCEEDED(res)) - { - /* - * We should always be able to read the proper amount of data from the - * chain. - */ - assert(bytesToReadFromBuffer == *pcbRead); - - /* - * Advance the pointer for the number of positions read. - */ - This->currentPosition.u.LowPart += *pcbRead; - } - -end: TRACE("<-- %08x\n", res); return res; } @@ -359,7 +237,6 @@ static HRESULT WINAPI StgStreamImpl_Write( { StgStreamImpl* const This=(StgStreamImpl*)iface; - ULARGE_INTEGER newSize; ULONG bytesWritten = 0; HRESULT res; @@ -405,51 +282,13 @@ static HRESULT WINAPI StgStreamImpl_Write( TRACE("<-- S_OK, written 0\n"); return S_OK; } - else - { - newSize.u.HighPart = 0; - newSize.u.LowPart = This->currentPosition.u.LowPart + cb; - } - - /* - * Verify if we need to grow the stream - */ - if (newSize.u.LowPart > This->streamSize.u.LowPart) - { - /* grow stream */ - res = IStream_SetSize(iface, newSize); - if (FAILED(res)) - return res; - } - /* - * Depending on the type of chain that was opened when the stream was constructed, - * we delegate the work to the method that readwrites to the block chains. - */ - if (This->smallBlockChain!=0) - { - res = SmallBlockChainStream_WriteAt(This->smallBlockChain, - This->currentPosition, - cb, - pv, - pcbWritten); - - } - else if (This->bigBlockChain!=0) - { - res = BlockChainStream_WriteAt(This->bigBlockChain, - This->currentPosition, - cb, - pv, - pcbWritten); - } - else - { - /* this should never happen because the IStream_SetSize call above will - * make sure a big or small block chain is created */ - assert(FALSE); - res = 0; - } + res = StorageBaseImpl_StreamWriteAt(This->parentStorage, + This->dirEntry, + This->currentPosition, + cb, + pv, + pcbWritten); /* * Advance the position pointer for the number of positions written. @@ -477,6 +316,8 @@ static HRESULT WINAPI StgStreamImpl_Seek( StgStreamImpl* const This=(StgStreamImpl*)iface; ULARGE_INTEGER newPosition; + DirEntry currentEntry; + HRESULT hr; TRACE("(%p, %d, %d, %p)\n", iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition); @@ -515,7 +356,9 @@ static HRESULT WINAPI StgStreamImpl_Seek( *plibNewPosition = This->currentPosition; break; case STREAM_SEEK_END: - *plibNewPosition = This->streamSize; + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, ¤tEntry); + if (FAILED(hr)) return hr; + *plibNewPosition = currentEntry.size; break; default: WARN("invalid dwOrigin %d\n", dwOrigin); @@ -545,8 +388,7 @@ static HRESULT WINAPI StgStreamImpl_SetSize( { StgStreamImpl* const This=(StgStreamImpl*)iface; - DirEntry currentEntry; - BOOL Success; + HRESULT hr; TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart); @@ -574,99 +416,8 @@ static HRESULT WINAPI StgStreamImpl_SetSize( return STG_E_ACCESSDENIED; } - /* In simple mode keep the stream size above the small block limit */ - if (This->parentStorage->openFlags & STGM_SIMPLE) - libNewSize.u.LowPart = max(libNewSize.u.LowPart, LIMIT_TO_USE_SMALL_BLOCK); - - if (This->streamSize.u.LowPart == libNewSize.u.LowPart) - return S_OK; - - /* - * This will happen if we're creating a stream - */ - if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0)) - { - if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) - { - This->smallBlockChain = SmallBlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->dirEntry); - } - else - { - This->bigBlockChain = BlockChainStream_Construct( - This->parentStorage->ancestorStorage, - NULL, - This->dirEntry); - } - } - - /* - * Read this stream's size to see if it's small blocks or big blocks - */ - Success = StorageImpl_ReadDirEntry(This->parentStorage->ancestorStorage, - This->dirEntry, - ¤tEntry); - /* - * Determine if we have to switch from small to big blocks or vice versa - */ - if ( (This->smallBlockChain!=0) && - (currentEntry.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) - { - if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) - { - /* - * Transform the small block chain into a big block chain - */ - This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks( - This->parentStorage->ancestorStorage, - &This->smallBlockChain); - } - } - else if ( (This->bigBlockChain!=0) && - (currentEntry.size.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) ) - { - if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) - { - /* - * Transform the big block chain into a small block chain - */ - This->smallBlockChain = Storage32Impl_BigBlocksToSmallBlocks( - This->parentStorage->ancestorStorage, - &This->bigBlockChain); - } - } - - if (This->smallBlockChain!=0) - { - Success = SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize); - } - else - { - Success = BlockChainStream_SetSize(This->bigBlockChain, libNewSize); - } - - /* - * Write the new information about this stream to the directory entry - */ - Success = StorageImpl_ReadDirEntry(This->parentStorage->ancestorStorage, - This->dirEntry, - ¤tEntry); - - currentEntry.size.u.HighPart = libNewSize.u.HighPart; - currentEntry.size.u.LowPart = libNewSize.u.LowPart; - - if (Success) - { - StorageImpl_WriteDirEntry(This->parentStorage->ancestorStorage, - This->dirEntry, - ¤tEntry); - } - - This->streamSize = libNewSize; - - return S_OK; + hr = StorageBaseImpl_StreamSetSize(This->parentStorage, This->dirEntry, libNewSize); + return hr; } /*** @@ -835,7 +586,7 @@ static HRESULT WINAPI StgStreamImpl_Stat( StgStreamImpl* const This=(StgStreamImpl*)iface; DirEntry currentEntry; - BOOL readSuccessful; + HRESULT hr; TRACE("%p %p %d\n", This, pstatstg, grfStatFlag); @@ -852,11 +603,11 @@ static HRESULT WINAPI StgStreamImpl_Stat( /* * Read the information from the directory entry. */ - readSuccessful = StorageImpl_ReadDirEntry(This->parentStorage->ancestorStorage, + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->dirEntry, ¤tEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { StorageUtl_CopyDirEntryToSTATSTG(This->parentStorage, pstatstg, @@ -873,7 +624,7 @@ static HRESULT WINAPI StgStreamImpl_Stat( } WARN("failed to read entry\n"); - return E_FAIL; + return hr; } /*** @@ -998,20 +749,6 @@ StgStreamImpl* StgStreamImpl_Construct( newStream->currentPosition.u.HighPart = 0; newStream->currentPosition.u.LowPart = 0; - /* - * Initialize the rest of the data. - */ - newStream->streamSize.u.HighPart = 0; - newStream->streamSize.u.LowPart = 0; - newStream->bigBlockChain = 0; - newStream->smallBlockChain = 0; - - /* - * Read the size from the directory entry and determine if the blocks forming - * this stream are large or small. - */ - StgStreamImpl_OpenBlockChain(newStream); - /* add us to the storage's list of active streams */ StorageBaseImpl_AddStream(parentStorage, newStream); } diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 384722dc027..479c2a54b8a 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -82,13 +82,16 @@ struct StorageInternalImpl * Entry in the parent's stream tracking list */ struct list ParentListEntry; + + StorageBaseImpl *parentStorage; }; typedef struct StorageInternalImpl StorageInternalImpl; /* Method definitions for the Storage32InternalImpl class. */ -static StorageInternalImpl* StorageInternalImpl_Construct(StorageImpl* ancestorStorage, +static StorageInternalImpl* StorageInternalImpl_Construct(StorageBaseImpl* parentStorage, DWORD openFlags, DirRef storageDirEntry); static void StorageImpl_Destroy(StorageBaseImpl* iface); +static void StorageImpl_Invalidate(StorageBaseImpl* iface); static BOOL StorageImpl_ReadBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer); static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, const void* buffer); static void StorageImpl_SetNextBlockInChain(StorageImpl* This, ULONG blockIndex, ULONG nextBlock); @@ -114,7 +117,27 @@ static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This, static BOOL StorageBaseImpl_IsStreamOpen(StorageBaseImpl * stg, DirRef streamEntry); static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageEntry); -static void StorageInternalImpl_Invalidate( StorageInternalImpl *This ); + +/**************************************************************************** + * Transacted storage object that reads/writes a snapshot file. + */ +typedef struct TransactedSnapshotImpl +{ + struct StorageBaseImpl base; + + /* + * Changes are temporarily saved to the snapshot. + */ + StorageBaseImpl *snapshot; + + /* + * Changes are committed to the transacted parent. + */ + StorageBaseImpl *transactedParent; +} TransactedSnapshotImpl; + +/* Generic function to create a transacted wrapper for a direct storage object. */ +static HRESULT Storage_ConstructTransacted(StorageBaseImpl* parent, StorageBaseImpl** result); /* OLESTREAM memory structure to use for Get and Put Routines */ /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ @@ -176,7 +199,7 @@ static HRESULT deleteStreamContents( DirEntry entryDataToDelete); static HRESULT removeFromTree( - StorageImpl *This, + StorageBaseImpl *This, DirRef parentStorageIndex, DirRef deletedIndex); @@ -184,17 +207,8 @@ static HRESULT removeFromTree( * Declaration of the functions used to manipulate DirEntry */ -static HRESULT createDirEntry( - StorageImpl *storage, - const DirEntry *newData, - DirRef *index); - -static HRESULT destroyDirEntry( - StorageImpl *storage, - DirRef index); - static HRESULT insertIntoTree( - StorageImpl *This, + StorageBaseImpl *This, DirRef parentStorageIndex, DirRef newEntryIndex); @@ -203,13 +217,13 @@ static LONG entryNameCmp( const OLECHAR *name2); static DirRef findElement( - StorageImpl *storage, + StorageBaseImpl *storage, DirRef storageEntry, const OLECHAR *name, DirEntry *data); static HRESULT findTreeParent( - StorageImpl *storage, + StorageBaseImpl *storage, DirRef storageEntry, const OLECHAR *childName, DirEntry *parentData, @@ -241,7 +255,7 @@ struct IEnumSTATSTGImpl * since we want to cast this in an IEnumSTATSTG pointer */ LONG ref; /* Reference count */ - StorageImpl* parentStorage; /* Reference to the parent storage */ + StorageBaseImpl* parentStorage; /* Reference to the parent storage */ DirRef storageDirEntry; /* Directory entry of the storage to enumerate */ /* @@ -257,7 +271,7 @@ struct IEnumSTATSTGImpl }; -static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageImpl* This, DirRef storageDirEntry); +static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(StorageBaseImpl* This, DirRef storageDirEntry); static void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This); static void IEnumSTATSTGImpl_PushSearchNode(IEnumSTATSTGImpl* This, DirRef nodeToPush); static DirRef IEnumSTATSTGImpl_PopSearchNode(IEnumSTATSTGImpl* This, BOOL remove); @@ -432,7 +446,7 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( goto end; } - if (!This->ancestorStorage) + if (This->reverted) { res = STG_E_REVERTED; goto end; @@ -442,7 +456,7 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( * Check that we're compatible with the parent's storage mode, but * only if we are not in transacted mode */ - if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) { + if(!(This->openFlags & STGM_TRANSACTED)) { if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) { res = STG_E_ACCESSDENIED; @@ -454,7 +468,7 @@ static HRESULT WINAPI StorageBaseImpl_OpenStream( * Search for the element with the given name */ streamEntryRef = findElement( - This->ancestorStorage, + This, This->storageDirEntry, pwcsName, ¤tEntry); @@ -515,7 +529,8 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( IStorage** ppstg) /* [out] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - StorageInternalImpl* newStorage; + StorageInternalImpl* newStorage; + StorageBaseImpl* newTransactedStorage; DirEntry currentEntry; DirRef storageEntryRef; HRESULT res = STG_E_UNKNOWN; @@ -560,14 +575,14 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( goto end; } - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; /* * Check that we're compatible with the parent's storage mode, * but only if we are not transacted */ - if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) { + if(!(This->openFlags & STGM_TRANSACTED)) { if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) { res = STG_E_ACCESSDENIED; @@ -578,7 +593,7 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( *ppstg = NULL; storageEntryRef = findElement( - This->ancestorStorage, + This, This->storageDirEntry, pwcsName, ¤tEntry); @@ -594,15 +609,28 @@ static HRESULT WINAPI StorageBaseImpl_OpenStorage( } newStorage = StorageInternalImpl_Construct( - This->ancestorStorage, + This, grfMode, storageEntryRef); if (newStorage != 0) { - *ppstg = (IStorage*)newStorage; + if (grfMode & STGM_TRANSACTED) + { + res = Storage_ConstructTransacted(&newStorage->base, &newTransactedStorage); + + if (FAILED(res)) + { + HeapFree(GetProcessHeap(), 0, newStorage); + goto end; + } - StorageBaseImpl_AddRef(*ppstg); + *ppstg = (IStorage*)newTransactedStorage; + } + else + { + *ppstg = (IStorage*)newStorage; + } list_add_tail(&This->storageHead, &newStorage->ParentListEntry); @@ -645,11 +673,11 @@ static HRESULT WINAPI StorageBaseImpl_EnumElements( if ( (This==0) || (ppenum==0)) return E_INVALIDARG; - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; newEnum = IEnumSTATSTGImpl_Construct( - This->ancestorStorage, + This, This->storageDirEntry); if (newEnum!=0) @@ -678,7 +706,6 @@ static HRESULT WINAPI StorageBaseImpl_Stat( { StorageBaseImpl *This = (StorageBaseImpl *)iface; DirEntry currentEntry; - BOOL readSuccessful; HRESULT res = STG_E_UNKNOWN; TRACE("(%p, %p, %x)\n", @@ -690,18 +717,18 @@ static HRESULT WINAPI StorageBaseImpl_Stat( goto end; } - if (!This->ancestorStorage) + if (This->reverted) { res = STG_E_REVERTED; goto end; } - readSuccessful = StorageImpl_ReadDirEntry( - This->ancestorStorage, + res = StorageBaseImpl_ReadDirEntry( + This, This->storageDirEntry, ¤tEntry); - if (readSuccessful) + if (SUCCEEDED(res)) { StorageUtl_CopyDirEntryToSTATSTG( This, @@ -711,13 +738,8 @@ static HRESULT WINAPI StorageBaseImpl_Stat( pstatstg->grfMode = This->openFlags; pstatstg->grfStateBits = This->stateBits; - - res = S_OK; - goto end; } - res = E_FAIL; - end: if (res == S_OK) { @@ -746,10 +768,10 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement( TRACE("(%p, %s, %s)\n", iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName)); - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; - currentEntryRef = findElement(This->ancestorStorage, + currentEntryRef = findElement(This, This->storageDirEntry, pwcsNewName, ¤tEntry); @@ -765,7 +787,7 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement( /* * Search for the old element name */ - currentEntryRef = findElement(This->ancestorStorage, + currentEntryRef = findElement(This, This->storageDirEntry, pwcsOldName, ¤tEntry); @@ -780,17 +802,17 @@ static HRESULT WINAPI StorageBaseImpl_RenameElement( } /* Remove the element from its current position in the tree */ - removeFromTree(This->ancestorStorage, This->storageDirEntry, + removeFromTree(This, This->storageDirEntry, currentEntryRef); /* Change the name of the element */ strcpyW(currentEntry.name, pwcsNewName); - StorageImpl_WriteDirEntry(This->ancestorStorage, currentEntryRef, + StorageBaseImpl_WriteDirEntry(This, currentEntryRef, ¤tEntry); /* Insert the element in a new position in the tree */ - insertIntoTree(This->ancestorStorage, This->storageDirEntry, + insertIntoTree(This, This->storageDirEntry, currentEntryRef); } else @@ -843,7 +865,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( if (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE) return STG_E_INVALIDFLAG; - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; /* @@ -861,7 +883,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( * Check that we're compatible with the parent's storage mode * if not in transacted mode */ - if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) { + if(!(This->openFlags & STGM_TRANSACTED)) { if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) ) return STG_E_ACCESSDENIED; } @@ -871,7 +893,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( *ppstm = 0; - currentEntryRef = findElement(This->ancestorStorage, + currentEntryRef = findElement(This, This->storageDirEntry, pwcsName, ¤tEntry); @@ -926,13 +948,12 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream( /* * Create an entry with the new data */ - createDirEntry(This->ancestorStorage, &newStreamEntry, &newStreamEntryRef); - + StorageBaseImpl_CreateDirEntry(This, &newStreamEntry, &newStreamEntryRef); /* * Insert the new entry in the parent storage's tree. */ insertIntoTree( - This->ancestorStorage, + This, This->storageDirEntry, newStreamEntryRef); @@ -968,27 +989,24 @@ static HRESULT WINAPI StorageBaseImpl_SetClass( REFCLSID clsid) /* [in] */ { StorageBaseImpl *This = (StorageBaseImpl *)iface; - HRESULT hRes = E_FAIL; + HRESULT hRes; DirEntry currentEntry; - BOOL success; TRACE("(%p, %p)\n", iface, clsid); - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; - success = StorageImpl_ReadDirEntry(This->ancestorStorage, - This->storageDirEntry, - ¤tEntry); - if (success) + hRes = StorageBaseImpl_ReadDirEntry(This, + This->storageDirEntry, + ¤tEntry); + if (SUCCEEDED(hRes)) { currentEntry.clsid = *clsid; - success = StorageImpl_WriteDirEntry(This->ancestorStorage, - This->storageDirEntry, - ¤tEntry); - if (success) - hRes = S_OK; + hRes = StorageBaseImpl_WriteDirEntry(This, + This->storageDirEntry, + ¤tEntry); } return hRes; @@ -1045,7 +1063,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStorage( return STG_E_INVALIDFLAG; } - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; /* @@ -1057,7 +1075,7 @@ static HRESULT WINAPI StorageBaseImpl_CreateStorage( return STG_E_ACCESSDENIED; } - currentEntryRef = findElement(This->ancestorStorage, + currentEntryRef = findElement(This, This->storageDirEntry, pwcsName, ¤tEntry); @@ -1117,13 +1135,13 @@ static HRESULT WINAPI StorageBaseImpl_CreateStorage( /* * Create a new directory entry for the storage */ - createDirEntry(This->ancestorStorage, &newEntry, &newEntryRef); + StorageBaseImpl_CreateDirEntry(This, &newEntry, &newEntryRef); /* * Insert the new directory entry into the parent storage's tree */ insertIntoTree( - This->ancestorStorage, + This, This->storageDirEntry, newEntryRef); @@ -1148,11 +1166,12 @@ static HRESULT WINAPI StorageBaseImpl_CreateStorage( * * Reserve a directory entry in the file and initialize it. */ -static HRESULT createDirEntry( - StorageImpl *storage, +static HRESULT StorageImpl_CreateDirEntry( + StorageBaseImpl *base, const DirEntry *newData, DirRef *index) { + StorageImpl *storage = (StorageImpl*)base; ULONG currentEntryIndex = 0; ULONG newEntryIndex = DIRENTRY_NULL; HRESULT hr = S_OK; @@ -1258,12 +1277,13 @@ static HRESULT createDirEntry( * * Mark a directory entry in the file as free. */ -static HRESULT destroyDirEntry( - StorageImpl *storage, +static HRESULT StorageImpl_DestroyDirEntry( + StorageBaseImpl *base, DirRef index) { HRESULT hr; BYTE emptyData[RAW_DIRENTRY_SIZE]; + StorageImpl *storage = (StorageImpl*)base; memset(&emptyData, 0, RAW_DIRENTRY_SIZE); @@ -1273,6 +1293,46 @@ static HRESULT destroyDirEntry( } +/*************************************************************************** + * + * Internal Method + * + * Destroy an entry, its attached data, and all entries reachable from it. + */ +static HRESULT DestroyReachableEntries( + StorageBaseImpl *base, + DirRef index) +{ + HRESULT hr = S_OK; + DirEntry data; + ULARGE_INTEGER zero; + + zero.QuadPart = 0; + + if (index != DIRENTRY_NULL) + { + hr = StorageBaseImpl_ReadDirEntry(base, index, &data); + + if (SUCCEEDED(hr)) + hr = DestroyReachableEntries(base, data.dirRootEntry); + + if (SUCCEEDED(hr)) + hr = DestroyReachableEntries(base, data.leftChild); + + if (SUCCEEDED(hr)) + hr = DestroyReachableEntries(base, data.rightChild); + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_StreamSetSize(base, index, zero); + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_DestroyDirEntry(base, index); + } + + return hr; +} + + /**************************************************************************** * * Internal Method @@ -1308,7 +1368,7 @@ static LONG entryNameCmp( * Add a directory entry to a storage */ static HRESULT insertIntoTree( - StorageImpl *This, + StorageBaseImpl *This, DirRef parentStorageIndex, DirRef newEntryIndex) { @@ -1318,16 +1378,16 @@ static HRESULT insertIntoTree( /* * Read the inserted entry */ - StorageImpl_ReadDirEntry(This, - newEntryIndex, - &newEntry); + StorageBaseImpl_ReadDirEntry(This, + newEntryIndex, + &newEntry); /* * Read the storage entry */ - StorageImpl_ReadDirEntry(This, - parentStorageIndex, - ¤tEntry); + StorageBaseImpl_ReadDirEntry(This, + parentStorageIndex, + ¤tEntry); if (currentEntry.dirRootEntry != DIRENTRY_NULL) { @@ -1346,9 +1406,9 @@ static HRESULT insertIntoTree( /* * Read */ - StorageImpl_ReadDirEntry(This, - currentEntry.dirRootEntry, - ¤tEntry); + StorageBaseImpl_ReadDirEntry(This, + currentEntry.dirRootEntry, + ¤tEntry); previous = currentEntry.leftChild; next = currentEntry.rightChild; @@ -1362,17 +1422,17 @@ static HRESULT insertIntoTree( { if (previous != DIRENTRY_NULL) { - StorageImpl_ReadDirEntry(This, - previous, - ¤tEntry); + StorageBaseImpl_ReadDirEntry(This, + previous, + ¤tEntry); current = previous; } else { currentEntry.leftChild = newEntryIndex; - StorageImpl_WriteDirEntry(This, - current, - ¤tEntry); + StorageBaseImpl_WriteDirEntry(This, + current, + ¤tEntry); found = 1; } } @@ -1380,17 +1440,17 @@ static HRESULT insertIntoTree( { if (next != DIRENTRY_NULL) { - StorageImpl_ReadDirEntry(This, - next, - ¤tEntry); + StorageBaseImpl_ReadDirEntry(This, + next, + ¤tEntry); current = next; } else { currentEntry.rightChild = newEntryIndex; - StorageImpl_WriteDirEntry(This, - current, - ¤tEntry); + StorageBaseImpl_WriteDirEntry(This, + current, + ¤tEntry); found = 1; } } @@ -1413,9 +1473,9 @@ static HRESULT insertIntoTree( * The storage is empty, make the new entry the root of its element tree */ currentEntry.dirRootEntry = newEntryIndex; - StorageImpl_WriteDirEntry(This, - parentStorageIndex, - ¤tEntry); + StorageBaseImpl_WriteDirEntry(This, + parentStorageIndex, + ¤tEntry); } return S_OK; @@ -1427,13 +1487,13 @@ static HRESULT insertIntoTree( * * Find and read the element of a storage with the given name. */ -static DirRef findElement(StorageImpl *storage, DirRef storageEntry, +static DirRef findElement(StorageBaseImpl *storage, DirRef storageEntry, const OLECHAR *name, DirEntry *data) { DirRef currentEntry; /* Read the storage entry to find the root of the tree. */ - StorageImpl_ReadDirEntry(storage, storageEntry, data); + StorageBaseImpl_ReadDirEntry(storage, storageEntry, data); currentEntry = data->dirRootEntry; @@ -1441,7 +1501,7 @@ static DirRef findElement(StorageImpl *storage, DirRef storageEntry, { LONG cmp; - StorageImpl_ReadDirEntry(storage, currentEntry, data); + StorageBaseImpl_ReadDirEntry(storage, currentEntry, data); cmp = entryNameCmp(name, data->name); @@ -1468,7 +1528,7 @@ static DirRef findElement(StorageImpl *storage, DirRef storageEntry, * If there is no such element, find a place where it could be inserted and * return STG_E_FILENOTFOUND. */ -static HRESULT findTreeParent(StorageImpl *storage, DirRef storageEntry, +static HRESULT findTreeParent(StorageBaseImpl *storage, DirRef storageEntry, const OLECHAR *childName, DirEntry *parentData, DirRef *parentEntry, ULONG *relation) { @@ -1476,7 +1536,7 @@ static HRESULT findTreeParent(StorageImpl *storage, DirRef storageEntry, DirEntry childData; /* Read the storage entry to find the root of the tree. */ - StorageImpl_ReadDirEntry(storage, storageEntry, parentData); + StorageBaseImpl_ReadDirEntry(storage, storageEntry, parentData); *parentEntry = storageEntry; *relation = DIRENTRY_RELATION_DIR; @@ -1487,7 +1547,7 @@ static HRESULT findTreeParent(StorageImpl *storage, DirRef storageEntry, { LONG cmp; - StorageImpl_ReadDirEntry(storage, childEntry, &childData); + StorageBaseImpl_ReadDirEntry(storage, childEntry, &childData); cmp = entryNameCmp(childName, childData.name); @@ -1787,14 +1847,14 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement( if (pwcsName==NULL) return STG_E_INVALIDPOINTER; - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; if ( STGM_ACCESS_MODE( This->openFlags ) == STGM_READ ) return STG_E_ACCESSDENIED; entryToDeleteRef = findElement( - This->ancestorStorage, + This, This->storageDirEntry, pwcsName, &entryToDelete); @@ -1826,7 +1886,7 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement( * Remove the entry from its parent storage */ hr = removeFromTree( - This->ancestorStorage, + This, This->storageDirEntry, entryToDeleteRef); @@ -1834,8 +1894,7 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement( * Invalidate the entry */ if (SUCCEEDED(hr)) - destroyDirEntry(This->ancestorStorage, - entryToDeleteRef); + StorageBaseImpl_DestroyDirEntry(This, entryToDeleteRef); return hr; } @@ -1902,7 +1961,14 @@ static void StorageBaseImpl_DeleteAll(StorageBaseImpl * stg) LIST_FOR_EACH_SAFE(cur, cur2, &stg->storageHead) { childstg = LIST_ENTRY(cur,StorageInternalImpl,ParentListEntry); - StorageInternalImpl_Invalidate( childstg ); + StorageBaseImpl_Invalidate( &childstg->base ); + } + + if (stg->transactedChild) + { + StorageBaseImpl_Invalidate(stg->transactedChild); + + stg->transactedChild = NULL; } } @@ -1931,7 +1997,7 @@ static HRESULT deleteStorageContents( { if (stg->base.storageDirEntry == indexToDelete) { - StorageInternalImpl_Invalidate(stg); + StorageBaseImpl_Invalidate(&stg->base); } } @@ -2067,18 +2133,20 @@ static void setEntryLink(DirEntry *entry, ULONG relation, DirRef new_target) * freeing any resources attached to it. */ static HRESULT removeFromTree( - StorageImpl *This, + StorageBaseImpl *This, DirRef parentStorageIndex, DirRef deletedIndex) { HRESULT hr = S_OK; - BOOL res = TRUE; DirEntry entryToDelete; DirEntry parentEntry; DirRef parentEntryRef; ULONG typeOfRelation; - res = StorageImpl_ReadDirEntry(This, deletedIndex, &entryToDelete); + hr = StorageBaseImpl_ReadDirEntry(This, deletedIndex, &entryToDelete); + + if (hr != S_OK) + return hr; /* * Find the element that links to the one we want to delete. @@ -2096,13 +2164,13 @@ static HRESULT removeFromTree( */ setEntryLink(&parentEntry, typeOfRelation, entryToDelete.leftChild); - res = StorageImpl_WriteDirEntry( + hr = StorageBaseImpl_WriteDirEntry( This, parentEntryRef, &parentEntry); - if(!res) + if(FAILED(hr)) { - return E_FAIL; + return hr; } if (entryToDelete.rightChild != DIRENTRY_NULL) @@ -2117,13 +2185,13 @@ static HRESULT removeFromTree( do { - res = StorageImpl_ReadDirEntry( + hr = StorageBaseImpl_ReadDirEntry( This, newRightChildParent, &newRightChildParentEntry); - if (!res) + if (FAILED(hr)) { - return E_FAIL; + return hr; } if (newRightChildParentEntry.rightChild != DIRENTRY_NULL) @@ -2132,13 +2200,13 @@ static HRESULT removeFromTree( newRightChildParentEntry.rightChild = entryToDelete.rightChild; - res = StorageImpl_WriteDirEntry( + hr = StorageBaseImpl_WriteDirEntry( This, newRightChildParent, &newRightChildParentEntry); - if (!res) + if (FAILED(hr)) { - return E_FAIL; + return hr; } } } @@ -2149,13 +2217,13 @@ static HRESULT removeFromTree( */ setEntryLink(&parentEntry, typeOfRelation, entryToDelete.rightChild); - res = StorageImpl_WriteDirEntry( + hr = StorageBaseImpl_WriteDirEntry( This, parentEntryRef, &parentEntry); - if(!res) + if(FAILED(hr)) { - return E_FAIL; + return hr; } } @@ -2187,13 +2255,220 @@ static HRESULT WINAPI StorageBaseImpl_SetStateBits( { StorageBaseImpl* const This = (StorageBaseImpl*)iface; - if (!This->ancestorStorage) + if (This->reverted) return STG_E_REVERTED; This->stateBits = (This->stateBits & ~grfMask) | (grfStateBits & grfMask); return S_OK; } +static HRESULT StorageImpl_BaseWriteDirEntry(StorageBaseImpl *base, + DirRef index, const DirEntry *data) +{ + StorageImpl *This = (StorageImpl*)base; + return StorageImpl_WriteDirEntry(This, index, data); +} + +static HRESULT StorageImpl_BaseReadDirEntry(StorageBaseImpl *base, + DirRef index, DirEntry *data) +{ + StorageImpl *This = (StorageImpl*)base; + return StorageImpl_ReadDirEntry(This, index, data); +} + +static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + ULONG bytesToRead; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + if (data.size.QuadPart == 0) + { + *bytesRead = 0; + return S_OK; + } + + if (offset.QuadPart + size > data.size.QuadPart) + { + bytesToRead = data.size.QuadPart - offset.QuadPart; + } + else + { + bytesToRead = size; + } + + if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + SmallBlockChainStream *stream; + + stream = SmallBlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = SmallBlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead); + + SmallBlockChainStream_Destroy(stream); + + return hr; + } + else + { + BlockChainStream *stream; + + stream = BlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = BlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead); + + BlockChainStream_Destroy(stream); + + return hr; + } +} + +static HRESULT StorageImpl_StreamSetSize(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER newsize) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + SmallBlockChainStream *smallblock=NULL; + BlockChainStream *bigblock=NULL; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + /* In simple mode keep the stream size above the small block limit */ + if (This->base.openFlags & STGM_SIMPLE) + newsize.QuadPart = max(newsize.QuadPart, LIMIT_TO_USE_SMALL_BLOCK); + + if (data.size.QuadPart == newsize.QuadPart) + return S_OK; + + /* Create a block chain object of the appropriate type */ + if (data.size.QuadPart == 0) + { + if (newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = SmallBlockChainStream_Construct(This, NULL, index); + if (!smallblock) return E_OUTOFMEMORY; + } + else + { + bigblock = BlockChainStream_Construct(This, NULL, index); + if (!bigblock) return E_OUTOFMEMORY; + } + } + else if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = SmallBlockChainStream_Construct(This, NULL, index); + if (!smallblock) return E_OUTOFMEMORY; + } + else + { + bigblock = BlockChainStream_Construct(This, NULL, index); + if (!bigblock) return E_OUTOFMEMORY; + } + + /* Change the block chain type if necessary. */ + if (smallblock && newsize.QuadPart >= LIMIT_TO_USE_SMALL_BLOCK) + { + bigblock = Storage32Impl_SmallBlocksToBigBlocks(This, &smallblock); + if (!bigblock) + { + SmallBlockChainStream_Destroy(smallblock); + return E_FAIL; + } + } + else if (bigblock && newsize.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + smallblock = Storage32Impl_BigBlocksToSmallBlocks(This, &bigblock); + if (!smallblock) + { + BlockChainStream_Destroy(bigblock); + return E_FAIL; + } + } + + /* Set the size of the block chain. */ + if (smallblock) + { + SmallBlockChainStream_SetSize(smallblock, newsize); + SmallBlockChainStream_Destroy(smallblock); + } + else + { + BlockChainStream_SetSize(bigblock, newsize); + BlockChainStream_Destroy(bigblock); + } + + /* Set the size in the directory entry. */ + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (SUCCEEDED(hr)) + { + data.size = newsize; + + hr = StorageImpl_WriteDirEntry(This, index, &data); + } + return hr; +} + +static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, + ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry data; + HRESULT hr; + ULARGE_INTEGER newSize; + + hr = StorageImpl_ReadDirEntry(This, index, &data); + if (FAILED(hr)) return hr; + + /* Grow the stream if necessary */ + newSize.QuadPart = 0; + newSize.QuadPart = offset.QuadPart + size; + + if (newSize.QuadPart > data.size.QuadPart) + { + hr = StorageImpl_StreamSetSize(base, index, newSize); + if (FAILED(hr)) + return hr; + + data.size = newSize; + } + + if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK) + { + SmallBlockChainStream *stream; + + stream = SmallBlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = SmallBlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten); + + SmallBlockChainStream_Destroy(stream); + + return hr; + } + else + { + BlockChainStream *stream; + + stream = BlockChainStream_Construct(This, NULL, index); + if (!stream) return E_OUTOFMEMORY; + + hr = BlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten); + + BlockChainStream_Destroy(stream); + + return hr; + } +} + /* * Virtual function table for the IStorage32Impl class. */ @@ -2221,7 +2496,15 @@ static const IStorageVtbl Storage32Impl_Vtbl = static const StorageBaseImplVtbl StorageImpl_BaseVtbl = { - StorageImpl_Destroy + StorageImpl_Destroy, + StorageImpl_Invalidate, + StorageImpl_CreateDirEntry, + StorageImpl_BaseWriteDirEntry, + StorageImpl_BaseReadDirEntry, + StorageImpl_DestroyDirEntry, + StorageImpl_StreamReadAt, + StorageImpl_StreamWriteAt, + StorageImpl_StreamSetSize }; static HRESULT StorageImpl_Construct( @@ -2236,8 +2519,8 @@ static HRESULT StorageImpl_Construct( StorageImpl* This; HRESULT hr = S_OK; DirEntry currentEntry; - BOOL readSuccessful; DirRef currentEntryRef; + WCHAR fullpath[MAX_PATH]; if ( FAILED( validateSTGM(openFlags) )) return STG_E_INVALIDFLAG; @@ -2259,26 +2542,24 @@ static HRESULT StorageImpl_Construct( This->base.ref = 1; This->base.create = create; - /* - * This is the top-level storage so initialize the ancestor pointer - * to this. - */ - This->base.ancestorStorage = This; + This->base.reverted = 0; This->hFile = hFile; if(pwcsName) { + if (!GetFullPathNameW(pwcsName, MAX_PATH, fullpath, NULL)) + { + lstrcpynW(fullpath, pwcsName, MAX_PATH); + } This->pwcsName = HeapAlloc(GetProcessHeap(), 0, - (lstrlenW(pwcsName)+1)*sizeof(WCHAR)); + (lstrlenW(fullpath)+1)*sizeof(WCHAR)); if (!This->pwcsName) { hr = STG_E_INSUFFICIENTMEMORY; goto end; } - strcpyW(This->pwcsName, pwcsName); - - memcpy(This->base.filename, pwcsName, DIRENTRY_NAME_BUFFER_LEN-1); - This->base.filename[DIRENTRY_NAME_BUFFER_LEN-1] = 0; + strcpyW(This->pwcsName, fullpath); + This->base.filename = This->pwcsName; } /* @@ -2411,12 +2692,12 @@ static HRESULT StorageImpl_Construct( do { - readSuccessful = StorageImpl_ReadDirEntry( + hr = StorageImpl_ReadDirEntry( This, currentEntryRef, ¤tEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { if ( (currentEntry.sizeOfNameString != 0 ) && (currentEntry.stgType == STGTY_ROOT) ) @@ -2427,9 +2708,9 @@ static HRESULT StorageImpl_Construct( currentEntryRef++; - } while (readSuccessful && (This->base.storageDirEntry == DIRENTRY_NULL) ); + } while (SUCCEEDED(hr) && (This->base.storageDirEntry == DIRENTRY_NULL) ); - if (!readSuccessful) + if (FAILED(hr)) { hr = STG_E_READFAULT; goto end; @@ -2456,12 +2737,21 @@ end: return hr; } +static void StorageImpl_Invalidate(StorageBaseImpl* iface) +{ + StorageImpl *This = (StorageImpl*) iface; + + StorageBaseImpl_DeleteAll(&This->base); + + This->base.reverted = 1; +} + static void StorageImpl_Destroy(StorageBaseImpl* iface) { StorageImpl *This = (StorageImpl*) iface; TRACE("(%p)\n", This); - StorageBaseImpl_DeleteAll(&This->base); + StorageImpl_Invalidate(iface); HeapFree(GetProcessHeap(), 0, This->pwcsName); @@ -3253,7 +3543,7 @@ void UpdateRawDirEntry(BYTE *buffer, const DirEntry *newData) * * This method will read the specified directory entry. */ -BOOL StorageImpl_ReadDirEntry( +HRESULT StorageImpl_ReadDirEntry( StorageImpl* This, DirRef index, DirEntry* buffer) @@ -3332,13 +3622,13 @@ BOOL StorageImpl_ReadDirEntry( buffer->size.u.HighPart = 0; } - return SUCCEEDED(readRes) ? TRUE : FALSE; + return readRes; } /********************************************************************* * Write the specified directory entry to the file */ -BOOL StorageImpl_WriteDirEntry( +HRESULT StorageImpl_WriteDirEntry( StorageImpl* This, DirRef index, const DirEntry* buffer) @@ -3349,7 +3639,7 @@ BOOL StorageImpl_WriteDirEntry( UpdateRawDirEntry(currentEntry, buffer); writeRes = StorageImpl_WriteRawDirEntry(This, index, currentEntry); - return SUCCEEDED(writeRes) ? TRUE : FALSE; + return writeRes; } static BOOL StorageImpl_ReadBigBlock( @@ -3616,13 +3906,389 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( return SmallBlockChainStream_Construct(This, NULL, streamEntryRef); } -static void StorageInternalImpl_Invalidate( StorageInternalImpl *This ) +static HRESULT CreateSnapshotFile(StorageBaseImpl* original, StorageBaseImpl **snapshot) { - if (This->base.ancestorStorage) + HRESULT hr; + DirEntry parentData, snapshotData; + + hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DELETEONRELEASE, + 0, (IStorage**)snapshot); + + if (SUCCEEDED(hr)) + { + hr = StorageBaseImpl_ReadDirEntry(original, + original->storageDirEntry, &parentData); + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_ReadDirEntry((*snapshot), + (*snapshot)->storageDirEntry, &snapshotData); + + if (SUCCEEDED(hr)) + { + memcpy(snapshotData.name, parentData.name, sizeof(snapshotData.name)); + snapshotData.sizeOfNameString = parentData.sizeOfNameString; + snapshotData.stgType = parentData.stgType; + snapshotData.clsid = parentData.clsid; + snapshotData.ctime = parentData.ctime; + snapshotData.mtime = parentData.mtime; + hr = StorageBaseImpl_WriteDirEntry((*snapshot), + (*snapshot)->storageDirEntry, &snapshotData); + } + + if (SUCCEEDED(hr)) + hr = IStorage_CopyTo((IStorage*)original, 0, NULL, NULL, + (IStorage*)(*snapshot)); + + if (FAILED(hr)) IStorage_Release((IStorage*)(*snapshot)); + } + + return hr; +} + +static HRESULT WINAPI TransactedSnapshotImpl_Commit( + IStorage* iface, + DWORD grfCommitFlags) /* [in] */ +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + HRESULT hr; + DirEntry data, tempStorageData, snapshotRootData; + DirRef tempStorageEntry, oldDirRoot; + StorageInternalImpl *tempStorage; + + TRACE("(%p,%x)\n", iface, grfCommitFlags); + + /* Cannot commit a read-only transacted storage */ + if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ ) + return STG_E_ACCESSDENIED; + + /* To prevent data loss, we create the new structure in the file before we + * delete the old one, so that in case of errors the old data is intact. We + * shouldn't do this if STGC_OVERWRITE is set, but that flag should only be + * needed in the rare situation where we have just enough free disk space to + * overwrite the existing data. */ + + /* Create an orphaned storage in the parent for the new directory structure. */ + memset(&data, 0, sizeof(data)); + data.name[0] = 'D'; + data.sizeOfNameString = 1; + data.stgType = STGTY_STORAGE; + data.leftChild = DIRENTRY_NULL; + data.rightChild = DIRENTRY_NULL; + data.dirRootEntry = DIRENTRY_NULL; + hr = StorageBaseImpl_CreateDirEntry(This->transactedParent, &data, &tempStorageEntry); + + if (FAILED(hr)) return hr; + + tempStorage = StorageInternalImpl_Construct(This->transactedParent, + STGM_READWRITE|STGM_SHARE_EXCLUSIVE, tempStorageEntry); + if (tempStorage) + { + hr = IStorage_CopyTo((IStorage*)This->snapshot, 0, NULL, NULL, + (IStorage*)tempStorage); + + list_init(&tempStorage->ParentListEntry); + + IStorage_Release((IStorage*) tempStorage); + } + else + hr = E_OUTOFMEMORY; + + if (FAILED(hr)) + { + DestroyReachableEntries(This->transactedParent, tempStorageEntry); + return hr; + } + + /* Update the storage to use the new data in one step. */ + hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, + This->transactedParent->storageDirEntry, &data); + + if (SUCCEEDED(hr)) + { + hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, + tempStorageEntry, &tempStorageData); + } + + if (SUCCEEDED(hr)) + { + hr = StorageBaseImpl_ReadDirEntry(This->snapshot, + This->snapshot->storageDirEntry, &snapshotRootData); + } + + if (SUCCEEDED(hr)) + { + oldDirRoot = data.dirRootEntry; + data.dirRootEntry = tempStorageData.dirRootEntry; + data.clsid = snapshotRootData.clsid; + data.ctime = snapshotRootData.ctime; + data.mtime = snapshotRootData.mtime; + + hr = StorageBaseImpl_WriteDirEntry(This->transactedParent, + This->transactedParent->storageDirEntry, &data); + } + + if (SUCCEEDED(hr)) + { + /* Destroy the old now-orphaned data. */ + DestroyReachableEntries(This->transactedParent, oldDirRoot); + StorageBaseImpl_DestroyDirEntry(This->transactedParent, tempStorageEntry); + } + else + { + DestroyReachableEntries(This->transactedParent, tempStorageEntry); + } + + return hr; +} + +static HRESULT WINAPI TransactedSnapshotImpl_Revert( + IStorage* iface) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + StorageBaseImpl *newSnapshot; + HRESULT hr; + + TRACE("(%p)\n", iface); + + /* Create a new copy of the parent data. */ + hr = CreateSnapshotFile(This->transactedParent, &newSnapshot); + if (FAILED(hr)) return hr; + + /* Destroy the open objects. */ + StorageBaseImpl_DeleteAll(&This->base); + + /* Replace our current snapshot. */ + IStorage_Release((IStorage*)This->snapshot); + This->snapshot = newSnapshot; + + return S_OK; +} + +static void TransactedSnapshotImpl_Invalidate(StorageBaseImpl* This) +{ + if (!This->reverted) { TRACE("Storage invalidated (stg=%p)\n", This); - This->base.ancestorStorage = NULL; + This->reverted = 1; + + StorageBaseImpl_DeleteAll(This); + } +} + +static void TransactedSnapshotImpl_Destroy( StorageBaseImpl *iface) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + + TransactedSnapshotImpl_Invalidate(iface); + + IStorage_Release((IStorage*)This->transactedParent); + + IStorage_Release((IStorage*)This->snapshot); + + HeapFree(GetProcessHeap(), 0, This); +} + +static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base, + const DirEntry *newData, DirRef *index) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_CreateDirEntry(This->snapshot, + newData, index); +} + +static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base, + DirRef index, const DirEntry *data) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_WriteDirEntry(This->snapshot, + index, data); +} + +static HRESULT TransactedSnapshotImpl_ReadDirEntry(StorageBaseImpl *base, + DirRef index, DirEntry *data) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_ReadDirEntry(This->snapshot, + index, data); +} + +static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, + DirRef index) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_DestroyDirEntry(This->snapshot, + index); +} + +static HRESULT TransactedSnapshotImpl_StreamReadAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_StreamReadAt(This->snapshot, + index, offset, size, buffer, bytesRead); +} + +static HRESULT TransactedSnapshotImpl_StreamWriteAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_StreamWriteAt(This->snapshot, + index, offset, size, buffer, bytesWritten); +} + +static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER newsize) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + + return StorageBaseImpl_StreamSetSize(This->snapshot, + index, newsize); +} + +static const IStorageVtbl TransactedSnapshotImpl_Vtbl = +{ + StorageBaseImpl_QueryInterface, + StorageBaseImpl_AddRef, + StorageBaseImpl_Release, + StorageBaseImpl_CreateStream, + StorageBaseImpl_OpenStream, + StorageBaseImpl_CreateStorage, + StorageBaseImpl_OpenStorage, + StorageBaseImpl_CopyTo, + StorageBaseImpl_MoveElementTo, + TransactedSnapshotImpl_Commit, + TransactedSnapshotImpl_Revert, + StorageBaseImpl_EnumElements, + StorageBaseImpl_DestroyElement, + StorageBaseImpl_RenameElement, + StorageBaseImpl_SetElementTimes, + StorageBaseImpl_SetClass, + StorageBaseImpl_SetStateBits, + StorageBaseImpl_Stat +}; + +static const StorageBaseImplVtbl TransactedSnapshotImpl_BaseVtbl = +{ + TransactedSnapshotImpl_Destroy, + TransactedSnapshotImpl_Invalidate, + TransactedSnapshotImpl_CreateDirEntry, + TransactedSnapshotImpl_WriteDirEntry, + TransactedSnapshotImpl_ReadDirEntry, + TransactedSnapshotImpl_DestroyDirEntry, + TransactedSnapshotImpl_StreamReadAt, + TransactedSnapshotImpl_StreamWriteAt, + TransactedSnapshotImpl_StreamSetSize +}; + +static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage, + TransactedSnapshotImpl** result) +{ + HRESULT hr; + + *result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TransactedSnapshotImpl)); + if (*result) + { + (*result)->base.lpVtbl = &TransactedSnapshotImpl_Vtbl; + + /* This is OK because the property set storage functions use the IStorage functions. */ + (*result)->base.pssVtbl = parentStorage->pssVtbl; + + (*result)->base.baseVtbl = &TransactedSnapshotImpl_BaseVtbl; + + list_init(&(*result)->base.strmHead); + + list_init(&(*result)->base.storageHead); + + (*result)->base.ref = 1; + + (*result)->base.openFlags = parentStorage->openFlags; + + (*result)->base.filename = parentStorage->filename; + + /* Create a new temporary storage to act as the snapshot */ + hr = CreateSnapshotFile(parentStorage, &(*result)->snapshot); + + if (SUCCEEDED(hr)) + { + (*result)->base.storageDirEntry = (*result)->snapshot->storageDirEntry; + + /* parentStorage already has 1 reference, which we take over here. */ + (*result)->transactedParent = parentStorage; + + parentStorage->transactedChild = (StorageBaseImpl*)*result; + } + + if (FAILED(hr)) HeapFree(GetProcessHeap(), 0, (*result)); + + return hr; + } + else + return E_OUTOFMEMORY; +} + +static HRESULT Storage_ConstructTransacted(StorageBaseImpl *parentStorage, + StorageBaseImpl** result) +{ + static int fixme=0; + + if (parentStorage->openFlags & (STGM_NOSCRATCH|STGM_NOSNAPSHOT) && !fixme++) + { + FIXME("Unimplemented flags %x\n", parentStorage->openFlags); + } + + return TransactedSnapshotImpl_Construct(parentStorage, + (TransactedSnapshotImpl**)result); +} + +static HRESULT Storage_Construct( + HANDLE hFile, + LPCOLESTR pwcsName, + ILockBytes* pLkbyt, + DWORD openFlags, + BOOL fileBased, + BOOL create, + StorageBaseImpl** result) +{ + StorageImpl *newStorage; + StorageBaseImpl *newTransactedStorage; + HRESULT hr; + + hr = StorageImpl_Construct(hFile, pwcsName, pLkbyt, openFlags, fileBased, create, &newStorage); + if (FAILED(hr)) goto end; + + if (openFlags & STGM_TRANSACTED) + { + hr = Storage_ConstructTransacted(&newStorage->base, &newTransactedStorage); + if (FAILED(hr)) + IStorage_Release((IStorage*)newStorage); + else + *result = newTransactedStorage; + } + else + *result = &newStorage->base; + +end: + return hr; +} + +static void StorageInternalImpl_Invalidate( StorageBaseImpl *base ) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + if (!This->base.reverted) + { + TRACE("Storage invalidated (stg=%p)\n", This); + + This->base.reverted = 1; + + This->parentStorage = NULL; StorageBaseImpl_DeleteAll(&This->base); @@ -3634,11 +4300,74 @@ static void StorageInternalImpl_Destroy( StorageBaseImpl *iface) { StorageInternalImpl* This = (StorageInternalImpl*) iface; - StorageInternalImpl_Invalidate(This); + StorageInternalImpl_Invalidate(&This->base); HeapFree(GetProcessHeap(), 0, This); } +static HRESULT StorageInternalImpl_CreateDirEntry(StorageBaseImpl *base, + const DirEntry *newData, DirRef *index) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_CreateDirEntry(This->parentStorage, + newData, index); +} + +static HRESULT StorageInternalImpl_WriteDirEntry(StorageBaseImpl *base, + DirRef index, const DirEntry *data) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_WriteDirEntry(This->parentStorage, + index, data); +} + +static HRESULT StorageInternalImpl_ReadDirEntry(StorageBaseImpl *base, + DirRef index, DirEntry *data) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_ReadDirEntry(This->parentStorage, + index, data); +} + +static HRESULT StorageInternalImpl_DestroyDirEntry(StorageBaseImpl *base, + DirRef index) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_DestroyDirEntry(This->parentStorage, + index); +} + +static HRESULT StorageInternalImpl_StreamReadAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamReadAt(This->parentStorage, + index, offset, size, buffer, bytesRead); +} + +static HRESULT StorageInternalImpl_StreamWriteAt(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamWriteAt(This->parentStorage, + index, offset, size, buffer, bytesWritten); +} + +static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base, + DirRef index, ULARGE_INTEGER newsize) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamSetSize(This->parentStorage, + index, newsize); +} + /****************************************************************************** ** ** Storage32InternalImpl_Commit @@ -3763,14 +4492,14 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next( /* * Read the entry from the storage. */ - StorageImpl_ReadDirEntry(This->parentStorage, + StorageBaseImpl_ReadDirEntry(This->parentStorage, currentSearchNode, ¤tEntry); /* * Copy the information to the return buffer. */ - StorageUtl_CopyDirEntryToSTATSTG(&This->parentStorage->base, + StorageUtl_CopyDirEntryToSTATSTG(This->parentStorage, currentReturnStruct, ¤tEntry, STATFLAG_DEFAULT); @@ -3825,7 +4554,7 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Skip( /* * Read the entry from the storage. */ - StorageImpl_ReadDirEntry(This->parentStorage, + StorageBaseImpl_ReadDirEntry(This->parentStorage, currentSearchNode, ¤tEntry); @@ -3857,7 +4586,7 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Reset( IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; DirEntry storageEntry; - BOOL readSuccessful; + HRESULT hr; /* * Re-initialize the search stack to an empty stack @@ -3867,12 +4596,12 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Reset( /* * Read the storage entry from the top-level storage. */ - readSuccessful = StorageImpl_ReadDirEntry( + hr = StorageBaseImpl_ReadDirEntry( This->parentStorage, This->storageDirEntry, &storageEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { assert(storageEntry.sizeOfNameString!=0); @@ -3882,7 +4611,7 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Reset( IEnumSTATSTGImpl_PushSearchNode(This, storageEntry.dirRootEntry); } - return S_OK; + return hr; } static HRESULT WINAPI IEnumSTATSTGImpl_Clone( @@ -3933,7 +4662,7 @@ static void IEnumSTATSTGImpl_PushSearchNode( DirRef nodeToPush) { DirEntry storageEntry; - BOOL readSuccessful; + HRESULT hr; /* * First, make sure we're not trying to push an unexisting node. @@ -3961,12 +4690,12 @@ static void IEnumSTATSTGImpl_PushSearchNode( /* * Read the storage entry from the top-level storage. */ - readSuccessful = StorageImpl_ReadDirEntry( + hr = StorageBaseImpl_ReadDirEntry( This->parentStorage, nodeToPush, &storageEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { assert(storageEntry.sizeOfNameString!=0); @@ -4013,7 +4742,7 @@ static const IEnumSTATSTGVtbl IEnumSTATSTGImpl_Vtbl = */ static IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct( - StorageImpl* parentStorage, + StorageBaseImpl* parentStorage, DirRef storageDirEntry) { IEnumSTATSTGImpl* newEnumeration; @@ -4081,7 +4810,15 @@ static const IStorageVtbl Storage32InternalImpl_Vtbl = static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = { - StorageInternalImpl_Destroy + StorageInternalImpl_Destroy, + StorageInternalImpl_Invalidate, + StorageInternalImpl_CreateDirEntry, + StorageInternalImpl_WriteDirEntry, + StorageInternalImpl_ReadDirEntry, + StorageInternalImpl_DestroyDirEntry, + StorageInternalImpl_StreamReadAt, + StorageInternalImpl_StreamWriteAt, + StorageInternalImpl_StreamSetSize }; /****************************************************************************** @@ -4089,7 +4826,7 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = */ static StorageInternalImpl* StorageInternalImpl_Construct( - StorageImpl* ancestorStorage, + StorageBaseImpl* parentStorage, DWORD openFlags, DirRef storageDirEntry) { @@ -4110,10 +4847,11 @@ static StorageInternalImpl* StorageInternalImpl_Construct( newStorage->base.baseVtbl = &StorageInternalImpl_BaseVtbl; newStorage->base.openFlags = (openFlags & ~STGM_CREATE); - /* - * Keep the ancestor storage pointer but do not nail a reference to it. - */ - newStorage->base.ancestorStorage = ancestorStorage; + newStorage->base.reverted = 0; + + newStorage->base.ref = 1; + + newStorage->parentStorage = parentStorage; /* * Keep a reference to the directory entry of this storage @@ -4325,19 +5063,19 @@ void BlockChainStream_Destroy(BlockChainStream* This) static ULONG BlockChainStream_GetHeadOfChain(BlockChainStream* This) { DirEntry chainEntry; - BOOL readSuccessful; + HRESULT hr; if (This->headOfStreamPlaceHolder != 0) return *(This->headOfStreamPlaceHolder); if (This->ownerDirEntry != DIRENTRY_NULL) { - readSuccessful = StorageImpl_ReadDirEntry( + hr = StorageImpl_ReadDirEntry( This->parentStorage, This->ownerDirEntry, &chainEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { return chainEntry.startingBlock; } @@ -4853,19 +5591,19 @@ static ULONG SmallBlockChainStream_GetHeadOfChain( SmallBlockChainStream* This) { DirEntry chainEntry; - BOOL readSuccessful; + HRESULT hr; if (This->headOfStreamPlaceHolder != NULL) return *(This->headOfStreamPlaceHolder); if (This->ownerDirEntry) { - readSuccessful = StorageImpl_ReadDirEntry( + hr = StorageImpl_ReadDirEntry( This->parentStorage, This->ownerDirEntry, &chainEntry); - if (readSuccessful) + if (SUCCEEDED(hr)) { return chainEntry.startingBlock; } @@ -5584,7 +6322,7 @@ HRESULT WINAPI StgCreateDocfile( DWORD reserved, IStorage **ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HANDLE hFile = INVALID_HANDLE_VALUE; HRESULT hr = STG_E_INVALIDFLAG; DWORD shareMode; @@ -5693,7 +6431,7 @@ HRESULT WINAPI StgCreateDocfile( /* * Allocate and initialize the new IStorage32object. */ - hr = StorageImpl_Construct( + hr = Storage_Construct( hFile, pwcsName, NULL, @@ -5826,12 +6564,11 @@ HRESULT WINAPI StgOpenStorage( DWORD reserved, IStorage **ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HRESULT hr = S_OK; HANDLE hFile = 0; DWORD shareMode; DWORD accessMode; - WCHAR fullname[MAX_PATH]; TRACE("(%s, %p, %x, %p, %d, %p)\n", debugstr_w(pwcsName), pstgPriority, grfMode, @@ -5966,7 +6703,7 @@ HRESULT WINAPI StgOpenStorage( /* * Allocate and initialize the new IStorage32object. */ - hr = StorageImpl_Construct( + hr = Storage_Construct( hFile, pwcsName, NULL, @@ -5985,11 +6722,6 @@ HRESULT WINAPI StgOpenStorage( goto end; } - /* prepare the file name string given in lieu of the root property name */ - GetFullPathNameW(pwcsName, MAX_PATH, fullname, NULL); - memcpy(newStorage->base.filename, fullname, DIRENTRY_NAME_BUFFER_LEN); - newStorage->base.filename[DIRENTRY_NAME_BUFFER_LEN-1] = '\0'; - /* * Get an "out" pointer for the caller. */ @@ -6009,7 +6741,7 @@ HRESULT WINAPI StgCreateDocfileOnILockBytes( DWORD reserved, IStorage** ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HRESULT hr = S_OK; if ((ppstgOpen == 0) || (plkbyt == 0)) @@ -6018,7 +6750,7 @@ HRESULT WINAPI StgCreateDocfileOnILockBytes( /* * Allocate and initialize the new IStorage object. */ - hr = StorageImpl_Construct( + hr = Storage_Construct( 0, 0, plkbyt, @@ -6051,7 +6783,7 @@ HRESULT WINAPI StgOpenStorageOnILockBytes( DWORD reserved, IStorage **ppstgOpen) { - StorageImpl* newStorage = 0; + StorageBaseImpl* newStorage = 0; HRESULT hr = S_OK; if ((plkbyt == 0) || (ppstgOpen == 0)) @@ -6065,7 +6797,7 @@ HRESULT WINAPI StgOpenStorageOnILockBytes( /* * Allocate and initialize the new IStorage object. */ - hr = StorageImpl_Construct( + hr = Storage_Construct( 0, 0, plkbyt, diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index c97a2b7a75c..07a4b339d89 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -214,9 +214,9 @@ struct StorageBaseImpl LONG ref; /* - * Ancestor storage (top level) + * TRUE if this object has been invalidated */ - StorageImpl* ancestorStorage; + int reverted; /* * Index of the directory entry of this storage @@ -239,15 +239,28 @@ struct StorageBaseImpl DWORD stateBits; /* If set, this overrides the root storage name returned by IStorage_Stat */ - WCHAR filename[DIRENTRY_NAME_BUFFER_LEN]; + LPCWSTR filename; BOOL create; /* Was the storage created or opened. The behaviour of STGM_SIMPLE depends on this */ + /* + * If this storage was opened in transacted mode, the object that implements + * the transacted snapshot or cache. + */ + StorageBaseImpl *transactedChild; }; /* virtual methods for StorageBaseImpl objects */ struct StorageBaseImplVtbl { void (*Destroy)(StorageBaseImpl*); + void (*Invalidate)(StorageBaseImpl*); + HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*); + HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*); + HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*); + HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef); + HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); + HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); + HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); }; static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) @@ -255,6 +268,56 @@ static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) This->baseVtbl->Destroy(This); } +static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This) +{ + This->baseVtbl->Invalidate(This); +} + +static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This, + const DirEntry *newData, DirRef *index) +{ + return This->baseVtbl->CreateDirEntry(This, newData, index); +} + +static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This, + DirRef index, const DirEntry *data) +{ + return This->baseVtbl->WriteDirEntry(This, index, data); +} + +static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This, + DirRef index, DirEntry *data) +{ + return This->baseVtbl->ReadDirEntry(This, index, data); +} + +static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This, + DirRef index) +{ + return This->baseVtbl->DestroyDirEntry(This, index); +} + +/* Read up to size bytes from this directory entry's stream at the given offset. */ +static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead); +} + +/* Write size bytes to this directory entry's stream at the given offset, + * growing the stream if necessary. */ +static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten); +} + +static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER newsize) +{ + return This->baseVtbl->StreamSetSize(This, index, newsize); +} + /**************************************************************************** * StorageBaseImpl stream list handlers */ @@ -324,12 +387,12 @@ HRESULT StorageImpl_WriteRawDirEntry( ULONG index, const BYTE *buffer); -BOOL StorageImpl_ReadDirEntry( +HRESULT StorageImpl_ReadDirEntry( StorageImpl* This, DirRef index, DirEntry* buffer); -BOOL StorageImpl_WriteDirEntry( +HRESULT StorageImpl_WriteDirEntry( StorageImpl* This, DirRef index, const DirEntry* buffer); @@ -380,22 +443,9 @@ struct StgStreamImpl DirRef dirEntry; /* - * Helper variable that contains the size of the stream - */ - ULARGE_INTEGER streamSize; - - /* * This is the current position of the cursor in the stream */ ULARGE_INTEGER currentPosition; - - /* - * The information in the stream is represented by a chain of small blocks - * or a chain of large blocks. Depending on the case, one of the two - * following variables points to that information. - */ - BlockChainStream* bigBlockChain; - SmallBlockChainStream* smallBlockChain; }; /* diff --git a/dlls/ole32/tests/hglobalstream.c b/dlls/ole32/tests/hglobalstream.c index cae13ed2ea9..4fee6129465 100644 --- a/dlls/ole32/tests/hglobalstream.c +++ b/dlls/ole32/tests/hglobalstream.c @@ -75,6 +75,23 @@ static void test_streamonhglobal(IStream *pStream) hr = IStream_SetSize(pStream, ull); ok_ole_success(hr, "IStream_SetSize"); + /* ignores HighPart */ + ll.u.HighPart = -1; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); + todo_wine + ok_ole_success(hr, "IStream_Seek"); + ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); + todo_wine + ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); + + /* ignores HighPart */ + ll.u.HighPart = -1; + ll.u.LowPart = 0; + hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, NULL); + todo_wine + ok_ole_success(hr, "IStream_Seek"); + hr = IStream_Commit(pStream, STGC_DEFAULT); ok_ole_success(hr, "IStream_Commit"); diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c index d27f766baba..7cc5f78c2db 100644 --- a/dlls/ole32/tests/moniker.c +++ b/dlls/ole32/tests/moniker.c @@ -1878,9 +1878,9 @@ static void test_save_load_filemoniker(void) int i; /* see FileMonikerImpl_Save docs */ - zero_pos.u.LowPart = 0; - dead_pos.u.LowPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD); - nulls_pos.u.LowPart = dead_pos.u.LowPart + sizeof(WORD); + zero_pos.QuadPart = 0; + dead_pos.QuadPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD); + nulls_pos.QuadPart = dead_pos.QuadPart + sizeof(WORD); /* create the stream we're going to write to */ hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm); diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 6e222c7140a..f89a787c034 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -36,7 +36,9 @@ DEFINE_GUID( test_stg_cls, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0); static CHAR filenameA[MAX_PATH]; static WCHAR filename[MAX_PATH]; +static const char file1_nameA[] = {'c','o','p','y','t','e','s','t','A',0}; static const WCHAR file1_name[] = {'c','o','p','y','t','e','s','t','A',0}; +static const char file2_nameA[] = {'c','o','p','y','t','e','s','t','B',0}; static const WCHAR file2_name[] = {'c','o','p','y','t','e','s','t','B',0}; static const WCHAR stgA_name[] = {'S','t','o','r','a','g','e','A',0}; static const WCHAR stgB_name[] = {'S','t','o','r','a','g','e','B',0}; @@ -44,6 +46,15 @@ static const WCHAR strmA_name[] = {'S','t','r','e','a','m','A',0}; static const WCHAR strmB_name[] = {'S','t','r','e','a','m','B',0}; static const WCHAR strmC_name[] = {'S','t','r','e','a','m','C',0}; +/* Win9x and WinMe don't have lstrcmpW */ +static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2) +{ + CHAR stra1[512], stra2[512]; + WideCharToMultiByte(CP_ACP, 0, strw1, -1, stra1, sizeof(stra1), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, strw2, -1, stra2, sizeof(stra2), NULL, NULL); + return lstrcmpA(stra1, stra2); +} + static void test_hglobal_storage_stat(void) { ILockBytes *ilb = NULL; @@ -992,17 +1003,13 @@ static void test_transact(void) r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r); - todo_wine { r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); - } if (r == S_OK) IStream_Release(stm); - todo_wine { r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); - } if (r == S_OK) IStorage_Release(stg2); @@ -1024,7 +1031,7 @@ static void test_transact(void) IStorage_Release(stg3); r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 ); - todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); if (r == S_OK) IStorage_Release(stg3); @@ -1188,7 +1195,6 @@ static void test_revert(void) r = IStorage_Revert(stg); /* all open objects become invalid */ - todo_wine { r = IStream_Write(stm, "this shouldn't work\n", 20, NULL); ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r); @@ -1200,7 +1206,6 @@ static void test_revert(void) r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME); ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r); - } IStream_Release(stm); IStream_Release(stm2); @@ -1219,17 +1224,13 @@ static void test_revert(void) r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r); - todo_wine { r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); - } if (r == S_OK) IStream_Release(stm); - todo_wine { r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 ); ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); - } if (r == S_OK) IStorage_Release(stg2); @@ -1251,7 +1252,7 @@ static void test_revert(void) IStorage_Release(stg3); r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 ); - todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r); if (r == S_OK) IStorage_Release(stg3); @@ -1348,7 +1349,7 @@ static void test_parent_free(void) static void test_nonroot_transacted(void) { - IStorage *stg = NULL, *stg2 = NULL; + IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL; HRESULT r; IStream *stm = NULL; static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 }; @@ -1391,14 +1392,33 @@ static void test_nonroot_transacted(void) IStream_Release(stm); r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); - todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); if (r == S_OK) IStream_Release(stm); IStorage_Release(stg2); } - IStream_Release(stg); + /* create a read-only transacted substorage */ + r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2); + ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r); + + if (r == S_OK) + { + /* The storage can be modified. */ + r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3); + todo_wine ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); + if (r == S_OK) + IStream_Release(stg3); + + /* But changes cannot be committed. */ + r = IStorage_Commit(stg2, 0); + ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r); + + IStorage_Release(stg2); + } + + IStorage_Release(stg); /* create a non-transacted file */ r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | @@ -1434,7 +1454,7 @@ static void test_nonroot_transacted(void) IStream_Release(stm); r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm ); - todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); + ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r); if (r == S_OK) IStream_Release(stm); @@ -1891,6 +1911,7 @@ static void test_fmtusertypestg(void) IStorage *stg; IEnumSTATSTG *stat; HRESULT hr; + static const char fileA[] = {'f','m','t','t','e','s','t',0}; static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0}; static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0}; static WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0}; @@ -1914,7 +1935,7 @@ static void test_fmtusertypestg(void) DWORD got; while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1) { - if (lstrcmpW(statstg.pwcsName, strmNameW) == 0) + if (strcmp_ww(statstg.pwcsName, strmNameW) == 0) found = TRUE; else ok(0, "found unexpected stream or storage\n"); @@ -1937,7 +1958,7 @@ static void test_fmtusertypestg(void) DWORD got; while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1) { - if (lstrcmpW(statstg.pwcsName, strmNameW) == 0) + if (strcmp_ww(statstg.pwcsName, strmNameW) == 0) found = TRUE; else ok(0, "found unexpected stream or storage\n"); @@ -1947,7 +1968,7 @@ static void test_fmtusertypestg(void) } IStorage_Release(stg); - DeleteFileW( fileW ); + DeleteFileA( fileA ); } } @@ -2105,7 +2126,7 @@ static void test_copyto(void) hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); ok(hr == S_OK, "Read failed: 0x%08x\n", hr); if(SUCCEEDED(hr)) - ok(lstrcmpW(buf, strmA_name) == 0, + ok(strcmp_ww(buf, strmA_name) == 0, "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf)); IStream_Release(strm_tmp); @@ -2128,7 +2149,7 @@ static void test_copyto(void) hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); ok(hr == S_OK, "Read failed: 0x%08x\n", hr); if(SUCCEEDED(hr)) - ok(lstrcmpW(buf, strmB_name) == 0, + ok(strcmp_ww(buf, strmB_name) == 0, "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf)); IStream_Release(strm_tmp); @@ -2146,7 +2167,7 @@ static void test_copyto(void) hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); ok(hr == S_OK, "Read failed: 0x%08x\n", hr); if(SUCCEEDED(hr)) - ok(lstrcmpW(buf, strmC_name) == 0, + ok(strcmp_ww(buf, strmC_name) == 0, "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf)); IStream_Release(strm_tmp); @@ -2158,8 +2179,8 @@ cleanup: if(file2) IStorage_Release(file2); - DeleteFileW(file1_name); - DeleteFileW(file2_name); + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); } static void test_copyto_snbexclusions(void) @@ -2220,7 +2241,7 @@ static void test_copyto_snbexclusions(void) hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); ok(hr == S_OK, "Read failed: 0x%08x\n", hr); if(SUCCEEDED(hr)) - ok(lstrcmpW(buf, strmB_name) == 0, + ok(strcmp_ww(buf, strmB_name) == 0, "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf)); IStream_Release(strm_tmp); @@ -2241,8 +2262,8 @@ cleanup: if(file2) IStorage_Release(file2); - DeleteFileW(file1_name); - DeleteFileW(file2_name); + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); } static void test_copyto_iidexclusions_storage(void) @@ -2308,7 +2329,7 @@ static void test_copyto_iidexclusions_storage(void) hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL); ok(hr == S_OK, "Read failed: 0x%08x\n", hr); if(SUCCEEDED(hr)) - ok(lstrcmpW(buf, strmC_name) == 0, + ok(strcmp_ww(buf, strmC_name) == 0, "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf)); IStream_Release(strm_tmp); @@ -2320,8 +2341,8 @@ cleanup: if(file2) IStorage_Release(file2); - DeleteFileW(file1_name); - DeleteFileW(file2_name); + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); } static void test_copyto_iidexclusions_stream(void) @@ -2393,8 +2414,8 @@ cleanup: if(file2) IStorage_Release(file2); - DeleteFileW(file1_name); - DeleteFileW(file2_name); + DeleteFileA(file1_nameA); + DeleteFileA(file2_nameA); } static void test_rename(void) @@ -2466,6 +2487,78 @@ static void test_rename(void) ok( r == TRUE, "deleted file\n"); } +static void test_toplevel_stat(void) +{ + IStorage *stg = NULL; + HRESULT r; + STATSTG stat; + char prev_dir[MAX_PATH]; + char temp[MAX_PATH]; + char full_path[MAX_PATH]; + LPSTR rel_pathA; + WCHAR rel_path[MAX_PATH]; + + DeleteFileA(filenameA); + + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + DeleteFileA(filenameA); + + /* Stat always returns the full path, even for files opened with a relative path. */ + GetCurrentDirectoryA(MAX_PATH, prev_dir); + + GetTempPathA(MAX_PATH, temp); + + SetCurrentDirectoryA(temp); + + GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA); + MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH); + + r = StgCreateDocfile( rel_path, STGM_CREATE | STGM_SHARE_EXCLUSIVE | + STGM_READWRITE |STGM_TRANSACTED, 0, &stg); + ok(r==S_OK, "StgCreateDocfile failed\n"); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + r = StgOpenStorage( rel_path, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r); + + r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", + wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); + CoTaskMemFree(stat.pwcsName); + + IStorage_Release( stg ); + + SetCurrentDirectoryA(prev_dir); + + DeleteFileA(filenameA); +} + START_TEST(storage32) { CHAR temp[MAX_PATH]; @@ -2503,4 +2596,5 @@ START_TEST(storage32) test_copyto_iidexclusions_storage(); test_copyto_iidexclusions_stream(); test_rename(); + test_toplevel_stat(); } diff --git a/dlls/oleaut32/dispatch.c b/dlls/oleaut32/dispatch.c index 2fd8bb42d00..ed3fad47019 100644 --- a/dlls/oleaut32/dispatch.c +++ b/dlls/oleaut32/dispatch.c @@ -130,10 +130,14 @@ HRESULT WINAPI DispGetParam( TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n", position, pdispparams->cArgs, pdispparams->cNamedArgs); - if (position < pdispparams->cArgs) { + + if (position < pdispparams->cArgs) + { /* positional arg? */ pos = pdispparams->cArgs - position - 1; - } else { + } + else + { /* FIXME: is this how to handle named args? */ for (pos=0; poscNamedArgs; pos++) if (pdispparams->rgdispidNamedArgs[pos] == position) break; @@ -141,10 +145,27 @@ HRESULT WINAPI DispGetParam( if (pos==pdispparams->cNamedArgs) return DISP_E_PARAMNOTFOUND; } + + if (pdispparams->cArgs > 0 && !pdispparams->rgvarg) + { + hr = E_INVALIDARG; + goto done; + } + + if (!pvarResult) + { + hr = E_INVALIDARG; + goto done; + } + hr = VariantChangeType(pvarResult, &pdispparams->rgvarg[pos], 0, vtTarg); - if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos; + +done: + if (FAILED(hr)) + *puArgErr = pos; + return hr; } @@ -234,8 +255,8 @@ static HRESULT WINAPI StdDispatch_QueryInterface( IsEqualIID(riid, &IID_IUnknown)) { *ppvObject = This; - IUnknown_AddRef((LPUNKNOWN)*ppvObject); - return S_OK; + IUnknown_AddRef((LPUNKNOWN)*ppvObject); + return S_OK; } return E_NOINTERFACE; } diff --git a/dlls/oleaut32/tests/Makefile.in b/dlls/oleaut32/tests/Makefile.in index 4cb08655d7b..97612393d61 100644 --- a/dlls/oleaut32/tests/Makefile.in +++ b/dlls/oleaut32/tests/Makefile.in @@ -6,6 +6,7 @@ TESTDLL = oleaut32.dll IMPORTS = oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 kernel32 CTESTS = \ + dispatch.c \ olefont.c \ olepicture.c \ safearray.c \ diff --git a/dlls/oleaut32/tests/dispatch.c b/dlls/oleaut32/tests/dispatch.c new file mode 100644 index 00000000000..c81210f5e5b --- /dev/null +++ b/dlls/oleaut32/tests/dispatch.c @@ -0,0 +1,272 @@ +/* + * Dispatch test + * + * Copyright 2009 James Hawkins + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +static const WCHAR szSunshine[] = {'S','u','n','s','h','i','n','e',0}; + +/* Temporary storage for ok_bstr. */ +static CHAR temp_str[MAX_PATH]; + +#define ok_bstr(bstr, expected, format) \ + do { \ + WideCharToMultiByte(CP_ACP, 0, bstr, -1, temp_str, MAX_PATH, NULL, NULL); \ + if (lstrcmpA(temp_str, expected) != 0) \ + ok(0, format, expected, temp_str); \ + } while(0); + +#define INIT_DISPPARAMS(dp, args, named_args, num_args, num_named_args) \ + dp.rgvarg = args; \ + dp.rgdispidNamedArgs = named_args; \ + dp.cArgs = num_args; \ + dp.cNamedArgs = num_named_args; \ + +/* Initializes vararg with three values: + * VT_I2 - 42 + * VT_I4 - 1234567890 + * VT_BSTR - "Sunshine" + */ +#define INIT_VARARG(vararg) \ + VariantInit(&vararg[0]); \ + V_VT(&vararg[0]) = VT_I2; \ + V_I2(&vararg[0]) = 42; \ + VariantInit(&vararg[1]); \ + V_VT(&vararg[1]) = VT_I4; \ + V_I4(&vararg[1]) = 1234567890; \ + VariantInit(&vararg[2]); \ + V_VT(&vararg[2]) = VT_BSTR; \ + V_BSTR(&vararg[2]) = SysAllocString(szSunshine); + +/* Clears the vararg. */ +#define CLEAR_VARARG(vararg) \ + VariantClear(&vararg[0]); \ + VariantClear(&vararg[1]); \ + VariantClear(&vararg[2]); + +void test_DispGetParam(void) +{ + HRESULT hr; + DISPPARAMS dispparams; + VARIANTARG vararg[3]; + VARIANT result; + unsigned int err_index; + + VariantInit(&result); + + /* DispGetParam crashes on Windows if pdispparams is NULL. */ + + /* pdispparams has zero parameters. */ + INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 0, VT_I2, &result, &err_index); + ok(hr == DISP_E_PARAMNOTFOUND, + "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* pdispparams has zero parameters, position is invalid. */ + INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 1, VT_I2, &result, &err_index); + ok(hr == DISP_E_PARAMNOTFOUND, + "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* pdispparams has zero parameters, pvarResult is NULL. */ + INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 0, VT_I2, NULL, &err_index); + ok(hr == DISP_E_PARAMNOTFOUND, + "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* pdispparams has zero parameters, puArgErr is NULL. */ + INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0); + VariantInit(&result); + hr = DispGetParam(&dispparams, 0, VT_I2, &result, NULL); + ok(hr == DISP_E_PARAMNOTFOUND, + "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + + /* pdispparams.cArgs is 1, yet pdispparams.rgvarg is NULL. */ + INIT_DISPPARAMS(dispparams, NULL, NULL, 1, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 0, VT_I2, &result, &err_index); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 0, "Expected 0, got %d\n", err_index); + + /* pdispparams.cNamedArgs is 1, yet pdispparams.rgdispidNamedArgs is NULL. + * + * This crashes on Windows. + */ + + /* {42, 1234567890, "Sunshine"} */ + INIT_VARARG(vararg); + + /* Get the first param. position is end-based, so 2 is the first parameter + * of 3 parameters. + */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 2, VT_I2, &result, &err_index); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_I2, "Expected VT_I2, got %08x\n", V_VT(&result)); + ok(V_I2(&result) == 42, "Expected 42, got %d\n", V_I2(&result)); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* Get the second param. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 1, VT_I4, &result, &err_index); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_I4, "Expected VT_I4, got %08x\n", V_VT(&result)); + ok(V_I4(&result) == 1234567890, + "Expected 1234567890, got %d\n", V_I4(&result)); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* Get the third param. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 0, VT_BSTR, &result, &err_index); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_BSTR, "Expected VT_BSTR, got %08x\n", V_VT(&result)); + ok_bstr(V_BSTR(&result), "Sunshine", "Expected %s, got %s\n"); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + VariantClear(&result); + + /* position is out of range. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 3, VT_I2, &result, &err_index); + ok(hr == DISP_E_PARAMNOTFOUND, + "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* pvarResult is NULL. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 2, VT_I2, NULL, &err_index); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + ok(err_index == 0, "Expected 0, got %d\n", err_index); + + /* puArgErr is NULL. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + hr = DispGetParam(&dispparams, 2, VT_I2, &result, NULL); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_I2, "Expected VT_I2, got %08x\n", V_VT(&result)); + ok(V_I2(&result) == 42, "Expected 42, got %d\n", V_I2(&result)); + + /* Coerce the first param to VT_I4. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 2, VT_I4, &result, &err_index); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_I4, "Expected VT_I4, got %08x\n", V_VT(&result)); + ok(V_I4(&result) == 42, "Expected 42, got %d\n", V_I4(&result)); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + + /* Coerce the first param to VT_BSTR. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 2, VT_BSTR, &result, &err_index); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_BSTR, "Expected VT_BSTR, got %08x\n", V_VT(&result)); + ok_bstr(V_BSTR(&result), "42", "Expected %s, got %s\n"); + ok(err_index == 0xdeadbeef, + "Expected err_index to be unchanged, got %d\n", err_index); + VariantClear(&result); + + /* Coerce the second (VT_I4) param to VT_I2. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 1, VT_I2, &result, &err_index); + ok(hr == DISP_E_OVERFLOW, "Expected DISP_E_OVERFLOW, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 1, "Expected 1, got %d\n", err_index); + + /* Coerce the third (VT_BSTR) param to VT_I2. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 0, VT_I2, &result, &err_index); + ok(hr == DISP_E_TYPEMISMATCH, + "Expected DISP_E_TYPEMISMATCH, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 2, "Expected 2, got %d\n", err_index); + + /* Coerce the first parameter to an invalid type. */ + INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 2, VT_ILLEGAL, &result, &err_index); + ok(hr == DISP_E_BADVARTYPE, "Expected DISP_E_BADVARTYPE, got %08x\n", hr); + ok(V_VT(&result) == VT_EMPTY, + "Expected VT_EMPTY, got %08x\n", V_VT(&result)); + ok(err_index == 0, "Expected 0, got %d\n", err_index); + + CLEAR_VARARG(vararg); + + /* Coerce the the first parameter, which is of type VT_EMPTY, to VT_BSTR. */ + VariantInit(&vararg[0]); + INIT_DISPPARAMS(dispparams, vararg, NULL, 1, 0); + VariantInit(&result); + err_index = 0xdeadbeef; + hr = DispGetParam(&dispparams, 0, VT_BSTR, &result, &err_index); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&result) == VT_BSTR, "Expected VT_BSTR, got %08x\n", V_VT(&result)); + ok(err_index == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", err_index); +} + +START_TEST(dispatch) +{ + test_DispGetParam(); +} diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index 55d883bb7d3..c8ddc8a7348 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -357,6 +357,7 @@ static void test_empty_image(void) { ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres); ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle); IPicture_Release (pic); + IStream_Release (stream); } static void test_empty_image_2(void) { @@ -395,6 +396,7 @@ static void test_empty_image_2(void) { ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type); IPicture_Release (pic); + IStream_Release (stream); } static void test_Invoke(void) @@ -408,16 +410,17 @@ static void test_Invoke(void) HGLOBAL hglob; void *data; - hglob = GlobalAlloc (0, sizeof(gifimage)); - data = GlobalLock(hglob); - memcpy(data, gifimage, sizeof(gifimage)); + hglob = GlobalAlloc (0, sizeof(gifimage)); + data = GlobalLock(hglob); + memcpy(data, gifimage, sizeof(gifimage)); GlobalUnlock(hglob); - hr = CreateStreamOnHGlobal (hglob, FALSE, &stream); + hr = CreateStreamOnHGlobal (hglob, FALSE, &stream); ok_ole_success(hr, "CreateStreamOnHGlobal"); - hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp); + hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp); IStream_Release(stream); + GlobalFree(hglob); ok_ole_success(hr, "OleLoadPicture"); V_VT(&vararg) = VT_BOOL; diff --git a/dlls/oleaut32/tests/safearray.c b/dlls/oleaut32/tests/safearray.c index d5390566a85..439325d31e9 100644 --- a/dlls/oleaut32/tests/safearray.c +++ b/dlls/oleaut32/tests/safearray.c @@ -1658,9 +1658,11 @@ static void test_SafeArrayChangeTypeEx(void) MKARRAY(0,1,VT_UI1); hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_NULL); ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1 returned %x\n", hres); + VariantClear(&v); MKARRAY(0,1,VT_UI1); hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_EMPTY); ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1 returned %x\n", hres); + VariantClear(&v); } diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index d1809460238..e9c53e91331 100644 --- a/dlls/oleaut32/tests/usrmarshal.c +++ b/dlls/oleaut32/tests/usrmarshal.c @@ -109,6 +109,14 @@ static ULONG get_cell_count(const SAFEARRAY *psa) return ulNumCells; } +static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype) +{ + if (sftype == SF_BSTR) + return sizeof(DWORD); + else + return lpsa->cbElements; +} + static void check_safearray(void *buffer, LPSAFEARRAY lpsa) { unsigned char *wiresa = buffer; @@ -136,7 +144,7 @@ static void check_safearray(void *buffer, LPSAFEARRAY lpsa) wiresa += sizeof(WORD); ok(*(WORD *)wiresa == lpsa->fFeatures, "wiresa + 0xa should be lpsa->fFeatures instead of 0x%08x\n", *(WORD *)wiresa); wiresa += sizeof(WORD); - ok(*(DWORD *)wiresa == lpsa->cbElements, "wiresa + 0xc should be lpsa->cbElements instead of 0x%08x\n", *(DWORD *)wiresa); + ok(*(DWORD *)wiresa == elem_wire_size(lpsa, sftype), "wiresa + 0xc should be 0x%08x instead of 0x%08x\n", elem_wire_size(lpsa, sftype), *(DWORD *)wiresa); wiresa += sizeof(DWORD); ok(*(WORD *)wiresa == lpsa->cLocks, "wiresa + 0x10 should be lpsa->cLocks instead of 0x%04x\n", *(WORD *)wiresa); wiresa += sizeof(WORD); @@ -197,7 +205,7 @@ static void init_user_marshal_cb(USER_MARSHAL_CB *umcb, static void test_marshal_LPSAFEARRAY(void) { - unsigned char *buffer; + unsigned char *buffer, *next; ULONG size, expected; LPSAFEARRAY lpsa; LPSAFEARRAY lpsa2 = NULL; @@ -207,6 +215,10 @@ static void test_marshal_LPSAFEARRAY(void) USER_MARSHAL_CB umcb; HRESULT hr; VARTYPE vt; + OLECHAR *values[10]; + int expected_bstr_size; + int i; + LONG indices[1]; sab.lLbound = 5; sab.cElements = 10; @@ -228,7 +240,8 @@ static void test_marshal_LPSAFEARRAY(void) "size should be %u bytes, not %u\n", expected, size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); check_safearray(buffer, lpsa); @@ -253,10 +266,12 @@ static void test_marshal_LPSAFEARRAY(void) init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa); - ok(size == 4, "size should be 4 bytes, not %d\n", size); + expected = 4; + ok(size == expected, "size should be 4 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); check_safearray(buffer, lpsa); if (LPSAFEARRAY_UNMARSHAL_WORKS) @@ -290,7 +305,8 @@ static void test_marshal_LPSAFEARRAY(void) "size should be %u bytes, not %u\n", expected, size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); check_safearray(buffer, lpsa); @@ -318,12 +334,94 @@ static void test_marshal_LPSAFEARRAY(void) "size should be %u bytes, not %u\n", expected, size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); check_safearray(buffer, lpsa); HeapFree(GetProcessHeap(), 0, buffer); SafeArrayDestroyData(lpsa); SafeArrayDestroyDescriptor(lpsa); + /* Test an array of VT_BSTR */ + sab.lLbound = 3; + sab.cElements = sizeof(values) / sizeof(values[0]); + + lpsa = SafeArrayCreate(VT_BSTR, 1, &sab); + expected_bstr_size = 0; + for (i = 0; i < sab.cElements; i++) + { + int j; + WCHAR buf[128]; + for (j = 0; j <= i; j++) + buf[j] = 'a' + j; + buf[j] = 0; + indices[0] = i + sab.lLbound; + values[i] = SysAllocString(buf); + hr = SafeArrayPutElement(lpsa, indices, values[i]); + ok(hr == S_OK, "Failed to put bstr element hr 0x%x\n", hr); + expected_bstr_size += (j * sizeof(WCHAR)) + (3 * sizeof(DWORD)); + if (i % 2 == 0) /* Account for DWORD padding. Works so long as cElements is even */ + expected_bstr_size += sizeof(WCHAR); + } + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa); + expected = 44 + (sab.cElements * sizeof(DWORD)) + expected_bstr_size; + todo_wine + ok(size == expected + sizeof(DWORD) || size == (expected + sizeof(DWORD) + 12 /* win64 */), + "size should be %u bytes, not %u\n", expected + (ULONG) sizeof(DWORD), size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa); + todo_wine + ok(size == expected || size == (expected + 12 /* win64 */), + "size should be %u bytes, not %u\n", expected, size); + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memset(buffer, 0xcc, size); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); + next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + todo_wine + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); + + check_safearray(buffer, lpsa); + + lpsa2 = NULL; + if (LPSAFEARRAY_UNMARSHAL_WORKS) + { + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); + next = LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2); + todo_wine + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); + ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal, result %p\n", next); + } + + for (i = 0; i < sizeof(values) / sizeof(values[0]); i++) + { + BSTR gotvalue = NULL; + + if (lpsa2) + { + indices[0] = i + sab.lLbound; + hr = SafeArrayGetElement(lpsa2, indices, &gotvalue); + ok(hr == S_OK, "Failed to get bstr element at hres 0x%x\n", hr); + if (hr == S_OK) + { + ok(VarBstrCmp(values[i], gotvalue, 0, 0) == VARCMP_EQ, "String %d does not match\n", i); + SysFreeString(gotvalue); + } + } + + SysFreeString(values[i]); + } + + if (LPSAFEARRAY_UNMARSHAL_WORKS) + { + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); + LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2); + } + + HeapFree(GetProcessHeap(), 0, buffer); + SafeArrayDestroy(lpsa); + + /* VARTYPE-less arrays with FADF_VARIANT */ hr = SafeArrayAllocDescriptor(1, &lpsa); ok(hr == S_OK, "saad failed %08x\n", hr); @@ -345,7 +443,9 @@ static void test_marshal_LPSAFEARRAY(void) "size should be %u bytes, not %u\n", expected, size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + next = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + todo_wine + ok(next - buffer == expected, "Marshaled %u bytes, expected %u\n", (ULONG) (next - buffer), expected); lpsa->cbElements = 16; /* VARIANT wire size */ check_safearray(buffer, lpsa); HeapFree(GetProcessHeap(), 0, buffer); diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c index 87f290151a7..3ea6ac22ab2 100644 --- a/dlls/oleaut32/tests/vartype.c +++ b/dlls/oleaut32/tests/vartype.c @@ -4855,6 +4855,7 @@ static void test_VarBstrFromR4(void) */ ok(memcmp(bstr, szNative, sizeof(szNative)) == 0, "string different\n"); } + SysFreeString(bstr); } f = -0.0; @@ -4866,6 +4867,7 @@ static void test_VarBstrFromR4(void) ok(memcmp(bstr + 1, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr)); else ok(memcmp(bstr, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr)); + SysFreeString(bstr); } /* The following tests that lcid is used for decimal separator even without LOCALE_USE_NLS */ @@ -4875,6 +4877,7 @@ static void test_VarBstrFromR4(void) if (bstr) { ok(memcmp(bstr, szOneHalf_English, sizeof(szOneHalf_English)) == 0, "English locale failed (got %s)\n", wtoascii(bstr)); + SysFreeString(bstr); } f = 0.5; hres = pVarBstrFromR4(f, lcid_spanish, LOCALE_NOUSEROVERRIDE, &bstr); @@ -4882,12 +4885,14 @@ static void test_VarBstrFromR4(void) if (bstr) { ok(memcmp(bstr, szOneHalf_Spanish, sizeof(szOneHalf_Spanish)) == 0, "Spanish locale failed (got %s)\n", wtoascii(bstr)); + SysFreeString(bstr); } } -#define BSTR_DATE(dt,str) SysFreeString(bstr); bstr = NULL; \ +#define BSTR_DATE(dt,str) \ + bstr = NULL; \ hres = pVarBstrFromDate(dt,lcid,LOCALE_NOUSEROVERRIDE,&bstr); \ - if (bstr) WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0); \ + if (bstr) {WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0); SysFreeString(bstr);} \ else buff[0] = 0; \ ok(hres == S_OK && !strcmp(str,buff), "Expected '%s', got '%s', hres = 0x%08x\n", \ str, buff, hres) @@ -4897,7 +4902,7 @@ static void test_VarBstrFromDate(void) char buff[256]; LCID lcid; HRESULT hres; - BSTR bstr = NULL; + BSTR bstr; CHECKPTR(VarBstrFromDate); lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT); @@ -4920,6 +4925,7 @@ static void test_VarBstrFromDate(void) if (hres== S_OK && bstr)\ {\ ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\ + SysFreeString(bstr);\ } static void test_VarBstrFromCy(void) @@ -4982,6 +4988,7 @@ static void test_VarBstrFromCy(void) if (hres== S_OK && bstr)\ {\ ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\ + SysFreeString(bstr);\ } #define BSTR_DEC64(l, a, b, c, x, d, e) \ @@ -4991,6 +4998,7 @@ static void test_VarBstrFromCy(void) if (hres== S_OK && bstr)\ {\ ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\ + SysFreeString(bstr);\ } static void test_VarBstrFromDec(void) @@ -5162,6 +5170,7 @@ static void test_VarBstrCmp(void) VARBSTRCMP(bstr2,bstr,0,VARCMP_GT); SysFreeString(bstr2); SysFreeString(bstr); + SysFreeString(bstrempty); } /* Get the internal representation of a BSTR */ @@ -5858,6 +5867,7 @@ static void test_EmptyChangeTypeEx(void) ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt), "change empty: vt %d expected 0x%08x, got 0x%08x, vt %d\n", vt, hExpected, hres, V_VT(&vDst)); + if(hres == S_OK) VariantClear(&vDst); } } diff --git a/dlls/oleaut32/usrmarshal.c b/dlls/oleaut32/usrmarshal.c index 7409fcef19e..202cf843b96 100644 --- a/dlls/oleaut32/usrmarshal.c +++ b/dlls/oleaut32/usrmarshal.c @@ -763,6 +763,26 @@ static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa) } } +static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype) +{ + if (sftype == SF_BSTR) + return sizeof(DWORD); + else if (sftype == SF_VARIANT) + return sizeof(variant_wire_t) - sizeof(DWORD); + else + return lpsa->cbElements; +} + +static DWORD elem_mem_size(wireSAFEARRAY wiresa, SF_TYPE sftype) +{ + if (sftype == SF_BSTR) + return sizeof(BSTR); + else if (sftype == SF_VARIANT) + return sizeof(VARIANT); + else + return wiresa->cbElements; +} + ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa) { ULONG size = StartingSize; @@ -868,13 +888,15 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf SF_TYPE sftype; GUID guid; + sftype = SAFEARRAY_GetUnionType(psa); + *(ULONG *)Buffer = psa->cDims; Buffer += sizeof(ULONG); *(USHORT *)Buffer = psa->cDims; Buffer += sizeof(USHORT); *(USHORT *)Buffer = psa->fFeatures; Buffer += sizeof(USHORT); - *(ULONG *)Buffer = psa->cbElements; + *(ULONG *)Buffer = elem_wire_size(psa, sftype); Buffer += sizeof(ULONG); hr = SafeArrayGetVartype(psa, &vt); @@ -883,7 +905,6 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf *(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16); Buffer += sizeof(ULONG); - sftype = SAFEARRAY_GetUnionType(psa); *(ULONG *)Buffer = sftype; Buffer += sizeof(ULONG); @@ -1043,7 +1064,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B (*ppsa)->fFeatures &= FADF_AUTOSETFLAGS; (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); /* FIXME: there should be a limit on how large wiresa->cbElements can be */ - (*ppsa)->cbElements = wiresa->cbElements; + (*ppsa)->cbElements = elem_mem_size(wiresa, sftype); (*ppsa)->cLocks = LOWORD(wiresa->cLocks); /* SafeArrayCreateEx allocates the data for us, but diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index 8db45b8f6f3..4511164c092 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c @@ -1778,7 +1778,7 @@ static inline void array_compute_and_size_conformance( break; case RPC_FC_C_CSTRING: case RPC_FC_C_WSTRING: - if (pFormat[0] == RPC_FC_C_CSTRING) + if (fc == RPC_FC_C_CSTRING) { TRACE("string=%s\n", debugstr_a((const char *)pMemory)); pStubMsg->ActualCount = strlen((const char *)pMemory)+1; @@ -1789,7 +1789,7 @@ static inline void array_compute_and_size_conformance( pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; } - if (fc == RPC_FC_STRING_SIZED) + if (pFormat[1] == RPC_FC_STRING_SIZED) pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); else pStubMsg->MaxCount = pStubMsg->ActualCount; diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 823468823d9..665bc40056f 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -1219,6 +1219,8 @@ static void destroy_key_container(OBJECTHDR *pObjectHdr) store_key_container_permissions(pKeyContainer); release_key_container_keys(pKeyContainer); } + else + release_key_container_keys(pKeyContainer); HeapFree( GetProcessHeap(), 0, pKeyContainer ); } @@ -1378,12 +1380,18 @@ static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, cons (OBJECTHDR**)&pKeyContainer)) return (HCRYPTPROV)INVALID_HANDLE_VALUE; + /* read_key_value calls import_key, which calls import_private_key, + * which implicitly installs the key value into the appropriate key + * container key. Thus the ref count is incremented twice, once for + * the output key value, and once for the implicit install, and needs + * to be decremented to balance the two. + */ if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE, dwProtectFlags, &hCryptKey)) - pKeyContainer->hKeyExchangeKeyPair = hCryptKey; + release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE, dwProtectFlags, &hCryptKey)) - pKeyContainer->hSignatureKeyPair = hCryptKey; + release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); } return hKeyContainer; @@ -3065,9 +3073,9 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP if (pCryptKey) { new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen); setup_key(pCryptKey); - RSAENH_CPDestroyKey(hProv, pKeyContainer->hSignatureKeyPair); - copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY, - &pKeyContainer->hSignatureKeyPair); + release_and_install_key(hProv, *phKey, + &pKeyContainer->hSignatureKeyPair, + FALSE); } break; @@ -3077,9 +3085,9 @@ BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYP if (pCryptKey) { new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen); setup_key(pCryptKey); - RSAENH_CPDestroyKey(hProv, pKeyContainer->hKeyExchangeKeyPair); - copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY, - &pKeyContainer->hKeyExchangeKeyPair); + release_and_install_key(hProv, *phKey, + &pKeyContainer->hKeyExchangeKeyPair, + FALSE); } break; @@ -4162,11 +4170,12 @@ BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpe LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) { - HCRYPTKEY hCryptKey; + HCRYPTKEY hCryptKey = (HCRYPTKEY)INVALID_HANDLE_VALUE; CRYPTKEY *pCryptKey; DWORD dwHashLen; BYTE abHashValue[RSAENH_MAX_HASH_SIZE]; ALG_ID aiAlgid; + BOOL ret = FALSE; TRACE("(hProv=%08lx, hHash=%08lx, dwKeySpec=%08x, sDescription=%s, dwFlags=%08x, " "pbSignature=%p, pdwSigLen=%p)\n", hProv, hHash, dwKeySpec, debugstr_w(sDescription), @@ -4183,18 +4192,19 @@ BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpe (OBJECTHDR**)&pCryptKey)) { SetLastError(NTE_NO_KEY); - return FALSE; + goto out; } if (!pbSignature) { *pdwSigLen = pCryptKey->dwKeyLen; - return TRUE; + ret = TRUE; + goto out; } if (pCryptKey->dwKeyLen > *pdwSigLen) { SetLastError(ERROR_MORE_DATA); *pdwSigLen = pCryptKey->dwKeyLen; - return FALSE; + goto out; } *pdwSigLen = pCryptKey->dwKeyLen; @@ -4202,22 +4212,25 @@ BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpe if (!RSAENH_CPHashData(hProv, hHash, (CONST BYTE*)sDescription, (DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0)) { - return FALSE; + goto out; } } dwHashLen = sizeof(DWORD); - if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) return FALSE; + if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) goto out; dwHashLen = RSAENH_MAX_HASH_SIZE; - if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) return FALSE; + if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) goto out; if (!build_hash_signature(pbSignature, *pdwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags)) { - return FALSE; + goto out; } - return encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbSignature, pbSignature, RSAENH_ENCRYPT); + ret = encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbSignature, pbSignature, RSAENH_ENCRYPT); +out: + RSAENH_CPDestroyKey(hProv, hCryptKey); + return ret; } /****************************************************************************** diff --git a/dlls/rsaenh/tests/rsaenh.c b/dlls/rsaenh/tests/rsaenh.c index b56f4d415a3..83ec87252c1 100644 --- a/dlls/rsaenh/tests/rsaenh.c +++ b/dlls/rsaenh/tests/rsaenh.c @@ -2093,6 +2093,7 @@ static void test_rsa_round_trip(void) ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen); ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value\n"); } + CryptDestroyKey(keyExchangeKey); CryptReleaseContext(prov, 0); CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, @@ -2334,6 +2335,7 @@ static void test_null_provider(void) ok(result, "CryptAcquireContext failed: %08x\n", GetLastError()); result = CryptGenKey(prov, CALG_RSA_SIGN, 0, &key); ok(result, "CryptGenKey with CALG_RSA_SIGN failed with error %08x\n", GetLastError()); + CryptDestroyKey(key); result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key); ok(!result, "expected CryptGetUserKey to fail\n"); result = CryptGetUserKey(prov, AT_SIGNATURE, &key); @@ -2350,11 +2352,12 @@ static void test_null_provider(void) ok(result, "CryptAcquireContext failed: %08x\n", GetLastError()); result = CryptGenKey(prov, CALG_RSA_KEYX, 0, &key); ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError()); + CryptDestroyKey(key); result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key); ok(result, "CryptGetUserKey with AT_KEYEXCHANGE failed: %08x\n", GetLastError()); + CryptDestroyKey(key); result = CryptGetUserKey(prov, AT_SIGNATURE, &key); ok(!result, "expected CryptGetUserKey to fail\n"); - CryptDestroyKey(key); CryptReleaseContext(prov, 0); CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, diff --git a/dlls/setupapi/queue.c b/dlls/setupapi/queue.c index 6c9ca642c18..6a2b8d62009 100644 --- a/dlls/setupapi/queue.c +++ b/dlls/setupapi/queue.c @@ -722,8 +722,9 @@ BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf, { SP_FILE_COPY_PARAMS_W params; INFCONTEXT context; - WCHAR dest[MAX_PATH], src[MAX_PATH]; + WCHAR dest[MAX_PATH], src[MAX_PATH], *dest_dir; INT flags; + BOOL ret = FALSE; TRACE( "hinf=%p/%p section=%s root=%s\n", hinf, hlist, debugstr_w(section), debugstr_w(src_root) ); @@ -742,18 +743,21 @@ BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf, if (!hlist) hlist = hinf; if (!hinf) hinf = hlist; if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE; - if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) return FALSE; + if (!(params.TargetDirectory = dest_dir = get_destination_dir( hinf, section ))) return FALSE; do { if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL )) - return FALSE; + goto end; if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0; if (!SetupGetIntField( &context, 4, &flags )) flags = 0; /* FIXME */ params.SourceFilename = *src ? src : NULL; - if (!SetupQueueCopyIndirectW( ¶ms )) return FALSE; + if (!SetupQueueCopyIndirectW( ¶ms )) goto end; } while (SetupFindNextLine( &context, &context )); - return TRUE; + ret = TRUE; +end: + HeapFree(GetProcessHeap(), 0, dest_dir); + return ret; } diff --git a/dlls/setupapi/tests/install.c b/dlls/setupapi/tests/install.c index 4b718fc8da6..9aed163f2ba 100644 --- a/dlls/setupapi/tests/install.c +++ b/dlls/setupapi/tests/install.c @@ -473,9 +473,16 @@ static void test_inffilelist(void) static const char inffile2[] = "test2.inf"; static const WCHAR inffile2W[] = {'t','e','s','t','2','.','i','n','f',0}; static const char invalid_inf[] = "invalid.inf"; + static const WCHAR invalid_infW[] = {'i','n','v','a','l','i','d','.','i','n','f',0}; static const char *inf = "[Version]\n" "Signature=\"$Chicago$\""; + static const char *inf2 = + "[Version]\n" + "Signature=\"$CHICAGO$\""; + static const char *infNT = + "[Version]\n" + "Signature=\"$WINDOWS NT$\""; WCHAR *p, *ptr; char dirA[MAX_PATH]; @@ -587,6 +594,55 @@ static void test_inffilelist(void) ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW), "unexpected filename %s\n",wine_dbgstr_w(p)); + /* upper case value + */ + create_inf_file(inffile2, inf2); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + todo_wine + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* signature Windows NT is also inf style win4 + */ + create_inf_file(inffile2, infNT); + expected = 3 + strlen(inffile) + strlen(inffile2); + ret = pSetupGetInfFileListW(dir, INF_STYLE_WIN4, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + todo_wine + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* old style + */ + expected = 2 + strlen(invalid_inf); + ret = pSetupGetInfFileListW(dir, INF_STYLE_OLDNT, buffer, MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + todo_wine + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,invalid_infW), "unexpected filename %s\n",wine_dbgstr_w(p)); + + /* mixed style + */ + expected = 4 + strlen(inffile) + strlen(inffile2) + strlen(invalid_inf); + ret = pSetupGetInfFileListW(dir, INF_STYLE_OLDNT | INF_STYLE_WIN4, buffer, + MAX_PATH, &outsize); + ok(ret, "expected SetupGetInfFileListW to succeed!\n"); + todo_wine + ok(expected == outsize, "expected required buffersize to be %d, got %d\n", + expected, outsize); + for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1) + ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW) || !lstrcmpW(p,invalid_infW), + "unexpected filename %s\n",wine_dbgstr_w(p)); + DeleteFile(inffile); DeleteFile(inffile2); DeleteFile(invalid_inf); diff --git a/dlls/setupapi/tests/stringtable.c b/dlls/setupapi/tests/stringtable.c index 40e4a54d189..2b7b77a0aa1 100644 --- a/dlls/setupapi/tests/stringtable.c +++ b/dlls/setupapi/tests/stringtable.c @@ -304,6 +304,7 @@ static void test_StringTableLookUpStringEx(void) ok(!memcmp(buffer, &data, 4), "unexpected data\n"); pStringTableDestroy(table); + pStringTableDestroy(table2); } static void test_StringTableStringFromId(void) diff --git a/dlls/shdocvw/tests/webbrowser.c b/dlls/shdocvw/tests/webbrowser.c index fba30befa94..cd82924b87d 100644 --- a/dlls/shdocvw/tests/webbrowser.c +++ b/dlls/shdocvw/tests/webbrowser.c @@ -1818,7 +1818,10 @@ static void test_ie_funcs(IUnknown *unk) /* Name */ hres = IWebBrowser2_get_Name(wb, &sName); ok(hres == S_OK, "getName failed: %08x, expected S_OK\n", hres); - ok(!strcmp_wa(sName, "Microsoft Web Browser Control"), "got '%s', expected 'Microsoft Web Browser Control'\n", wine_dbgstr_w(sName)); + if (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) == LANG_ENGLISH) + ok(!strcmp_wa(sName, "Microsoft Web Browser Control"), "got '%s', expected 'Microsoft Web Browser Control'\n", wine_dbgstr_w(sName)); + else /* Non-English cannot be blank. */ + ok(sName!=NULL, "get_Name return a NULL string.\n"); SysFreeString(sName); /* Quit */ diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c index 47167a7068e..6deed534401 100644 --- a/dlls/shell32/shlview.c +++ b/dlls/shell32/shlview.c @@ -1321,7 +1321,7 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn break; case NM_RETURN: - TRACE("-- NM_DBLCLK %p\n",This); + TRACE("-- NM_RETURN %p\n",This); if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This); break; @@ -1441,7 +1441,7 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn DWORD dwAttr = SFGAO_CANRENAME; pidl = (LPITEMIDLIST)lpdi->item.lParam; - TRACE("-- LVN_BEGINLABELEDITA %p\n",This); + TRACE("-- LVN_BEGINLABELEDITW %p\n",This); IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr); if (SFGAO_CANRENAME & dwAttr) diff --git a/dlls/shell32/tests/progman_dde.c b/dlls/shell32/tests/progman_dde.c index 7e6c87451c2..0a7fdaa2102 100644 --- a/dlls/shell32/tests/progman_dde.c +++ b/dlls/shell32/tests/progman_dde.c @@ -22,17 +22,8 @@ * - Covers basic CreateGroup, ShowGroup, DeleteGroup, AddItem, and DeleteItem * functionality * - Todo: Handle CommonGroupFlag - * Handle Difference between administrator and non-administrator calls - * as documented * Better AddItem Tests (Lots of parameters to test) * Tests for Invalid Characters in Names / Invalid Parameters - * - Technically, calling as an administrator creates groups in the CSIDL_COMMON_PROGRAMS - * directory. Win 9x and non-administrator calls us CSIDL_PROGRAMS directory. - * Original plans were to check that items/groups were created in appropriate - * places. As of this writing and in order to simplify the test code, it now - * checks for existence in either place. From web searches, it is not at all - * obvious or trivial to detect if the call is coming from an administrator or - * non-administrator. IsUserAnAdmin */ #include @@ -60,12 +51,9 @@ #define DDE_TEST_COMPOUND 0x00070000 #define DDE_TEST_CALLMASK 0x00ff0000 -/* Type of Test (Common, Individual) */ -#define DDE_TEST_COMMON 0x01000000 -#define DDE_TEST_INDIVIDUAL 0x02000000 - #define DDE_TEST_NUMMASK 0x0000ffff +static HRESULT (WINAPI *pSHGetLocalizedName)(LPCWSTR, LPWSTR, UINT, int *); static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL); static BOOL (WINAPI *pReadCabinetState)(CABINETSTATE *, int); @@ -74,44 +62,66 @@ static void init_function_pointers(void) HMODULE hmod; hmod = GetModuleHandleA("shell32.dll"); + pSHGetLocalizedName = (void*)GetProcAddress(hmod, "SHGetLocalizedName"); pSHGetSpecialFolderPathA = (void*)GetProcAddress(hmod, "SHGetSpecialFolderPathA"); pReadCabinetState = (void*)GetProcAddress(hmod, "ReadCabinetState"); if (!pReadCabinetState) pReadCabinetState = (void*)GetProcAddress(hmod, (LPSTR)651); } -static char CommonPrograms[MAX_PATH]; -static char Programs[MAX_PATH]; +static BOOL use_common(void) +{ + HMODULE hmod; + static BOOL (WINAPI *pIsNTAdmin)(DWORD, LPDWORD); + + /* IsNTAdmin() is available on all platforms. */ + hmod = LoadLibraryA("advpack.dll"); + pIsNTAdmin = (void*)GetProcAddress(hmod, "IsNTAdmin"); + + if (!pIsNTAdmin(0, NULL)) + { + /* We are definitely not an administrator */ + FreeLibrary(hmod); + return FALSE; + } + FreeLibrary(hmod); + + /* If we end up here we are on NT4+ as Win9x and WinMe don't have the + * notion of administrators (as we need it). + */ + + /* As of Vista we should always use the users directory. Tests with the + * real Administrator account on Windows 7 proved this. + * + * FIXME: We need a better way of identifying Vista+ as currently this check + * also covers Wine and we don't know yet which behavior we want to follow. + */ + if (pSHGetLocalizedName) + return FALSE; + + return TRUE; +} + +static char ProgramsDir[MAX_PATH]; static char Group1Title[MAX_PATH] = "Group1"; static char Group2Title[MAX_PATH] = "Group2"; static char Group3Title[MAX_PATH] = "Group3"; -static char Startup[MAX_PATH] = "Startup"; static char StartupTitle[MAX_PATH] = "Startup"; static void init_strings(void) { char startup[MAX_PATH]; + char commonprograms[MAX_PATH]; + char programs[MAX_PATH]; + CABINETSTATE cs; if (pSHGetSpecialFolderPathA) { - pSHGetSpecialFolderPathA(NULL, Programs, CSIDL_PROGRAMS, FALSE); - if (!pSHGetSpecialFolderPathA(NULL, CommonPrograms, CSIDL_COMMON_PROGRAMS, FALSE)) - { - /* Win9x */ - lstrcpyA(CommonPrograms, Programs); - } - if (GetProcAddress(GetModuleHandleA("shell32.dll"), "SHGetKnownFolderPath")) - { - /* Vista and higher use CSIDL_PROGRAMS for these tests. - * Wine doesn't have SHGetKnownFolderPath yet but should most likely follow - * this new ProgMan DDE behavior once implemented. - */ - lstrcpyA(CommonPrograms, Programs); - } + pSHGetSpecialFolderPathA(NULL, programs, CSIDL_PROGRAMS, FALSE); + pSHGetSpecialFolderPathA(NULL, commonprograms, CSIDL_COMMON_PROGRAMS, FALSE); pSHGetSpecialFolderPathA(NULL, startup, CSIDL_STARTUP, FALSE); - lstrcpyA(Startup, (strrchr(startup, '\\') + 1)); } else { @@ -120,41 +130,70 @@ static void init_strings(void) LONG res; /* Older Win9x and NT4 */ + RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &key); - size = sizeof(Programs); - RegQueryValueExA(key, "Programs", NULL, NULL, (LPBYTE)&Programs, &size); + size = sizeof(programs); + RegQueryValueExA(key, "Programs", NULL, NULL, (LPBYTE)&programs, &size); size = sizeof(startup); RegQueryValueExA(key, "Startup", NULL, NULL, (LPBYTE)&startup, &size); - lstrcpyA(Startup, (strrchr(startup, '\\') + 1)); RegCloseKey(key); RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &key); - size = sizeof(CommonPrograms); - res = RegQueryValueExA(key, "Common Programs", NULL, NULL, (LPBYTE)&CommonPrograms, &size); + size = sizeof(commonprograms); + res = RegQueryValueExA(key, "Common Programs", NULL, NULL, (LPBYTE)&commonprograms, &size); RegCloseKey(key); - if (res != ERROR_SUCCESS) - { - /* Win9x */ - lstrcpyA(CommonPrograms, Programs); - } } + /* ProgramsDir on Vista+ is always the users one (CSIDL_PROGRAMS). Before Vista + * it depends on whether the user is an administrator (CSIDL_COMMON_PROGRAMS) or + * not (CSIDL_PROGRAMS). + */ + if (use_common()) + lstrcpyA(ProgramsDir, commonprograms); + else + lstrcpyA(ProgramsDir, programs); + memset(&cs, 0, sizeof(cs)); pReadCabinetState(&cs, sizeof(cs)); if (cs.fFullPathTitle == -1) { - lstrcpyA(Group1Title, CommonPrograms); + lstrcpyA(Group1Title, ProgramsDir); lstrcatA(Group1Title, "\\Group1"); - lstrcpyA(Group2Title, CommonPrograms); + lstrcpyA(Group2Title, ProgramsDir); lstrcatA(Group2Title, "\\Group2"); - lstrcpyA(Group3Title, CommonPrograms); + lstrcpyA(Group3Title, ProgramsDir); lstrcatA(Group3Title, "\\Group3"); lstrcpyA(StartupTitle, startup); } else { - lstrcpyA(StartupTitle, Startup); + /* Vista has the nice habit of displaying the full path in English + * and the short one localized. CSIDL_STARTUP on Vista gives us the + * English version so we have to 'translate' this one. + * + * MSDN claims it should be used for files not folders but this one + * suits our purposes just fine. + */ + if (pSHGetLocalizedName) + { + WCHAR startupW[MAX_PATH]; + WCHAR module[MAX_PATH]; + WCHAR module_expanded[MAX_PATH]; + WCHAR localized[MAX_PATH]; + int id; + + MultiByteToWideChar(CP_ACP, 0, startup, -1, startupW, sizeof(startupW)/sizeof(WCHAR)); + pSHGetLocalizedName(startupW, module, MAX_PATH, &id); + ExpandEnvironmentStringsW(module, module_expanded, MAX_PATH); + LoadStringW(GetModuleHandleW(module_expanded), id, localized, MAX_PATH); + + WideCharToMultiByte(CP_ACP, 0, localized, -1, StartupTitle, sizeof(StartupTitle), NULL, NULL); + } + else + { + lstrcpyA(StartupTitle, (strrchr(startup, '\\') + 1)); + } } } @@ -328,10 +367,7 @@ static void CheckFileExistsInProgramGroups(const char *nameToCheck, int shouldEx DWORD attributes; int len; - if (testParams & DDE_TEST_COMMON) - lstrcpyA(path, CommonPrograms); - else - lstrcpyA(path, Programs); + lstrcpyA(path, ProgramsDir); len = strlen(path) + strlen(nameToCheck)+1; if (groupName != NULL) @@ -579,22 +615,22 @@ static int DdeTestProgman(DWORD instance, HCONV hConv) GetTempFileNameA(temppath, "dde", 0, f2g3); /* CreateGroup Tests (including AddItem, DeleteItem) */ - CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_COMMON|DDE_TEST_CREATEGROUP|testnum++); + CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++); CreateAddItemText(itemtext, f1g1, "f1g1Name"); - AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f1g1Name.lnk", "Group1", DDE_TEST_COMMON|DDE_TEST_ADDITEM|testnum++); + AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f1g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++); CreateAddItemText(itemtext, f2g1, "f2g1Name"); - AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_COMMON|DDE_TEST_ADDITEM|testnum++); - DeleteItemTest(instance, hConv, "[DeleteItem(f2g1Name)]", DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_COMMON|DDE_TEST_DELETEITEM|testnum++); + AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++); + DeleteItemTest(instance, hConv, "[DeleteItem(f2g1Name)]", DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++); CreateAddItemText(itemtext, f3g1, "f3g1Name"); - AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_COMMON|DDE_TEST_ADDITEM|testnum++); - CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_COMMON|DDE_TEST_CREATEGROUP|testnum++); + AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++); + CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_CREATEGROUP|testnum++); /* Create Group that already exists - same instance */ - CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_COMMON|DDE_TEST_CREATEGROUP|testnum++); + CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++); /* ShowGroup Tests */ - ShowGroupTest(instance, hConv, "[ShowGroup(Group1)]", DMLERR_NOTPROCESSED, Startup, StartupTitle, TRUE, DDE_TEST_SHOWGROUP|testnum++); - DeleteItemTest(instance, hConv, "[DeleteItem(f3g1Name)]", DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_COMMON|DDE_TEST_DELETEITEM|testnum++); - ShowGroupTest(instance, hConv, "[ShowGroup(Startup,0)]", DMLERR_NO_ERROR, Startup, StartupTitle, TRUE, DDE_TEST_SHOWGROUP|testnum++); + ShowGroupTest(instance, hConv, "[ShowGroup(Group1)]", DMLERR_NOTPROCESSED, "Group1", Group1Title, TRUE, DDE_TEST_SHOWGROUP|testnum++); + DeleteItemTest(instance, hConv, "[DeleteItem(f3g1Name)]", DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++); + ShowGroupTest(instance, hConv, "[ShowGroup(Startup,0)]", DMLERR_NO_ERROR, "Startup", StartupTitle, TRUE, DDE_TEST_SHOWGROUP|testnum++); ShowGroupTest(instance, hConv, "[ShowGroup(Group1,0)]", DMLERR_NO_ERROR, "Group1", Group1Title, FALSE, DDE_TEST_SHOWGROUP|testnum++); /* DeleteGroup Test - Note that Window is Open for this test */ @@ -606,7 +642,7 @@ static int DdeTestProgman(DWORD instance, HCONV hConv) lstrcatA(comptext, itemtext); CreateAddItemText(itemtext, f2g3, "f2g3Name"); lstrcatA(comptext, itemtext); - CompoundCommandTest(instance, hConv, comptext, DMLERR_NO_ERROR, "Group3", Group3Title, "f1g3Name.lnk", "f2g3Name.lnk", DDE_TEST_COMMON|DDE_TEST_COMPOUND|testnum++); + CompoundCommandTest(instance, hConv, comptext, DMLERR_NO_ERROR, "Group3", Group3Title, "f1g3Name.lnk", "f2g3Name.lnk", DDE_TEST_COMPOUND|testnum++); DeleteGroupTest(instance, hConv, "[DeleteGroup(Group3)]", DMLERR_NO_ERROR, "Group3", DDE_TEST_DELETEGROUP|testnum++); @@ -626,8 +662,8 @@ static int DdeTestProgman(DWORD instance, HCONV hConv) static void DdeTestProgman2(DWORD instance, HCONV hConv, int testnum) { /* Create Group that already exists on a separate connection */ - CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_COMMON|DDE_TEST_CREATEGROUP|testnum++); - DeleteGroupTest(instance, hConv, "[DeleteGroup(Group2)]", DMLERR_NO_ERROR, "Group2", DDE_TEST_COMMON|DDE_TEST_DELETEGROUP|testnum++); + CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_CREATEGROUP|testnum++); + DeleteGroupTest(instance, hConv, "[DeleteGroup(Group2)]", DMLERR_NO_ERROR, "Group2", DDE_TEST_DELETEGROUP|testnum++); } START_TEST(progman_dde) diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index caae4254f06..f676a2a7664 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -647,8 +647,12 @@ static void test_CallForAttributes(void) * key. So the test will return at this point, if run on wine. */ lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszMyDocumentsKey, 0, KEY_WRITE|KEY_READ, &hKey); - ok (lResult == ERROR_SUCCESS, "RegOpenKeyEx failed! result: %08x\n", lResult); + ok (lResult == ERROR_SUCCESS || + lResult == ERROR_ACCESS_DENIED, + "RegOpenKeyEx failed! result: %08x\n", lResult); if (lResult != ERROR_SUCCESS) { + if (lResult == ERROR_ACCESS_DENIED) + skip("Not enough rights to open the registry key\n"); IMalloc_Free(ppM, pidlMyDocuments); IShellFolder_Release(psfDesktop); return; diff --git a/dlls/shlwapi/Makefile.in b/dlls/shlwapi/Makefile.in index 20329f686fc..2594a19ced5 100644 --- a/dlls/shlwapi/Makefile.in +++ b/dlls/shlwapi/Makefile.in @@ -6,7 +6,7 @@ VPATH = @srcdir@ MODULE = shlwapi.dll IMPORTLIB = shlwapi IMPORTS = uuid user32 gdi32 advapi32 kernel32 ntdll -DELAYIMPORTS = oleaut32 ole32 comctl32 comdlg32 mpr mlang urlmon shell32 winmm version dnsapi +DELAYIMPORTS = oleaut32 ole32 comctl32 comdlg32 mpr mlang urlmon shell32 winmm version C_SRCS = \ assoc.c \ diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index 0ecbab81ed5..f127ca1f903 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -1128,7 +1128,7 @@ HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent) * PARAMS * lpUnkSink [I] Sink for the connection point advise call * riid [I] REFIID of connection point to advise - * bAdviseOnly [I] TRUE = Advise only, FALSE = Unadvise first + * fConnect [I] TRUE = Connection being establisted, FALSE = broken * lpUnknown [I] Object supporting the IConnectionPointContainer interface * lpCookie [O] Pointer to connection point cookie * lppCP [O] Destination for the IConnectionPoint found @@ -1140,7 +1140,7 @@ HWND WINAPI SHSetParentHwnd(HWND hWnd, HWND hWndParent) * E_NOINTERFACE, if lpUnknown isn't an IConnectionPointContainer, * Or an HRESULT error code if any call fails. */ -HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL bAdviseOnly, +HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL fConnect, IUnknown* lpUnknown, LPDWORD lpCookie, IConnectionPoint **lppCP) { @@ -1148,7 +1148,7 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL b IConnectionPointContainer* lpContainer; IConnectionPoint *lpCP; - if(!lpUnknown || (bAdviseOnly && !lpUnkSink)) + if(!lpUnknown || (fConnect && !lpUnkSink)) return E_FAIL; if(lppCP) @@ -1162,9 +1162,10 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL b if (SUCCEEDED(hRet)) { - if(!bAdviseOnly) + if(!fConnect) hRet = IConnectionPoint_Unadvise(lpCP, *lpCookie); - hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie); + else + hRet = IConnectionPoint_Advise(lpCP, lpUnkSink, lpCookie); if (FAILED(hRet)) *lpCookie = 0; @@ -2929,20 +2930,27 @@ static HRESULT SHLWAPI_InvokeByIID( { IEnumConnections *enumerator; CONNECTDATA rgcd; + static DISPPARAMS empty = {NULL, NULL, 0, 0}; + DISPPARAMS* params = dispParams; HRESULT result = IConnectionPoint_EnumConnections(iCP, &enumerator); if (FAILED(result)) return result; + /* Invoke is never happening with an NULL dispParams */ + if (!params) + params = ∅ + while(IEnumConnections_Next(enumerator, 1, &rgcd, NULL)==S_OK) { IDispatch *dispIface; - if (SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, iid, (LPVOID*)&dispIface)) || + if ((iid && SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, iid, (LPVOID*)&dispIface))) || SUCCEEDED(IUnknown_QueryInterface(rgcd.pUnk, &IID_IDispatch, (LPVOID*)&dispIface))) { - IDispatch_Invoke(dispIface, dispId, &IID_NULL, 0, DISPATCH_METHOD, dispParams, NULL, NULL, NULL); + IDispatch_Invoke(dispIface, dispId, &IID_NULL, 0, DISPATCH_METHOD, params, NULL, NULL, NULL); IDispatch_Release(dispIface); } + IUnknown_Release(rgcd.pUnk); } IEnumConnections_Release(enumerator); @@ -2965,6 +2973,8 @@ HRESULT WINAPI IConnectionPoint_InvokeWithCancel( IConnectionPoint* iCP, result = IConnectionPoint_GetConnectionInterface(iCP, &iid); if (SUCCEEDED(result)) result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams); + else + result = SHLWAPI_InvokeByIID(iCP, NULL, dispId, dispParams); return result; } @@ -2988,6 +2998,8 @@ HRESULT WINAPI IConnectionPoint_SimpleInvoke( result = IConnectionPoint_GetConnectionInterface(iCP, &iid); if (SUCCEEDED(result)) result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams); + else + result = SHLWAPI_InvokeByIID(iCP, NULL, dispId, dispParams); return result; } @@ -4697,3 +4709,22 @@ INT WINAPI ZoneCheckUrlExW(LPWSTR szURL, PVOID pUnknown, DWORD dwUnknown2, return 0; } + +/*********************************************************************** + * SHVerbExistsNA [SHLWAPI.196] + * + * + * PARAMS + * + * verb [I] a string, often appears to be an extension. + * + * Other parameters currently unknown. + * + * RETURNS + * unknown + */ +INT WINAPI SHVerbExistsNA(LPSTR verb, PVOID pUnknown, PVOID pUnknown2, DWORD dwUnknown3) +{ + FIXME("(%s, %p, %p, %i) STUB\n",verb, pUnknown, pUnknown2, dwUnknown3); + return 0; +} diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index a8e7428c6f3..c877dd16e54 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -193,7 +193,7 @@ 193 stdcall -noname SHGetCurColorRes() 194 stdcall -noname SHWaitForSendMessageThread(ptr long) 195 stdcall -noname SHIsExpandableFolder(ptr ptr) -196 stdcall -noname DnsRecordSetCompare(ptr ptr ptr ptr) dnsapi.DnsRecordSetCompare +196 stdcall -noname SHVerbExistsNA(str ptr ptr long) 197 stdcall -noname SHFillRectClr(long ptr long) 198 stdcall -noname SHSearchMapInt(ptr ptr long long) 199 stdcall -noname IUnknown_Set(ptr ptr) diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c index c22313ab5d2..daf221c45fd 100644 --- a/dlls/shlwapi/tests/ordinal.c +++ b/dlls/shlwapi/tests/ordinal.c @@ -19,12 +19,14 @@ #include +#define COBJMACROS #include "wine/test.h" #include "winbase.h" #include "winerror.h" #include "winuser.h" #include "ole2.h" #include "oaidl.h" +#include "ocidl.h" /* Function ptrs for ordinal calls */ static HMODULE hShlwapi; @@ -36,6 +38,9 @@ static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD); static BOOL (WINAPI *pSHUnlockShared)(LPVOID); static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD); static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...); +static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*); +static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD); +static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **); static void test_GetAcceptLanguagesA(void) { HRESULT retval; @@ -523,6 +528,683 @@ static void test_SHPackDispParams(void) ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3)); } +typedef struct _disp +{ + const IDispatchVtbl *vtbl; + LONG refCount; +} Disp; + +typedef struct _contain +{ + const IConnectionPointContainerVtbl *vtbl; + LONG refCount; + + UINT ptCount; + IConnectionPoint **pt; +} Contain; + +typedef struct _cntptn +{ + const IConnectionPointVtbl *vtbl; + LONG refCount; + + Contain *container; + GUID id; + UINT sinkCount; + IUnknown **sink; +} ConPt; + +typedef struct _enum +{ + const IEnumConnectionsVtbl *vtbl; + LONG refCount; + + UINT idx; + ConPt *pt; +} EnumCon; + +typedef struct _enumpt +{ + const IEnumConnectionPointsVtbl *vtbl; + LONG refCount; + + int idx; + Contain *container; +} EnumPt; + + +static HRESULT WINAPI Disp_QueryInterface( + IDispatch* This, + REFIID riid, + void **ppvObject) +{ + trace("\n"); + *ppvObject = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch)) + { + *ppvObject = This; + } + + if (*ppvObject) + { + IUnknown_AddRef(This); + return S_OK; + } + + trace("no interface\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI Disp_AddRef(IDispatch* This) +{ + Disp *iface = (Disp*)This; + return InterlockedIncrement(&iface->refCount); +} + +static ULONG WINAPI Disp_Release(IDispatch* This) +{ + Disp *iface = (Disp*)This; + ULONG ret; + + ret = InterlockedDecrement(&iface->refCount); + if (ret == 0) + HeapFree(GetProcessHeap(),0,This); + return ret; +} + +static HRESULT WINAPI Disp_GetTypeInfoCount( + IDispatch* This, + UINT *pctinfo) +{ + trace("\n"); + return ERROR_SUCCESS; +} + +static HRESULT WINAPI Disp_GetTypeInfo( + IDispatch* This, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo) +{ + trace("\n"); + return ERROR_SUCCESS; +} + +static HRESULT WINAPI Disp_GetIDsOfNames( + IDispatch* This, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId) +{ + trace("\n"); + return ERROR_SUCCESS; +} + +static HRESULT WINAPI Disp_Invoke( + IDispatch* This, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr); + + ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n"); + ok(pDispParams != NULL, "Invoked with NULL pDispParams\n"); + ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags); + ok(lcid == 0,"Wrong lcid %x\n",lcid); + if (dispIdMember == 0xa0) + { + ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs); + ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs); + ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs); + ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg); + } + else if (dispIdMember == 0xa1) + { + ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs); + ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs); + ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs); + ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg)); + ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg)); + ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1)); + ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1)); + } + + return ERROR_SUCCESS; +} + +static const IDispatchVtbl disp_vtbl = { + Disp_QueryInterface, + Disp_AddRef, + Disp_Release, + + Disp_GetTypeInfoCount, + Disp_GetTypeInfo, + Disp_GetIDsOfNames, + Disp_Invoke +}; + +static HRESULT WINAPI Enum_QueryInterface( + IEnumConnections* This, + REFIID riid, + void **ppvObject) +{ + trace("\n"); + *ppvObject = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections)) + { + *ppvObject = This; + } + + if (*ppvObject) + { + IUnknown_AddRef(This); + return S_OK; + } + + trace("no interface\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI Enum_AddRef(IEnumConnections* This) +{ + EnumCon *iface = (EnumCon*)This; + return InterlockedIncrement(&iface->refCount); +} + +static ULONG WINAPI Enum_Release(IEnumConnections* This) +{ + EnumCon *iface = (EnumCon*)This; + ULONG ret; + + ret = InterlockedDecrement(&iface->refCount); + if (ret == 0) + HeapFree(GetProcessHeap(),0,This); + return ret; +} + +static HRESULT WINAPI Enum_Next( + IEnumConnections* This, + ULONG cConnections, + LPCONNECTDATA rgcd, + ULONG *pcFetched) +{ + EnumCon *iface = (EnumCon*)This; + + trace("\n"); + if (cConnections > 0 && iface->idx < iface->pt->sinkCount) + { + rgcd->pUnk = iface->pt->sink[iface->idx]; + IUnknown_AddRef(iface->pt->sink[iface->idx]); + rgcd->dwCookie=0xff; + if (pcFetched) + *pcFetched = 1; + iface->idx++; + return S_OK; + } + + return E_FAIL; +} + +static HRESULT WINAPI Enum_Skip( + IEnumConnections* This, + ULONG cConnections) +{ + trace("\n"); + return E_FAIL; +} + +static HRESULT WINAPI Enum_Reset( + IEnumConnections* This) +{ + trace("\n"); + return E_FAIL; +} + +static HRESULT WINAPI Enum_Clone( + IEnumConnections* This, + IEnumConnections **ppEnum) +{ + trace("\n"); + return E_FAIL; +} + +static const IEnumConnectionsVtbl enum_vtbl = { + + Enum_QueryInterface, + Enum_AddRef, + Enum_Release, + Enum_Next, + Enum_Skip, + Enum_Reset, + Enum_Clone +}; + +static HRESULT WINAPI ConPt_QueryInterface( + IConnectionPoint* This, + REFIID riid, + void **ppvObject) +{ + trace("\n"); + *ppvObject = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint)) + { + *ppvObject = This; + } + + if (*ppvObject) + { + IUnknown_AddRef(This); + return S_OK; + } + + trace("no interface\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI ConPt_AddRef( + IConnectionPoint* This) +{ + ConPt *iface = (ConPt*)This; + return InterlockedIncrement(&iface->refCount); +} + +static ULONG WINAPI ConPt_Release( + IConnectionPoint* This) +{ + ConPt *iface = (ConPt*)This; + ULONG ret; + + ret = InterlockedDecrement(&iface->refCount); + if (ret == 0) + { + if (iface->sinkCount > 0) + { + int i; + for (i = 0; i < iface->sinkCount; i++) + { + if (iface->sink[i]) + IUnknown_Release(iface->sink[i]); + } + HeapFree(GetProcessHeap(),0,iface->sink); + } + HeapFree(GetProcessHeap(),0,This); + } + return ret; +} + +static HRESULT WINAPI ConPt_GetConnectionInterface( + IConnectionPoint* This, + IID *pIID) +{ + static int i = 0; + ConPt *iface = (ConPt*)This; + trace("\n"); + if (i==0) + { + i++; + return E_FAIL; + } + else + memcpy(pIID,&iface->id,sizeof(GUID)); + return S_OK; +} + +static HRESULT WINAPI ConPt_GetConnectionPointContainer( + IConnectionPoint* This, + IConnectionPointContainer **ppCPC) +{ + ConPt *iface = (ConPt*)This; + trace("\n"); + + *ppCPC = (IConnectionPointContainer*)iface->container; + return S_OK; +} + +static HRESULT WINAPI ConPt_Advise( + IConnectionPoint* This, + IUnknown *pUnkSink, + DWORD *pdwCookie) +{ + ConPt *iface = (ConPt*)This; + trace("\n"); + + if (iface->sinkCount == 0) + iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*)); + else + iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1)); + iface->sink[iface->sinkCount] = pUnkSink; + IUnknown_AddRef(pUnkSink); + iface->sinkCount++; + *pdwCookie = iface->sinkCount; + return S_OK; +} + +static HRESULT WINAPI ConPt_Unadvise( + IConnectionPoint* This, + DWORD dwCookie) +{ + ConPt *iface = (ConPt*)This; + trace("\n"); + + if (dwCookie > iface->sinkCount) + return E_FAIL; + else + { + IUnknown_Release(iface->sink[dwCookie-1]); + iface->sink[dwCookie-1] = NULL; + } + return S_OK; +} + +static HRESULT WINAPI ConPt_EnumConnections( + IConnectionPoint* This, + IEnumConnections **ppEnum) +{ + EnumCon *ec; + + trace("\n"); + ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon)); + ec->vtbl = &enum_vtbl; + ec->refCount = 1; + ec->pt = (ConPt*)This; + ec->idx = 0; + *ppEnum = (IEnumConnections*)ec; + + return S_OK; +} + +static const IConnectionPointVtbl point_vtbl = { + ConPt_QueryInterface, + ConPt_AddRef, + ConPt_Release, + + ConPt_GetConnectionInterface, + ConPt_GetConnectionPointContainer, + ConPt_Advise, + ConPt_Unadvise, + ConPt_EnumConnections +}; + +static HRESULT WINAPI EnumPt_QueryInterface( + IEnumConnectionPoints* This, + REFIID riid, + void **ppvObject) +{ + trace("\n"); + *ppvObject = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints)) + { + *ppvObject = This; + } + + if (*ppvObject) + { + IUnknown_AddRef(This); + return S_OK; + } + + trace("no interface\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This) +{ + EnumPt *iface = (EnumPt*)This; + return InterlockedIncrement(&iface->refCount); +} + +static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This) +{ + EnumPt *iface = (EnumPt*)This; + ULONG ret; + + ret = InterlockedDecrement(&iface->refCount); + if (ret == 0) + HeapFree(GetProcessHeap(),0,This); + return ret; +} + +static HRESULT WINAPI EnumPt_Next( + IEnumConnectionPoints* This, + ULONG cConnections, + IConnectionPoint **rgcd, + ULONG *pcFetched) +{ + EnumPt *iface = (EnumPt*)This; + + trace("\n"); + if (cConnections > 0 && iface->idx < iface->container->ptCount) + { + *rgcd = iface->container->pt[iface->idx]; + IUnknown_AddRef(iface->container->pt[iface->idx]); + if (pcFetched) + *pcFetched = 1; + iface->idx++; + return S_OK; + } + + return E_FAIL; +} + +static HRESULT WINAPI EnumPt_Skip( + IEnumConnectionPoints* This, + ULONG cConnections) +{ + trace("\n"); + return E_FAIL; +} + +static HRESULT WINAPI EnumPt_Reset( + IEnumConnectionPoints* This) +{ + trace("\n"); + return E_FAIL; +} + +static HRESULT WINAPI EnumPt_Clone( + IEnumConnectionPoints* This, + IEnumConnectionPoints **ppEnumPt) +{ + trace("\n"); + return E_FAIL; +} + +static const IEnumConnectionPointsVtbl enumpt_vtbl = { + + EnumPt_QueryInterface, + EnumPt_AddRef, + EnumPt_Release, + EnumPt_Next, + EnumPt_Skip, + EnumPt_Reset, + EnumPt_Clone +}; + +static HRESULT WINAPI Contain_QueryInterface( + IConnectionPointContainer* This, + REFIID riid, + void **ppvObject) +{ + trace("\n"); + *ppvObject = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer)) + { + *ppvObject = This; + } + + if (*ppvObject) + { + IUnknown_AddRef(This); + return S_OK; + } + + trace("no interface\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI Contain_AddRef( + IConnectionPointContainer* This) +{ + Contain *iface = (Contain*)This; + return InterlockedIncrement(&iface->refCount); +} + +static ULONG WINAPI Contain_Release( + IConnectionPointContainer* This) +{ + Contain *iface = (Contain*)This; + ULONG ret; + + ret = InterlockedDecrement(&iface->refCount); + if (ret == 0) + { + if (iface->ptCount > 0) + { + int i; + for (i = 0; i < iface->ptCount; i++) + IUnknown_Release(iface->pt[i]); + HeapFree(GetProcessHeap(),0,iface->pt); + } + HeapFree(GetProcessHeap(),0,This); + } + return ret; +} + +static HRESULT WINAPI Contain_EnumConnectionPoints( + IConnectionPointContainer* This, + IEnumConnectionPoints **ppEnum) +{ + EnumPt *ec; + + trace("\n"); + ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt)); + ec->vtbl = &enumpt_vtbl; + ec->refCount = 1; + ec->idx= 0; + ec->container = (Contain*)This; + *ppEnum = (IEnumConnectionPoints*)ec; + + return S_OK; +} + +static HRESULT WINAPI Contain_FindConnectionPoint( + IConnectionPointContainer* This, + REFIID riid, + IConnectionPoint **ppCP) +{ + Contain *iface = (Contain*)This; + ConPt *pt; + trace("\n"); + + if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0) + { + pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt)); + pt->vtbl = &point_vtbl; + pt->refCount = 1; + pt->sinkCount = 0; + pt->sink = NULL; + pt->container = iface; + + if (iface->ptCount == 0) + iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*)); + else + iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1)); + iface->pt[iface->ptCount] = (IConnectionPoint*)pt; + iface->ptCount++; + + *ppCP = (IConnectionPoint*)pt; + } + else + { + *ppCP = iface->pt[0]; + IUnknown_AddRef((IUnknown*)*ppCP); + } + + return S_OK; +} + +static const IConnectionPointContainerVtbl contain_vtbl = { + Contain_QueryInterface, + Contain_AddRef, + Contain_Release, + + Contain_EnumConnectionPoints, + Contain_FindConnectionPoint +}; + +void test_IConnectionPoint(void) +{ + HRESULT rc; + ULONG ref; + IConnectionPoint *point; + Contain *container; + Disp *dispatch; + DWORD cookie = 0xffffffff; + DISPPARAMS params; + VARIANT vars[10]; + + if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint) + { + win_skip("IConnectionPoint Apis not present\n"); + return; + } + + container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain)); + container->vtbl = &contain_vtbl; + container->refCount = 1; + container->ptCount = 0; + container->pt = NULL; + + dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp)); + dispatch->vtbl = &disp_vtbl; + dispatch->refCount = 1; + + rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + ok(point != NULL, "returned ConnectionPoint is NULL\n"); + ok(cookie != 0xffffffff, "invalid cookie returned\n"); + + rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + + if (pSHPackDispParams) + { + memset(¶ms, 0xc0, sizeof(params)); + memset(vars, 0xc0, sizeof(vars)); + rc = pSHPackDispParams(¶ms, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe); + ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc); + + rc = pIConnectionPoint_SimpleInvoke(point,0xa1,¶ms); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + } + else + win_skip("pSHPackDispParams not present\n"); + + rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + +/* MSDN says this should be required but it crashs on XP + IUnknown_Release(point); +*/ + ref = IUnknown_Release((IUnknown*)container); + ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref); + ref = IUnknown_Release((IUnknown*)dispatch); + ok(ref == 0, "leftover IDispatch reference %i\n",ref); +} + START_TEST(ordinal) { hShlwapi = GetModuleHandleA("shlwapi.dll"); @@ -534,6 +1216,9 @@ START_TEST(ordinal) pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9); pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10); pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282); + pIConnectionPoint_SimpleInvoke=(void*)GetProcAddress(hShlwapi,(char*)284); + pIConnectionPoint_InvokeWithCancel=(void*)GetProcAddress(hShlwapi,(char*)283); + pConnectToConnectionPoint=(void*)GetProcAddress(hShlwapi,(char*)168); test_GetAcceptLanguagesA(); test_SHSearchMapInt(); @@ -541,4 +1226,5 @@ START_TEST(ordinal) test_fdsa(); test_GetShellSecurityDescriptor(); test_SHPackDispParams(); + test_IConnectionPoint(); } diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index 0c2900e98a6..0138c35838c 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -1023,7 +1023,7 @@ static void test_ParseURL(void) parseda.pszSuffix, test->url+test->protocol_len+1); ok(parseda.cchSuffix == strlen(test->url+test->protocol_len+1), "parseda.pszSuffix = %d, expected %d\n", - parseda.cchSuffix, strlen(test->url+test->protocol_len+1)); + parseda.cchSuffix, lstrlenA(test->url+test->protocol_len+1)); ok(parseda.nScheme == test->scheme, "parseda.nScheme = %d, expected %d\n", parseda.nScheme, test->scheme); }else { @@ -1046,7 +1046,7 @@ static void test_ParseURL(void) wine_dbgstr_w(parsedw.pszSuffix), wine_dbgstr_w(url+test->protocol_len+1)); ok(parsedw.cchSuffix == strlen(test->url+test->protocol_len+1), "parsedw.pszSuffix = %d, expected %d\n", - parsedw.cchSuffix, strlen(test->url+test->protocol_len+1)); + parsedw.cchSuffix, lstrlenA(test->url+test->protocol_len+1)); ok(parsedw.nScheme == test->scheme, "parsedw.nScheme = %d, expected %d\n", parsedw.nScheme, test->scheme); }else { diff --git a/dlls/snmpapi/main.c b/dlls/snmpapi/main.c index 9e14a194876..1c4d1fa36cd 100644 --- a/dlls/snmpapi/main.c +++ b/dlls/snmpapi/main.c @@ -112,6 +112,8 @@ static void asn_any_free(AsnAny *any) any->asnType = ASN_NULL; } +static ULONGLONG startTime; + /*********************************************************************** * DllMain for SNMPAPI */ @@ -127,6 +129,7 @@ BOOL WINAPI DllMain( return FALSE; /* prefer native version */ case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDLL); + startTime = GetTickCount64(); break; case DLL_PROCESS_DETACH: break; @@ -136,6 +139,21 @@ BOOL WINAPI DllMain( } /*********************************************************************** + * SnmpSvcGetUptime (SNMPAPI.@) + * + * BUGS + * This returns the number of centiseconds since the DLL was loaded, + * rather than the number of centiseconds since the SNMP service was + * started, since there isn't yet any SNMP service in Wine. + */ +DWORD WINAPI SnmpSvcGetUptime(void) +{ + ULONGLONG now = GetTickCount64(); + + return (now - startTime) / 10; +} + +/*********************************************************************** * SnmpUtilDbgPrint (SNMPAPI.@) * * NOTES diff --git a/dlls/snmpapi/snmpapi.spec b/dlls/snmpapi/snmpapi.spec index 385ca8ac7a4..208231ecfbe 100644 --- a/dlls/snmpapi/snmpapi.spec +++ b/dlls/snmpapi/snmpapi.spec @@ -11,7 +11,7 @@ @ stub SnmpSvcGenerateTrap @ stub SnmpSvcGenerateWarmStartTrap @ stub SnmpSvcGetEnterpriseOID -@ stub SnmpSvcGetUptime +@ stdcall SnmpSvcGetUptime() @ stub SnmpSvcInitUptime @ stub SnmpSvcReleaseMessage @ stub SnmpSvcReportEvent diff --git a/dlls/urlmon/Makefile.in b/dlls/urlmon/Makefile.in index 448a0693a55..f0dd490942f 100644 --- a/dlls/urlmon/Makefile.in +++ b/dlls/urlmon/Makefile.in @@ -4,7 +4,9 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = urlmon.dll IMPORTLIB = urlmon -IMPORTS = uuid ole32 shlwapi wininet user32 advapi32 kernel32 ntdll +IMPORTS = uuid ole32 rpcrt4 shlwapi wininet user32 advapi32 kernel32 ntdll +EXTRADEFS = -D_URLMON_ -DENTRY_PREFIX=URLMON_ -DPROXY_DELEGATION -DREGISTER_PROXY_DLL \ + -DPROXY_CLSID_IS="{0x79EAC9F1,0xBAF9,0x11CE,{0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B}}" C_SRCS = \ bindctx.c \ @@ -26,10 +28,15 @@ C_SRCS = \ session.c \ umon.c \ umstream.c \ - urlmon_main.c + urlmon_main.c \ + usrmarshal.c RC_SRCS = rsrc.rc +IDL_P_SRCS = urlmon_urlmon.idl + +EXTRA_OBJS = dlldata.o + @MAKE_DLL_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c index bb81ec820b6..2e47b110d1d 100644 --- a/dlls/urlmon/http.c +++ b/dlls/urlmon/http.c @@ -95,7 +95,7 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD requ memset(&url_comp, 0, sizeof(url_comp)); url_comp.dwStructSize = sizeof(url_comp); - url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength = + url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength = url_comp.dwExtraInfoLength = url_comp.dwUserNameLength = url_comp.dwPasswordLength = 1; if (!InternetCrackUrlW(url, 0, 0, &url_comp)) return MK_E_SYNTAX; @@ -124,7 +124,12 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD requ } accept_mimes[num] = 0; - path = heap_strndupW(url_comp.lpszUrlPath, url_comp.dwUrlPathLength); + path = heap_alloc((url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength+1)*sizeof(WCHAR)); + if(url_comp.dwUrlPathLength) + memcpy(path, url_comp.lpszUrlPath, url_comp.dwUrlPathLength*sizeof(WCHAR)); + if(url_comp.dwExtraInfoLength) + memcpy(path+url_comp.dwUrlPathLength, url_comp.lpszExtraInfo, url_comp.dwExtraInfoLength*sizeof(WCHAR)); + path[url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength] = 0; if(This->https) request_flags |= INTERNET_FLAG_SECURE; This->base.request = HttpOpenRequestW(This->base.connection, diff --git a/dlls/urlmon/regsvr.c b/dlls/urlmon/regsvr.c index 9561a23feaf..9e278259e37 100644 --- a/dlls/urlmon/regsvr.c +++ b/dlls/urlmon/regsvr.c @@ -495,6 +495,12 @@ static struct regsvr_coclass const coclass_list[] = { "urlmon.dll", "Both" }, + { &CLSID_PSFactoryBuffer, + "URLMoniker ProxyStub Factory", + NULL, + "urlmon.dll", + "Apartment" + }, { NULL } /* list terminator */ }; @@ -573,12 +579,14 @@ HRESULT WINAPI DllRegisterServer(void) TRACE("\n"); - hr = register_coclasses(coclass_list); - if (SUCCEEDED(hr)) + hr = URLMON_DllRegisterServer(); + if(SUCCEEDED(hr)) + hr = register_coclasses(coclass_list); + if(SUCCEEDED(hr)) hr = register_interfaces(interface_list); - if(FAILED(hr)) - return hr; - return register_inf(TRUE); + if(SUCCEEDED(hr)) + hr = register_inf(TRUE); + return hr; } /*********************************************************************** @@ -590,10 +598,12 @@ HRESULT WINAPI DllUnregisterServer(void) TRACE("\n"); - hr = unregister_coclasses(coclass_list); - if (SUCCEEDED(hr)) + hr = URLMON_DllUnregisterServer(); + if(SUCCEEDED(hr)) + hr = unregister_coclasses(coclass_list); + if(SUCCEEDED(hr)) hr = unregister_interfaces(interface_list); - if(FAILED(hr)) - return hr; - return register_inf(FALSE); + if(SUCCEEDED(hr)) + hr = register_inf(FALSE); + return hr; } diff --git a/dlls/urlmon/tests/sec_mgr.c b/dlls/urlmon/tests/sec_mgr.c index 62471cf8de5..06df952814b 100644 --- a/dlls/urlmon/tests/sec_mgr.c +++ b/dlls/urlmon/tests/sec_mgr.c @@ -605,6 +605,31 @@ static void test_GetZoneAttributes(void) ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr); } +static void test_InternetSecurityMarshalling(void) +{ + IInternetSecurityManager *secmgr = NULL; + IUnknown *unk; + IStream *stream; + HRESULT hres; + + hres = CoInternetCreateSecurityManager(NULL, &secmgr, 0); + if(FAILED(hres)) + return; + + hres = IInternetSecurityManager_QueryInterface(secmgr, &IID_IUnknown, (void**)&unk); + ok(hres == S_OK, "QueryInterface returned: %08x\n", hres); + + hres = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hres == S_OK, "CreateStreamOnHGlobal returned: %08x\n", hres); + + hres = CoMarshalInterface(stream, &IID_IInternetSecurityManager, unk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); + ok(hres == S_OK, "CoMarshalInterface returned: %08x\n", hres); + + IStream_Release(stream); + IUnknown_Release(unk); + IInternetSecurityManager_Release(secmgr); +} + START_TEST(sec_mgr) { @@ -617,6 +642,7 @@ START_TEST(sec_mgr) test_GetZoneActionPolicy(); test_GetZoneAt(); test_GetZoneAttributes(); + test_InternetSecurityMarshalling(); OleUninitialize(); } diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c index a420308453d..272884eb2a6 100644 --- a/dlls/urlmon/urlmon_main.c +++ b/dlls/urlmon/urlmon_main.c @@ -348,6 +348,7 @@ static void init_session(BOOL init) HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { unsigned int i; + HRESULT hr; TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); @@ -357,6 +358,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return IClassFactory_QueryInterface(object_creation[i].cf, riid, ppv); } + hr = URLMON_DllGetClassObject(rclsid, riid, ppv); + if(SUCCEEDED(hr)) + return hr; + FIXME("%s: no class found.\n", debugstr_guid(rclsid)); return CLASS_E_CLASSNOTAVAILABLE; } diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 21b93430a60..8db786b7d80 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -48,6 +48,12 @@ extern HRESULT GopherProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); extern HRESULT MimeFilter_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); +extern HRESULT WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN; +extern HRESULT WINAPI URLMON_DllRegisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI URLMON_DllUnregisterServer(void) DECLSPEC_HIDDEN; + +extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN; + /********************************************************************** * Dll lifetime tracking declaration for urlmon.dll */ diff --git a/include/ks.h b/dlls/urlmon/urlmon_urlmon.idl similarity index 86% copy from include/ks.h copy to dlls/urlmon/urlmon_urlmon.idl index e570fafcbe0..71a0719d7d9 100644 --- a/include/ks.h +++ b/dlls/urlmon/urlmon_urlmon.idl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Robert Reif + * Copyright 2009 Piotr 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 @@ -16,9 +16,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef _KS_ -#define _KS_ - -/* FIXME dummy placeholder for now */ - -#endif /* _KS_ */ +#include "urlmon.idl" diff --git a/dlls/urlmon/usrmarshal.c b/dlls/urlmon/usrmarshal.c new file mode 100644 index 00000000000..b94556362be --- /dev/null +++ b/dlls/urlmon/usrmarshal.c @@ -0,0 +1,162 @@ +/* + * Copyright 2009 Piotr 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); + +HRESULT CALLBACK IWinInetHttpInfo_QueryInfo_Proxy(IWinInetHttpInfo* This, + DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags, + DWORD *pdwReserved) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IWinInetHttpInfo_QueryInfo_Stub(IWinInetHttpInfo* This, + DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf, DWORD *pdwFlags, + DWORD *pdwReserved) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IWinInetInfo_QueryOption_Proxy(IWinInetInfo* This, + DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IWinInetInfo_QueryOption_Stub(IWinInetInfo* This, + DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IBindHost_MonikerBindToStorage_Proxy(IBindHost* This, + IMoniker *pMk, IBindCtx *pBC, IBindStatusCallback *pBSC, + REFIID riid, void **ppvObj) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IBindHost_MonikerBindToStorage_Stub(IBindHost* This, + IMoniker *pMk, IBindCtx *pBC, IBindStatusCallback *pBSC, + REFIID riid, IUnknown **ppvObj) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IBindHost_MonikerBindToObject_Proxy(IBindHost* This, + IMoniker *pMk, IBindCtx *pBC, IBindStatusCallback *pBSC, + REFIID riid, void **ppvObj) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IBindHost_MonikerBindToObject_Stub(IBindHost* This, + IMoniker *pMk, IBindCtx *pBC, IBindStatusCallback *pBSC, + REFIID riid, IUnknown **ppvObj) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IBindStatusCallbackEx_GetBindInfoEx_Proxy( + IBindStatusCallbackEx* This, DWORD *grfBINDF, BINDINFO *pbindinfo, + DWORD *grfBINDF2, DWORD *pdwReserved) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IBindStatusCallbackEx_GetBindInfoEx_Stub( + IBindStatusCallbackEx* This, DWORD *grfBINDF, RemBINDINFO *pbindinfo, + RemSTGMEDIUM *pstgmed, DWORD *grfBINDF2, DWORD *pdwReserved) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IBindStatusCallback_GetBindInfo_Proxy( + IBindStatusCallback* This, DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IBindStatusCallback_GetBindInfo_Stub( + IBindStatusCallback* This, DWORD *grfBINDF, + RemBINDINFO *pbindinfo, RemSTGMEDIUM *pstgmed) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IBindStatusCallback_OnDataAvailable_Proxy( + IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize, + FORMATETC *pformatetc, STGMEDIUM *pstgmed) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IBindStatusCallback_OnDataAvailable_Stub( + IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize, + RemFORMATETC *pformatetc, RemSTGMEDIUM *pstgmed) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT CALLBACK IBinding_GetBindResult_Proxy(IBinding* This, + CLSID *pclsidProtocol, DWORD *pdwResult, + LPOLESTR *pszResult, DWORD *pdwReserved) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT __RPC_STUB IBinding_GetBindResult_Stub(IBinding* This, + CLSID *pclsidProtocol, DWORD *pdwResult, + LPOLESTR *pszResult, DWORD dwReserved) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE IWindowForBindingUI_GetWindow_Proxy( + IWindowForBindingUI* This, REFGUID rguidReason, HWND *phwnd) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +void __RPC_STUB IWindowForBindingUI_GetWindow_Stub(IRpcStubBuffer* This, + IRpcChannelBuffer* pRpcChannelBuffer, PRPC_MESSAGE pRpcMessage, + DWORD* pdwStubPhase) +{ + FIXME("stub\n"); +} diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c index 7c1228beb0a..900335406e7 100644 --- a/dlls/userenv/tests/userenv.c +++ b/dlls/userenv/tests/userenv.c @@ -145,6 +145,7 @@ static void test_create_env(void) todo_wine expect_env(TRUE, r, common_vars[i].name); else expect_env(TRUE, r, common_vars[i].name); + if (r) HeapFree(GetProcessHeap(), 0, st); } } @@ -164,6 +165,7 @@ static void test_create_env(void) todo_wine expect_env(TRUE, r, common_post_nt4_vars[i].name); else expect_env(TRUE, r, common_post_nt4_vars[i].name); + if (r) HeapFree(GetProcessHeap(), 0, st); } } } @@ -178,17 +180,23 @@ static void test_create_env(void) todo_wine expect_env(TRUE, r, htok_vars[i].name); else expect_env(TRUE, r, htok_vars[i].name); + if (r) HeapFree(GetProcessHeap(), 0, st); } } r = get_env(env[0], "WINE_XYZZY", &st); expect(FALSE, r); + r = get_env(env[1], "WINE_XYZZY", &st); expect(FALSE, r); + r = get_env(env[2], "WINE_XYZZY", &st); expect(TRUE, r); + if (r) HeapFree(GetProcessHeap(), 0, st); + r = get_env(env[3], "WINE_XYZZY", &st); expect(TRUE, r); + if (r) HeapFree(GetProcessHeap(), 0, st); } START_TEST(userenv) diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index aefe6cc65a2..523bd4f9aab 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -923,7 +923,9 @@ HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) TRACE("(%p)\n", pssa); if (!pssa || !(analysis = *pssa)) return E_INVALIDARG; + invalid = analysis->invalid; + ScriptFreeCache((SCRIPT_CACHE *)&analysis->sc); for (i = 0; i < analysis->numItems; i++) { diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 9e220254db3..17900f8352b 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c @@ -56,7 +56,7 @@ HRESULT WINAPI EnableThemeDialogTexture(HWND hwnd, DWORD dwFlags) TRACE("(%p,0x%08x\n", hwnd, dwFlags); res = SetPropW (hwnd, (LPCWSTR)MAKEINTATOM(atDialogThemeEnabled), - (HANDLE)(dwFlags|0x80000000)); + UlongToHandle(dwFlags|0x80000000)); /* 0x80000000 serves as a "flags set" flag */ if (!res) return HRESULT_FROM_WIN32(GetLastError()); @@ -74,8 +74,7 @@ BOOL WINAPI IsThemeDialogTextureEnabled(HWND hwnd) DWORD dwDialogTextureFlags; TRACE("(%p)\n", hwnd); - dwDialogTextureFlags = (DWORD)GetPropW (hwnd, - (LPCWSTR)MAKEINTATOM(atDialogThemeEnabled)); + dwDialogTextureFlags = HandleToUlong( GetPropW( hwnd, (LPCWSTR)MAKEINTATOM(atDialogThemeEnabled) )); if (dwDialogTextureFlags == 0) /* Means EnableThemeDialogTexture wasn't called for this dialog */ return TRUE; diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c index 28395393729..b84e978dba8 100644 --- a/dlls/uxtheme/system.c +++ b/dlls/uxtheme/system.c @@ -393,8 +393,7 @@ static void UXTHEME_RestoreSystemMetrics(void) if (RegQueryValueExW (hKey, bsp->keyName, 0, &type, (LPBYTE)&value, &count) == ERROR_SUCCESS) { - SystemParametersInfoW (bsp->spiSet, 0, (LPVOID)value, - SPIF_UPDATEINIFILE); + SystemParametersInfoW (bsp->spiSet, 0, UlongToPtr(value), SPIF_UPDATEINIFILE); } bsp++; @@ -445,9 +444,7 @@ static void UXTHEME_SaveSystemMetrics(void) DWORD value; SystemParametersInfoW (bsp->spiGet, 0, &value, 0); - SystemParametersInfoW (bsp->spiSet, 0, (LPVOID)value, - SPIF_UPDATEINIFILE); - + SystemParametersInfoW (bsp->spiSet, 0, UlongToPtr(value), SPIF_UPDATEINIFILE); bsp++; } diff --git a/dlls/windowscodecs/tests/bmpformat.c b/dlls/windowscodecs/tests/bmpformat.c index 1f114a23285..f817df5178f 100644 --- a/dlls/windowscodecs/tests/bmpformat.c +++ b/dlls/windowscodecs/tests/bmpformat.c @@ -225,6 +225,8 @@ static void test_decode_24bpp(void) /* cannot querycapability twice */ hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + + IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); @@ -373,6 +375,7 @@ static void test_decode_1bpp(void) ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), "unexpected capabilities: %x\n", capability); + IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); @@ -531,6 +534,7 @@ static void test_decode_4bpp(void) ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), "unexpected capabilities: %x\n", capability); + IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); @@ -710,6 +714,7 @@ static void test_decode_rle8(void) ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), "unexpected capabilities: %x\n", capability); + IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); @@ -876,6 +881,7 @@ static void test_decode_rle4(void) ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), "unexpected capabilities: %x\n", capability); + IWICBitmapDecoder_Release(decoder2); } IStream_Release(bmpstream); @@ -1034,6 +1040,71 @@ static void test_createfromstream(void) IWICImagingFactory_Release(factory); } +/* 1x1 pixel gif, missing trailer */ +static unsigned char gifimage_notrailer[] = { +0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff, +0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44, +0x01,0x00 +}; + +static void test_gif_notrailer(void) +{ + IWICBitmapDecoder *decoder; + IWICImagingFactory *factory; + HRESULT hr; + IWICStream *gifstream; + IWICBitmapFrameDecode *framedecode; + UINT framecount; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void**)&factory); + ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + if (FAILED(hr)) return; + + hr = IWICImagingFactory_CreateStream(factory, &gifstream); + ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICStream_InitializeFromMemory(gifstream, gifimage_notrailer, + sizeof(gifimage_notrailer)); + ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr); + + if (SUCCEEDED(hr)) + { + hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void**)&decoder); + ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + } + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)gifstream, + WICDecodeMetadataCacheOnDemand); + ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) IWICBitmapFrameDecode_Release(framedecode); + } + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_GetFrameCount(decoder, &framecount); + ok(hr == S_OK, "GetFrameCount failed, hr=%x\n", hr); + ok(framecount == 1, "framecount=%u\n", framecount); + } + + IWICBitmapDecoder_Release(decoder); + } + + IWICStream_Release(gifstream); + } + + IWICImagingFactory_Release(factory); +} + START_TEST(bmpformat) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -1045,6 +1116,7 @@ START_TEST(bmpformat) test_decode_rle4(); test_componentinfo(); test_createfromstream(); + test_gif_notrailer(); CoUninitialize(); } diff --git a/dlls/windowscodecs/ungif.c b/dlls/windowscodecs/ungif.c index c24f387df67..cfc7613cd4d 100644 --- a/dlls/windowscodecs/ungif.c +++ b/dlls/windowscodecs/ungif.c @@ -320,7 +320,10 @@ DGifGetRecordType(GifFileType * GifFile, GifByteType Buf; if (READ(GifFile, &Buf, 1) != 1) { - return GIF_ERROR; + /* Wine-specific behavior: Native accepts broken GIF files that have no + * terminator, so we match this by treating EOF as a terminator. */ + *Type = TERMINATE_RECORD_TYPE; + return GIF_OK; } switch (Buf) { diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 9129758034c..b1af53a093b 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -100,9 +100,9 @@ struct control_frame BOOL outer_loop; union { - unsigned int loop_no; - unsigned int ifc_no; - }; + unsigned int loop; + unsigned int ifc; + } no; struct wined3d_shader_loop_control loop_control; BOOL had_else; }; @@ -156,13 +156,13 @@ struct arb_vs_compile_args char clipplane_mask; } boolclip; DWORD boolclip_compare; - }; + } clip; DWORD ps_signature; union { - unsigned char vertex_samplers[4]; - DWORD vertex_samplers_compare; - }; + unsigned char samplers[4]; + DWORD samplers_compare; + } vertex; unsigned char loop_ctrl[MAX_CONST_I][3]; }; @@ -537,7 +537,7 @@ static inline void shader_arb_vs_local_constants(IWineD3DDeviceImpl* deviceImpl) /* GL locking is done by the caller (state handler) */ static void shader_arb_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; IWineD3DStateBlockImpl* stateBlock = device->stateBlock; const struct wined3d_gl_info *gl_info = context->gl_info; @@ -567,7 +567,7 @@ static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice != This) return; + if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return; memset(context->vshader_const_dirty + start, 1, sizeof(*context->vshader_const_dirty) * count); This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count); @@ -580,7 +580,7 @@ static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice != This) return; + if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return; memset(context->pshader_const_dirty + start, 1, sizeof(*context->pshader_const_dirty) * count); This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count); @@ -655,7 +655,7 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s } else { - unsigned int mask = ctx->cur_vs_args->boolclip.clipplane_mask; + unsigned int mask = ctx->cur_vs_args->clip.boolclip.clipplane_mask; clip_limit = min(count_bits(mask), 4); } *num_clipplanes = min(clip_limit, max_constantsF - highest_constf - 1); @@ -1271,7 +1271,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD /* Fragment samplers always have indentity mapping */ if(sampler_idx >= MAX_FRAGMENT_SAMPLERS) { - sampler_idx = priv->cur_vs_args->vertex_samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS]; + sampler_idx = priv->cur_vs_args->vertex.samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS]; } if (flags & TEX_DERIV) @@ -2620,8 +2620,8 @@ static void shader_hw_loop(const struct wined3d_shader_instruction *ins) if(priv->loop_depth > 1) shader_addline(buffer, "PUSHA aL;\n"); /* The constant loader makes sure to load -1 into iX.w */ shader_addline(buffer, "ARLC aL, %s.xywz;\n", src_name); - shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->loop_no); - shader_addline(buffer, "loop_%u_start:\n", control_frame->loop_no); + shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->no.loop); + shader_addline(buffer, "loop_%u_start:\n", control_frame->no.loop); } else { @@ -2647,8 +2647,8 @@ static void shader_hw_rep(const struct wined3d_shader_instruction *ins) if(priv->loop_depth > 1) shader_addline(buffer, "PUSHA aL;\n"); shader_addline(buffer, "ARLC aL, %s.xywz;\n", src_name); - shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->loop_no); - shader_addline(buffer, "loop_%u_start:\n", control_frame->loop_no); + shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->no.loop); + shader_addline(buffer, "loop_%u_start:\n", control_frame->no.loop); } else { @@ -2668,8 +2668,8 @@ static void shader_hw_endloop(const struct wined3d_shader_instruction *ins) struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry); shader_addline(buffer, "ARAC aL.xy, aL;\n"); - shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->loop_no); - shader_addline(buffer, "loop_%u_end:\n", control_frame->loop_no); + shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->no.loop); + shader_addline(buffer, "loop_%u_end:\n", control_frame->no.loop); if(priv->loop_depth > 1) shader_addline(buffer, "POPA aL;\n"); } @@ -2691,8 +2691,8 @@ static void shader_hw_endrep(const struct wined3d_shader_instruction *ins) struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry); shader_addline(buffer, "ARAC aL.xy, aL;\n"); - shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->loop_no); - shader_addline(buffer, "loop_%u_end:\n", control_frame->loop_no); + shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->no.loop); + shader_addline(buffer, "loop_%u_end:\n", control_frame->no.loop); if(priv->loop_depth > 1) shader_addline(buffer, "POPA aL;\n"); } @@ -2722,7 +2722,7 @@ static void shader_hw_break(const struct wined3d_shader_instruction *ins) if(vshader) { - shader_addline(buffer, "BRA loop_%u_end;\n", control_frame->loop_no); + shader_addline(buffer, "BRA loop_%u_end;\n", control_frame->no.loop); } else { @@ -2780,7 +2780,7 @@ static void shader_hw_breakc(const struct wined3d_shader_instruction *ins) * away the subtraction result */ shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1); - shader_addline(buffer, "BRA loop_%u_end (%s.x);\n", control_frame->loop_no, comp); + shader_addline(buffer, "BRA loop_%u_end (%s.x);\n", control_frame->no.loop, comp); } else { @@ -2808,7 +2808,7 @@ static void shader_hw_ifc(const struct wined3d_shader_instruction *ins) /* Invert the flag. We jump to the else label if the condition is NOT true */ comp = get_compare(invert_compare(ins->flags)); shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1); - shader_addline(buffer, "BRA ifc_%u_else (%s.x);\n", control_frame->ifc_no, comp); + shader_addline(buffer, "BRA ifc_%u_else (%s.x);\n", control_frame->no.ifc, comp); } else { @@ -2828,8 +2828,8 @@ static void shader_hw_else(const struct wined3d_shader_instruction *ins) if(vshader) { - shader_addline(buffer, "BRA ifc_%u_endif;\n", control_frame->ifc_no); - shader_addline(buffer, "ifc_%u_else:\n", control_frame->ifc_no); + shader_addline(buffer, "BRA ifc_%u_endif;\n", control_frame->no.ifc); + shader_addline(buffer, "ifc_%u_else:\n", control_frame->no.ifc); control_frame->had_else = TRUE; } else @@ -2850,12 +2850,12 @@ static void shader_hw_endif(const struct wined3d_shader_instruction *ins) { if(control_frame->had_else) { - shader_addline(buffer, "ifc_%u_endif:\n", control_frame->ifc_no); + shader_addline(buffer, "ifc_%u_endif:\n", control_frame->no.ifc); } else { shader_addline(buffer, "#No else branch. else is endif\n"); - shader_addline(buffer, "ifc_%u_else:\n", control_frame->ifc_no); + shader_addline(buffer, "ifc_%u_else:\n", control_frame->no.ifc); } } else @@ -2953,14 +2953,14 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh } } } - else if(args->boolclip.clip_texcoord) + else if(args->clip.boolclip.clip_texcoord) { unsigned int cur_clip = 0; char component[4] = {'x', 'y', 'z', 'w'}; for (i = 0; i < gl_info->limits.clipplanes; ++i) { - if(args->boolclip.clipplane_mask & (1 << i)) + if(args->clip.boolclip.clipplane_mask & (1 << i)) { shader_addline(buffer, "DP4 TA.%c, TMP_OUT, state.clip[%u].plane;\n", component[cur_clip++], i); @@ -2982,7 +2982,7 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh break; } shader_addline(buffer, "MOV result.texcoord[%u], TA;\n", - args->boolclip.clip_texcoord - 1); + args->clip.boolclip.clip_texcoord - 1); } /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c @@ -4084,9 +4084,9 @@ static inline BOOL vs_args_equal(const struct arb_vs_compile_args *stored, const if((stored->super.swizzle_map & use_map) != new->super.swizzle_map) return FALSE; if(stored->super.clip_enabled != new->super.clip_enabled) return FALSE; if(stored->super.fog_src != new->super.fog_src) return FALSE; - if(stored->boolclip_compare != new->boolclip_compare) return FALSE; + if(stored->clip.boolclip_compare != new->clip.boolclip_compare) return FALSE; if(stored->ps_signature != new->ps_signature) return FALSE; - if(stored->vertex_samplers_compare != new->vertex_samplers_compare) return FALSE; + if(stored->vertex.samplers_compare != new->vertex.samplers_compare) return FALSE; if(skip_int) return TRUE; return memcmp(stored->loop_ctrl, new->loop_ctrl, sizeof(stored->loop_ctrl)) == 0; @@ -4222,46 +4222,46 @@ static inline void find_arb_vs_compile_args(IWineD3DVertexShaderImpl *shader, IW const struct wined3d_gl_info *gl_info = &dev->adapter->gl_info; find_vs_compile_args(shader, stateblock, &args->super); - args->boolclip_compare = 0; + args->clip.boolclip_compare = 0; if(use_ps(stateblock)) { IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) stateblock->pixelShader; struct arb_pshader_private *shader_priv = ps->baseShader.backend_data; args->ps_signature = shader_priv->input_signature_idx; - args->boolclip.clip_texcoord = shader_priv->clipplane_emulation + 1; + args->clip.boolclip.clip_texcoord = shader_priv->clipplane_emulation + 1; } else { args->ps_signature = ~0; if(!dev->vs_clipping) { - args->boolclip.clip_texcoord = ffp_clip_emul(stateblock) ? gl_info->limits.texture_stages : 0; + args->clip.boolclip.clip_texcoord = ffp_clip_emul(stateblock) ? gl_info->limits.texture_stages : 0; } /* Otherwise: Setting boolclip_compare set clip_texcoord to 0 */ } - if(args->boolclip.clip_texcoord) + if(args->clip.boolclip.clip_texcoord) { if(stateblock->renderState[WINED3DRS_CLIPPING]) { - args->boolclip.clipplane_mask = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]; + args->clip.boolclip.clipplane_mask = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]; } /* clipplane_mask was set to 0 by setting boolclip_compare to 0 */ } /* This forces all local boolean constants to 1 to make them stateblock independent */ - args->boolclip.bools = shader->baseShader.reg_maps.local_bool_consts; + args->clip.boolclip.bools = shader->baseShader.reg_maps.local_bool_consts; /* TODO: Figure out if it would be better to store bool constants as bitmasks in the stateblock */ for(i = 0; i < MAX_CONST_B; i++) { - if(stateblock->vertexShaderConstantB[i]) args->boolclip.bools |= ( 1 << i); + if(stateblock->vertexShaderConstantB[i]) args->clip.boolclip.bools |= ( 1 << i); } - args->vertex_samplers[0] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 0]; - args->vertex_samplers[1] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 1]; - args->vertex_samplers[2] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 2]; - args->vertex_samplers[3] = 0; + args->vertex.samplers[0] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 0]; + args->vertex.samplers[1] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 1]; + args->vertex.samplers[2] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 2]; + args->vertex.samplers[3] = 0; /* Skip if unused or local */ int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts; @@ -4292,7 +4292,7 @@ static inline void find_arb_vs_compile_args(IWineD3DVertexShaderImpl *shader, IW /* GL locking is done by the caller */ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) { - IWineD3DDeviceImpl *This = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *This = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; struct shader_arb_priv *priv = This->shader_priv; const struct wined3d_gl_info *gl_info = context->gl_info; int i; @@ -4772,7 +4772,7 @@ static inline BOOL get_bool_const(const struct wined3d_shader_instruction *ins, } else { - if(vshader) bools = priv->cur_vs_args->boolclip.bools; + if(vshader) bools = priv->cur_vs_args->clip.boolclip.bools; else bools = priv->cur_ps_args->bools; return bools & flag; } @@ -4933,7 +4933,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio if(priv->target_version >= NV2) { - control_frame->loop_no = priv->num_loops++; + control_frame->no.loop = priv->num_loops++; priv->loop_depth++; } else @@ -5062,7 +5062,7 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio /* IF(bool) and if_cond(a, b) use the same ELSE and ENDIF tokens */ control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame)); control_frame->type = IFC; - control_frame->ifc_no = priv->num_ifcs++; + control_frame->no.ifc = priv->num_ifcs++; list_add_head(&priv->control_frames, &control_frame->entry); } else if(ins->handler_idx == WINED3DSIH_ELSE) @@ -5263,11 +5263,11 @@ static void arbfp_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info } #undef GLINFO_LOCATION -#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION stateblock->device->adapter->gl_info static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + IWineD3DDeviceImpl *device = stateblock->device; float col[4]; - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite * application provided constants @@ -5275,7 +5275,6 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc if(device->shader_backend == &arb_program_shader_backend) { if (use_ps(stateblock)) return; - device = stateblock->wineD3DDevice; context->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1; device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1); } @@ -5288,8 +5287,8 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + IWineD3DDeviceImpl *device = stateblock->device; float col[4]; - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite * application provided constants @@ -5297,7 +5296,6 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb if(device->shader_backend == &arb_program_shader_backend) { if (use_ps(stateblock)) return; - device = stateblock->wineD3DDevice; context->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1; device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1); } @@ -5317,7 +5315,7 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; float mat[2][2]; if (use_ps(stateblock)) @@ -5354,7 +5352,7 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; float param[4]; if (use_ps(stateblock)) @@ -5875,7 +5873,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(stateblock); BOOL use_vshader = use_vs(stateblock); diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 014bf1d6fc0..becd4475d0a 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -798,10 +798,10 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con } #undef GLINFO_LOCATION -#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION stateblock->device->adapter->gl_info static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *This = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *This = stateblock->device; const struct atifs_ffp_desc *desc; struct ffp_frag_settings settings; struct atifs_private_data *priv = This->fragment_priv; @@ -889,7 +889,7 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; BOOL use_vshader = use_vs(stateblock); context->last_was_pshader = use_ps(stateblock); diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c index da0bd7e8c78..f232bf393bc 100644 --- a/dlls/wined3d/basetexture.c +++ b/dlls/wined3d/basetexture.c @@ -81,7 +81,7 @@ static void gltexture_delete(struct gl_texture *tex) void basetexture_unload(IWineD3DBaseTexture *iface) { IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context = NULL; if (This->baseTexture.texture_rgb.name || This->baseTexture.texture_srgb.name) @@ -124,7 +124,7 @@ DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew) This->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U; This->baseTexture.texture_srgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U; if(This->baseTexture.bindCount) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(This->baseTexture.sampler)); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_SAMPLER(This->baseTexture.sampler)); } } @@ -152,7 +152,7 @@ DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface) HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; UINT textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface); if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) { @@ -477,7 +477,7 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, if (gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] != aniso) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 24b58a5a2bd..f6e89ddff4e 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -29,7 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION This->resource.device->adapter->gl_info #define VB_MAXDECLCHANGES 100 /* After that number we stop converting */ #define VB_RESETDECLCHANGE 1000 /* Reset the changecount after that number of draws */ @@ -68,7 +68,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); error = glGetError(); @@ -148,7 +148,7 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, DWORD attrib_size; BOOL ret = FALSE; unsigned int i; - DWORD offset = This->resource.wineD3DDevice->stateBlock->streamOffset[attrib->stream_idx]; + DWORD offset = This->resource.device->stateBlock->streamOffset[attrib->stream_idx]; DWORD_PTR data; /* Check for some valid situations which cause us pain. One is if the buffer is used for @@ -203,7 +203,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win DWORD *stride_this_run, BOOL *float16_used) { const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx]; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; BOOL ret = FALSE; WINED3DFORMAT format; @@ -311,7 +311,7 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This, static BOOL buffer_find_decl(struct wined3d_buffer *This) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_stream_info *si = &device->strided_streams; UINT stride_this_run = 0; @@ -472,7 +472,7 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This) if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } /* Rescue the data before resizing the buffer object if we do not have our backup copy */ @@ -607,7 +607,7 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) if (This->buffer_object) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); @@ -657,11 +657,6 @@ static HRESULT STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface, IUnknow /* 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) { @@ -692,7 +687,7 @@ static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; UINT start = 0, end = 0, vertices; struct wined3d_context *context; BOOL decl_changed = FALSE; @@ -800,7 +795,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } if (!This->conversion_map) @@ -962,12 +957,12 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, { if(count == 1) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); @@ -1016,12 +1011,12 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); @@ -1064,7 +1059,6 @@ static const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = /* IWineD3DBase methods */ buffer_GetParent, /* IWineD3DResource methods */ - buffer_GetDevice, buffer_SetPrivateData, buffer_GetPrivateData, buffer_FreePrivateData, diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 5bd06bee628..0debd2e78d7 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -117,7 +117,7 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo) static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOOL force_preload) { const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; - IWineD3DDeviceImpl *device = surface_impl->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = surface_impl->resource.device; IWineD3DBaseTextureImpl *texture_impl; BOOL update_minfilter = FALSE; BOOL update_magfilter = FALSE; @@ -317,7 +317,7 @@ static void context_check_fbo_status(struct wined3d_context *context) static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry; @@ -334,7 +334,7 @@ static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *contex /* GL locking is done by the caller */ static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); @@ -363,7 +363,7 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb /* GL locking is done by the caller */ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry; @@ -399,7 +399,7 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) /* GL locking is done by the caller */ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; @@ -1869,7 +1869,7 @@ static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWin { if (current_context && current_context->current_rt - && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.wineD3DDevice == This) + && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This) { target = current_context->current_rt; } @@ -1893,7 +1893,7 @@ static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWin context = findThreadContextForSwapChain(swapchain, tid); old_render_offscreen = context->render_offscreen; - context->render_offscreen = FALSE; + context->render_offscreen = ((IWineD3DSwapChainImpl *)swapchain)->render_to_fbo; /* The context != This->activeContext will catch a NOP context change. This can occur * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen * rendering. No context change is needed in that case @@ -1952,7 +1952,7 @@ retry: { /* Stay with the currently active context. */ if (current_context - && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.wineD3DDevice == This) + && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This) { context = current_context; } @@ -2057,7 +2057,7 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit IWineD3DSwapChain *swapchain; IWineD3DDeviceImpl *device; - device = ((IWineD3DSurfaceImpl *)rt)->resource.wineD3DDevice; + device = ((IWineD3DSurfaceImpl *)rt)->resource.device; if (SUCCEEDED(IWineD3DSurface_GetContainer(rt, &IID_IWineD3DSwapChain, (void **)&swapchain))) { IWineD3DSwapChain_Release((IUnknown *)swapchain); @@ -2097,6 +2097,14 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit } } +/* GL locking is done by the caller. */ +void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) +{ + glDrawBuffer(buffer); + checkGLcall("glDrawBuffer()"); + context->draw_buffer_dirty = TRUE; +} + /***************************************************************************** * context_acquire * diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c index f22845bb47c..9d173d61348 100644 --- a/dlls/wined3d/cubetexture.c +++ b/dlls/wined3d/cubetexture.c @@ -31,7 +31,7 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 { /* Override the IWineD3DResource Preload method. */ IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context = NULL; unsigned int i, j; BOOL srgb_mode; @@ -183,10 +183,6 @@ static ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface) /* **************************************************** IWineD3DCubeTexture IWineD3DResource parts follow **************************************************** */ -static HRESULT WINAPI IWineD3DCubeTextureImpl_GetDevice(IWineD3DCubeTexture *iface, IWineD3DDevice** ppDevice) { - return resource_get_device((IWineD3DResource *)iface, ppDevice); -} - static HRESULT WINAPI IWineD3DCubeTextureImpl_SetPrivateData(IWineD3DCubeTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags); } @@ -404,7 +400,6 @@ static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = IWineD3DCubeTextureImpl_Release, /* IWineD3DResource */ IWineD3DCubeTextureImpl_GetParent, - IWineD3DCubeTextureImpl_GetDevice, IWineD3DCubeTextureImpl_SetPrivateData, IWineD3DCubeTextureImpl_GetPrivateData, IWineD3DCubeTextureImpl_FreePrivateData, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index ee0faa72c57..1c141ba3f2f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -427,8 +427,8 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { if (This->hardwareCursor) DestroyCursor(This->hardwareCursor); This->haveHardwareCursor = FALSE; - IWineD3D_Release(This->wineD3D); - This->wineD3D = NULL; + IWineD3D_Release(This->wined3d); + This->wined3d = NULL; HeapFree(GetProcessHeap(), 0, This); TRACE("Freed device %p\n", This); This = NULL; @@ -883,7 +883,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE object->lpVtbl = vtable; object->type = Type; object->state = QUERY_CREATED; - object->wineD3DDevice = This; + object->device = This; object->parent = parent; object->ref = 1; @@ -921,408 +921,36 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE return WINED3D_OK; } -/***************************************************************************** - * IWineD3DDeviceImpl_SetupFullscreenWindow - * - * Helper function that modifies a HWND's Style and ExStyle for proper - * fullscreen use. - * - * Params: - * iface: Pointer to the IWineD3DDevice interface - * window: Window to setup - * - *****************************************************************************/ -static LONG fullscreen_style(LONG orig_style) { - LONG style = orig_style; - style &= ~WS_CAPTION; - style &= ~WS_THICKFRAME; - - /* Make sure the window is managed, otherwise we won't get keyboard input */ - style |= WS_POPUP | WS_SYSMENU; - - return style; -} - -static LONG fullscreen_exStyle(LONG orig_exStyle) { - LONG exStyle = orig_exStyle; - - /* Filter out window decorations */ - exStyle &= ~WS_EX_WINDOWEDGE; - exStyle &= ~WS_EX_CLIENTEDGE; - - return exStyle; -} - -static void IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDevice *iface, HWND window, UINT w, UINT h) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - - LONG style, exStyle; - /* Don't do anything if an original style is stored. - * That shouldn't happen - */ - TRACE("(%p): Setting up window %p for exclusive mode\n", This, window); - if (This->style || This->exStyle) { - ERR("(%p): Want to change the window parameters of HWND %p, but " - "another style is stored for restoration afterwards\n", This, window); - } - - /* Get the parameters and save them */ - style = GetWindowLongW(window, GWL_STYLE); - exStyle = GetWindowLongW(window, GWL_EXSTYLE); - This->style = style; - This->exStyle = exStyle; - - style = fullscreen_style(style); - exStyle = fullscreen_exStyle(exStyle); - - TRACE("Old style was %08x,%08x, setting to %08x,%08x\n", - This->style, This->exStyle, style, exStyle); - - SetWindowLongW(window, GWL_STYLE, style); - SetWindowLongW(window, GWL_EXSTYLE, exStyle); - - /* Inform the window about the update. */ - SetWindowPos(window, HWND_TOP, 0, 0, - w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW); -} - -/***************************************************************************** - * IWineD3DDeviceImpl_RestoreWindow - * - * Helper function that restores a windows' properties when taking it out - * of fullscreen mode - * - * Params: - * iface: Pointer to the IWineD3DDevice interface - * window: Window to setup - * - *****************************************************************************/ -static void IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND window) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - LONG style, exStyle; - - /* This could be a DDSCL_NORMAL -> DDSCL_NORMAL - * switch, do nothing - */ - if (!This->style && !This->exStyle) return; - - TRACE("(%p): Restoring window settings of window %p to %08x, %08x\n", - This, window, This->style, This->exStyle); - - style = GetWindowLongW(window, GWL_STYLE); - exStyle = GetWindowLongW(window, GWL_EXSTYLE); - - /* Only restore the style if the application didn't modify it during the fullscreen phase. - * Some applications change it before calling Reset() when switching between windowed and - * fullscreen modes(HL2), some depend on the original style(Eve Online) - */ - if(style == fullscreen_style(This->style) && - exStyle == fullscreen_style(This->exStyle)) { - SetWindowLongW(window, GWL_STYLE, This->style); - SetWindowLongW(window, GWL_EXSTYLE, This->exStyle); - } - - /* Delete the old values */ - This->style = 0; - This->exStyle = 0; - - /* Inform the window about the update */ - SetWindowPos(window, 0 /* InsertAfter, ignored */, - 0, 0, 0, 0, /* Pos, Size, ignored */ - SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); -} - -/* example at http://www.fairyengine.com/articles/dxmultiviews.htm */ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface, - WINED3DPRESENT_PARAMETERS *pPresentationParameters, IWineD3DSwapChain **ppSwapChain, + WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **swapchain, IUnknown *parent, WINED3DSURFTYPE surface_type) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - - HDC hDc; - IWineD3DSwapChainImpl *object; /** NOTE: impl ref allowed since this is a create function **/ - HRESULT hr; - BOOL displaymode_set = FALSE; - WINED3DDISPLAYMODE Mode; - const struct GlPixelFormatDesc *format_desc; - - TRACE("(%p) : Created Additional Swap Chain\n", This); + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DSwapChainImpl *object; + HRESULT hr; - /** FIXME: Test under windows to find out what the life cycle of a swap chain is, - * does a device hold a reference to a swap chain giving them a lifetime of the device - * or does the swap chain notify the device of its destruction. - *******************************/ - - /* Check the params */ - if(pPresentationParameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX) { - ERR("App requested %d back buffers, this is not supported for now\n", pPresentationParameters->BackBufferCount); - return WINED3DERR_INVALIDCALL; - } else if (pPresentationParameters->BackBufferCount > 1) { - FIXME("The app requests more than one back buffer, this can't be supported properly. Please configure the application to use double buffering(=1 back buffer) if possible\n"); - } + TRACE("iface %p, present_parameters %p, swapchain %p, parent %p, surface_type %#x.\n", + iface, present_parameters, swapchain, parent, surface_type); object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); - if(!object) + if (!object) { - ERR("Out of memory\n"); - *ppSwapChain = NULL; - return WINED3DERR_OUTOFVIDEOMEMORY; - } - - switch(surface_type) { - case SURFACE_GDI: - object->lpVtbl = &IWineGDISwapChain_Vtbl; - break; - case SURFACE_OPENGL: - object->lpVtbl = &IWineD3DSwapChain_Vtbl; - break; - case SURFACE_UNKNOWN: - FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain\n"); - HeapFree(GetProcessHeap(), 0, object); - return WINED3DERR_INVALIDCALL; - } - object->wineD3DDevice = This; - object->parent = parent; - object->ref = 1; - - *ppSwapChain = (IWineD3DSwapChain *)object; - - /********************* - * Lookup the window Handle and the relating X window handle - ********************/ - - /* Setup hwnd we are using, plus which display this equates to */ - object->win_handle = pPresentationParameters->hDeviceWindow; - if (!object->win_handle) { - object->win_handle = This->createParms.hFocusWindow; - } - if(!pPresentationParameters->Windowed && object->win_handle) { - IWineD3DDeviceImpl_SetupFullscreenWindow(iface, object->win_handle, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight); - } - - hDc = GetDC(object->win_handle); - TRACE("Using hDc %p\n", hDc); - - if (NULL == hDc) { - WARN("Failed to get a HDc for Window %p\n", object->win_handle); - return WINED3DERR_NOTAVAILABLE; - } - - /* Get info on the current display setup */ - IWineD3D_GetAdapterDisplayMode(This->wineD3D, This->adapter->num, &Mode); - object->orig_width = Mode.Width; - object->orig_height = Mode.Height; - object->orig_fmt = Mode.Format; - format_desc = getFormatDescEntry(Mode.Format, &This->adapter->gl_info); - - if (pPresentationParameters->Windowed && - ((pPresentationParameters->BackBufferWidth == 0) || - (pPresentationParameters->BackBufferHeight == 0) || - (pPresentationParameters->BackBufferFormat == WINED3DFMT_UNKNOWN))) { - - RECT Rect; - GetClientRect(object->win_handle, &Rect); - - if (pPresentationParameters->BackBufferWidth == 0) { - pPresentationParameters->BackBufferWidth = Rect.right; - TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth); - } - if (pPresentationParameters->BackBufferHeight == 0) { - pPresentationParameters->BackBufferHeight = Rect.bottom; - TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight); - } - if (pPresentationParameters->BackBufferFormat == WINED3DFMT_UNKNOWN) { - pPresentationParameters->BackBufferFormat = object->orig_fmt; - TRACE("Updating format to %s\n", debug_d3dformat(object->orig_fmt)); - } - } - - /* Put the correct figures in the presentation parameters */ - TRACE("Copying across presentation parameters\n"); - object->presentParms = *pPresentationParameters; - - TRACE("calling rendertarget CB\n"); - hr = IWineD3DDeviceParent_CreateRenderTarget(This->device_parent, parent, - object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight, - object->presentParms.BackBufferFormat, object->presentParms.MultiSampleType, - object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->frontBuffer); - if (SUCCEEDED(hr)) { - IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object); - ((IWineD3DSurfaceImpl *)object->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; - if(surface_type == SURFACE_OPENGL) { - IWineD3DSurface_ModifyLocation(object->frontBuffer, SFLAG_INDRAWABLE, TRUE); - } - } else { - ERR("Failed to create the front buffer\n"); - goto error; - } - - /********************* - * Windowed / Fullscreen - *******************/ - - /** - * TODO: MSDN says that we are only allowed one fullscreen swapchain per device, - * so we should really check to see if there is a fullscreen swapchain already - * I think Windows and X have different ideas about fullscreen, does a single head count as full screen? - **************************************/ - - if (!pPresentationParameters->Windowed) { - WINED3DDISPLAYMODE mode; - - - /* Change the display settings */ - mode.Width = pPresentationParameters->BackBufferWidth; - mode.Height = pPresentationParameters->BackBufferHeight; - mode.Format = pPresentationParameters->BackBufferFormat; - mode.RefreshRate = pPresentationParameters->FullScreen_RefreshRateInHz; - - IWineD3DDevice_SetDisplayMode(iface, 0, &mode); - displaymode_set = TRUE; - } - - /** - * Create an opengl context for the display visual - * NOTE: the visual is chosen as the window is created and the glcontext cannot - * use different properties after that point in time. FIXME: How to handle when requested format - * doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one - * it chooses is identical to the one already being used! - **********************************/ - /** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/ - - object->context = HeapAlloc(GetProcessHeap(), 0, sizeof(object->context)); - if(!object->context) { - ERR("Failed to create the context array\n"); - hr = E_OUTOFMEMORY; - goto error; + ERR("Failed to allocate swapchain memory.\n"); + return E_OUTOFMEMORY; } - object->num_contexts = 1; - if (surface_type == SURFACE_OPENGL) - { - object->context[0] = context_create(This, (IWineD3DSurfaceImpl *)object->frontBuffer, - object->win_handle, FALSE /* pbuffer */, pPresentationParameters); - if (!object->context[0]) { - ERR("Failed to create a new context\n"); - hr = WINED3DERR_NOTAVAILABLE; - goto error; - } else { - TRACE("Context created (HWND=%p, glContext=%p)\n", - object->win_handle, object->context[0]->glCtx); - } - } - else + hr = swapchain_init(object, surface_type, This, present_parameters, parent); + if (FAILED(hr)) { - object->context[0] = NULL; - } - - /********************* - * Create the back, front and stencil buffers - *******************/ - if(object->presentParms.BackBufferCount > 0) { - UINT i; - - object->backBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(IWineD3DSurface *) * object->presentParms.BackBufferCount); - if(!object->backBuffer) { - ERR("Out of memory\n"); - hr = E_OUTOFMEMORY; - goto error; - } - - for(i = 0; i < object->presentParms.BackBufferCount; i++) { - TRACE("calling rendertarget CB\n"); - hr = IWineD3DDeviceParent_CreateRenderTarget(This->device_parent, parent, - object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight, - object->presentParms.BackBufferFormat, object->presentParms.MultiSampleType, - object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->backBuffer[i]); - if(SUCCEEDED(hr)) { - IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object); - ((IWineD3DSurfaceImpl *)object->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; - } else { - ERR("Cannot create new back buffer\n"); - goto error; - } - if(surface_type == SURFACE_OPENGL) { - ENTER_GL(); - glDrawBuffer(GL_BACK); - checkGLcall("glDrawBuffer(GL_BACK)"); - LEAVE_GL(); - } - } - } else { - object->backBuffer = NULL; - - /* Single buffering - draw to front buffer */ - if(surface_type == SURFACE_OPENGL) { - ENTER_GL(); - glDrawBuffer(GL_FRONT); - checkGLcall("glDrawBuffer(GL_FRONT)"); - LEAVE_GL(); - } - } - - if (object->context[0]) context_release(object->context[0]); - - /* Under directX swapchains share the depth stencil, so only create one depth-stencil */ - if (pPresentationParameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) { - TRACE("Creating depth stencil buffer\n"); - if (This->auto_depth_stencil_buffer == NULL ) { - hr = IWineD3DDeviceParent_CreateDepthStencilSurface(This->device_parent, parent, - object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight, - object->presentParms.AutoDepthStencilFormat, object->presentParms.MultiSampleType, - object->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, - &This->auto_depth_stencil_buffer); - if (SUCCEEDED(hr)) { - IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0); - } else { - ERR("Failed to create the auto depth stencil\n"); - goto error; - } - } + WARN("Failed to initialize swapchain, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; } - IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *) object, &object->orig_gamma); + TRACE("Created swapchain %p.\n", object); + *swapchain = (IWineD3DSwapChain *)object; - TRACE("Created swapchain %p\n", object); - TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer ? object->backBuffer[0] : NULL, pPresentationParameters->EnableAutoDepthStencil); return WINED3D_OK; - -error: - if (displaymode_set) { - DEVMODEW devmode; - RECT clip_rc; - - SetRect(&clip_rc, 0, 0, object->orig_width, object->orig_height); - ClipCursor(NULL); - - /* Change the display settings */ - memset(&devmode, 0, sizeof(devmode)); - devmode.dmSize = sizeof(devmode); - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - devmode.dmBitsPerPel = format_desc->byte_count * 8; - devmode.dmPelsWidth = object->orig_width; - devmode.dmPelsHeight = object->orig_height; - ChangeDisplaySettingsExW(This->adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); - } - - if (object->backBuffer) { - UINT i; - for(i = 0; i < object->presentParms.BackBufferCount; i++) { - if (object->backBuffer[i]) IWineD3DSurface_Release(object->backBuffer[i]); - } - HeapFree(GetProcessHeap(), 0, object->backBuffer); - object->backBuffer = NULL; - } - if(object->context && object->context[0]) - { - context_release(object->context[0]); - context_destroy(This, object->context[0]); - } - if (object->frontBuffer) IWineD3DSurface_Release(object->frontBuffer); - HeapFree(GetProcessHeap(), 0, object); - return hr; } /** NOTE: These are ahead of the other getters and setters to save using a forward declaration **/ @@ -1616,7 +1244,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DW object->ref = 1; object->Flags = Flags; object->parent = Parent; - object->wineD3DDevice = This; + object->device = This; object->palNumEntries = IWineD3DPaletteImpl_Size(Flags); object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion)); @@ -1884,6 +1512,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, switch(wined3d_settings.offscreen_rendering_mode) { case ORM_FBO: + This->offscreenBuffer = GL_COLOR_ATTACHMENT0; + break; + case ORM_PBUFFER: This->offscreenBuffer = GL_BACK; break; @@ -2233,8 +1864,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, U static HRESULT WINAPI IWineD3DDeviceImpl_GetDirect3D(IWineD3DDevice *iface, IWineD3D **ppD3D) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *ppD3D= This->wineD3D; - TRACE("(%p) : wineD3D returning %p\n", This, *ppD3D); + *ppD3D = This->wined3d; + TRACE("Returning %p.\n", *ppD3D); IWineD3D_AddRef(*ppD3D); return WINED3D_OK; } @@ -4401,7 +4032,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetBackBuffer(IWineD3DDevice *iface, UI static HRESULT WINAPI IWineD3DDeviceImpl_GetDeviceCaps(IWineD3DDevice *iface, WINED3DCAPS* pCaps) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; WARN("(%p) : stub, calling idirect3d for now\n", This); - return IWineD3D_GetDeviceCaps(This->wineD3D, This->adapterNo, This->devType, pCaps); + return IWineD3D_GetDeviceCaps(This->wined3d, This->adapter->ordinal, This->devType, pCaps); } static HRESULT WINAPI IWineD3DDeviceImpl_GetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain, WINED3DDISPLAYMODE* pMode) { @@ -4979,7 +4610,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDev This->stateBlock->streamIsUP = TRUE; This->stateBlock->baseVertexIndex = 0; This->up_strided = DrawPrimStrideData; - drawPrimitive(iface, 0 /* numindices */, 0 /* start_idx */, idxSize, pIndexData); + drawPrimitive(iface, vertex_count, 0 /* start_idx */, idxSize, pIndexData); This->up_strided = NULL; return WINED3D_OK; } @@ -5678,18 +5309,17 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, IWineD3DSwapChain *swapchain; swapchain = get_swapchain(surface); - if (swapchain) { - GLenum buffer; - + if (!surface_is_offscreen(surface)) + { TRACE("Surface %p is onscreen\n", surface); context = context_acquire(This, surface, CTXUSAGE_RESOURCELOAD); ENTER_GL(); context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - buffer = surface_get_gl_buffer(surface, swapchain); - glDrawBuffer(buffer); - checkGLcall("glDrawBuffer()"); - } else { + context_set_draw_buffer(context, surface_get_gl_buffer(surface, swapchain)); + } + else + { TRACE("Surface %p is offscreen\n", surface); context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); @@ -5701,7 +5331,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, if (rect) { glEnable(GL_SCISSOR_TEST); - if(!swapchain) { + if(surface_is_offscreen(surface)) { glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1); } else { glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2, @@ -5724,12 +5354,6 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, glClear(GL_COLOR_BUFFER_BIT); checkGLcall("glClear"); - if (swapchain && surface == ((IWineD3DSwapChainImpl *)swapchain)->frontBuffer - && ((IWineD3DSwapChainImpl *)swapchain)->backBuffer) { - glDrawBuffer(GL_BACK); - checkGLcall("glDrawBuffer()"); - } - LEAVE_GL(); context_release(context); } @@ -6102,7 +5726,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED gl_info = context->gl_info; - if (src_swapchain) { + if (!surface_is_offscreen(src_surface)) { GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain); TRACE("Source surface %p is onscreen\n", src_surface); @@ -6140,7 +5764,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED LEAVE_GL(); /* Attach dst surface to dst fbo */ - if (dst_swapchain) { + if (!surface_is_offscreen(dst_surface)) { GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain); TRACE("Destination surface %p is onscreen\n", dst_surface); @@ -6528,9 +6152,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice* return WINED3D_OK; } -static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT_PARAMETERS* pPresentationParameters) +static HRESULT updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT_PARAMETERS* pPresentationParameters) { - IWineD3DDeviceImpl *device = surface->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = surface->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; /* Reallocate proper memory for the front and back buffer and adjust their sizes */ @@ -6581,12 +6205,14 @@ static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT surface->resource.allocatedMemory = NULL; surface->resource.heapMemory = NULL; surface->resource.size = IWineD3DSurface_GetPitch((IWineD3DSurface *) surface) * surface->pow2Width; - /* INDRAWABLE is a sane place for implicit targets after the reset, INSYSMEM is more appropriate for depth stencils. */ - if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) { - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) surface, SFLAG_INSYSMEM, TRUE); - } else { - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) surface, SFLAG_INDRAWABLE, TRUE); + + /* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered + * to a FBO */ + if(!surface_init_sysmem((IWineD3DSurface *) surface)) + { + return E_OUTOFMEMORY; } + return WINED3D_OK; } static HRESULT WINAPI reset_unload_resources(IWineD3DResource *resource, void *data) { @@ -6607,10 +6233,10 @@ static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, const WINED3DPRE if(!pp->BackBufferWidth) return TRUE; if(!pp->BackBufferHeight) return TRUE; - count = IWineD3D_GetAdapterModeCount(This->wineD3D, This->adapter->num, WINED3DFMT_UNKNOWN); + count = IWineD3D_GetAdapterModeCount(This->wined3d, This->adapter->ordinal, WINED3DFMT_UNKNOWN); for(i = 0; i < count; i++) { memset(&m, 0, sizeof(m)); - hr = IWineD3D_EnumAdapterModes(This->wineD3D, This->adapter->num, WINED3DFMT_UNKNOWN, i, &m); + hr = IWineD3D_EnumAdapterModes(This->wined3d, This->adapter->ordinal, WINED3DFMT_UNKNOWN, i, &m); if(FAILED(hr)) { ERR("EnumAdapterModes failed\n"); } @@ -6692,6 +6318,7 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain * } swapchain->context[0] = context_create(This, target, swapchain->win_handle, FALSE, &swapchain->presentParms); swapchain->num_contexts = 1; + swapchain->context[0]->render_offscreen = swapchain->render_to_fbo; create_dummy_textures(This); @@ -6844,12 +6471,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE swapchain->presentParms.BackBufferWidth = pPresentationParameters->BackBufferWidth; swapchain->presentParms.BackBufferHeight = pPresentationParameters->BackBufferHeight; - updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters); + hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters); + if(FAILED(hr)) + { + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); + return hr; + } + for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) { - updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters); + hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters); + if(FAILED(hr)) + { + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); + return hr; + } } if(This->auto_depth_stencil_buffer) { - updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters); + hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters); + if(FAILED(hr)) + { + IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); + return hr; + } } } @@ -6862,9 +6505,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE if(swapchain->win_handle && !pPresentationParameters->Windowed) { if(swapchain->presentParms.Windowed) { /* switch from windowed to fs */ - IWineD3DDeviceImpl_SetupFullscreenWindow(iface, swapchain->win_handle, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight); + swapchain_setup_fullscreen_window(swapchain, pPresentationParameters->BackBufferWidth, + pPresentationParameters->BackBufferHeight); } else { /* Fullscreen -> fullscreen mode change */ MoveWindow(swapchain->win_handle, 0, 0, @@ -6873,7 +6515,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } else if(swapchain->win_handle && !swapchain->presentParms.Windowed) { /* Fullscreen -> windowed switch */ - IWineD3DDeviceImpl_RestoreWindow(iface, swapchain->win_handle); + swapchain_restore_fullscreen_window(swapchain); } swapchain->presentParms.Windowed = pPresentationParameters->Windowed; } else if(!pPresentationParameters->Windowed) { @@ -6884,9 +6526,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE */ This->style = 0; This->exStyle = 0; - IWineD3DDeviceImpl_SetupFullscreenWindow(iface, swapchain->win_handle, - pPresentationParameters->BackBufferWidth, - pPresentationParameters->BackBufferHeight); + swapchain_setup_fullscreen_window(swapchain, pPresentationParameters->BackBufferWidth, + pPresentationParameters->BackBufferHeight); This->style = style; This->exStyle = exStyle; } @@ -6903,6 +6544,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE ERR("Resetting the stateblock failed with error 0x%08x\n", hr); } + if(wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + RECT client_rect; + GetClientRect(swapchain->win_handle, &client_rect); + + if(swapchain->presentParms.BackBufferWidth != client_rect.right || + swapchain->presentParms.BackBufferHeight != client_rect.bottom) + { + TRACE("Rendering to FBO. Backbuffer %ux%u, window %ux%u\n", + swapchain->presentParms.BackBufferWidth, + swapchain->presentParms.BackBufferHeight, + client_rect.right, client_rect.bottom); + swapchain->render_to_fbo = TRUE; + } + else + { + TRACE("Rendering directly to GL_BACK\n"); + swapchain->render_to_fbo = FALSE; + } + } + hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *) swapchain); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); @@ -7257,8 +6919,8 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, device->lpVtbl = &IWineD3DDevice_Vtbl; device->ref = 1; - device->wineD3D = (IWineD3D *)wined3d; - IWineD3D_AddRef(device->wineD3D); + device->wined3d = (IWineD3D *)wined3d; + IWineD3D_AddRef(device->wined3d); device->adapter = wined3d->adapter_count ? adapter : NULL; device->parent = parent; device->device_parent = device_parent; @@ -7273,7 +6935,7 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, if (FAILED(hr)) { ERR("Failed to get the adapter's display mode, hr %#x.\n", hr); - IWineD3D_Release(device->wineD3D); + IWineD3D_Release(device->wined3d); return hr; } device->ddraw_width = mode.Width; @@ -7286,7 +6948,6 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, device->createParms.hFocusWindow = focus_window; device->createParms.BehaviorFlags = flags; - device->adapterNo = adapter_idx; device->devType = device_type; for (i = 0; i < PATCHMAP_SIZE; ++i) list_init(&device->patches[i]); @@ -7311,7 +6972,7 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, if (FAILED(hr)) { ERR("Failed to compile state table, hr %#x.\n", hr); - IWineD3D_Release(device->wineD3D); + IWineD3D_Release(device->wined3d); return hr; } @@ -7341,7 +7002,7 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) { void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.device; /* The drawable size of a pbuffer render target is the current pbuffer size. */ *width = device->pbufferWidth; *height = device->pbufferHeight; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 60db4a4f4f6..a29b90c175c 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2199,6 +2199,8 @@ static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Ad /* TODO: Store modes per adapter and read it from the adapter structure */ if (Adapter == 0) { /* Display */ + const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); + UINT format_bits = format_desc->byte_count * CHAR_BIT; unsigned int i = 0; unsigned int j = 0; DEVMODEW mode; @@ -2209,28 +2211,15 @@ static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Ad while (EnumDisplaySettingsExW(NULL, j, &mode, 0)) { ++j; - switch (Format) + + if (Format == WINED3DFMT_UNKNOWN) + { + /* This is for D3D8, do not enumerate P8 here */ + if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i; + } + else if (mode.dmBitsPerPel == format_bits) { - case WINED3DFMT_UNKNOWN: - /* This is for D3D8, do not enumerate P8 here */ - if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i; - break; - - case WINED3DFMT_B8G8R8X8_UNORM: - if (mode.dmBitsPerPel == 32) ++i; - break; - - case WINED3DFMT_B5G6R5_UNORM: - if (mode.dmBitsPerPel == 16) ++i; - break; - - case WINED3DFMT_P8_UINT: - if (mode.dmBitsPerPel == 8) ++i; - break; - - default: - /* Skip other modes as they do not match the requested format */ - break; + ++i; } } @@ -2257,6 +2246,8 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte /* TODO: Store modes per adapter and read it from the adapter structure */ if (Adapter == 0) { + const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); + UINT format_bits = format_desc->byte_count * CHAR_BIT; DEVMODEW DevModeW; int ModeIdx = 0; UINT i = 0; @@ -2268,27 +2259,16 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte /* If we are filtering to a specific format (D3D9), then need to skip all unrelated modes, but if mode is irrelevant (D3D8), then we can just count through the ones with valid bit depths */ - while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) { - switch (Format) + while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) + { + if (Format == WINED3DFMT_UNKNOWN) + { + /* This is for D3D8, do not enumerate P8 here */ + if (DevModeW.dmBitsPerPel == 32 || DevModeW.dmBitsPerPel == 16) ++i; + } + else if (DevModeW.dmBitsPerPel == format_bits) { - case WINED3DFMT_UNKNOWN: - /* This is D3D8. Do not enumerate P8 here */ - if (DevModeW.dmBitsPerPel == 32 || - DevModeW.dmBitsPerPel == 16) i++; - break; - case WINED3DFMT_B8G8R8X8_UNORM: - if (DevModeW.dmBitsPerPel == 32) i++; - break; - case WINED3DFMT_B5G6R5_UNORM: - if (DevModeW.dmBitsPerPel == 16) i++; - break; - case WINED3DFMT_P8_UINT: - if (DevModeW.dmBitsPerPel == 8) i++; - break; - default: - /* Modes that don't match what we support can get an early-out */ - TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format)); - return WINED3DERR_INVALIDCALL; + ++i; } } @@ -4676,7 +4656,7 @@ BOOL InitAdapters(IWineD3DImpl *This) HDC hdc; TRACE("Initializing default adapter\n"); - adapter->num = 0; + adapter->ordinal = 0; adapter->monitorPoint.x = -1; adapter->monitorPoint.y = -1; @@ -4884,7 +4864,7 @@ BOOL InitAdapters(IWineD3DImpl *This) nogl_adapter: /* Initialize an adapter for ddraw-only memory counting */ memset(This->adapters, 0, sizeof(This->adapters)); - This->adapters[0].num = 0; + This->adapters[0].ordinal = 0; This->adapters[0].opengl = FALSE; This->adapters[0].monitorPoint.x = -1; This->adapters[0].monitorPoint.y = -1; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 11a80b23b7a..fb9004e5023 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -630,7 +630,7 @@ static void shader_glsl_load_np2fixup_constants( static void shader_glsl_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DStateBlockImpl* stateBlock = device->stateBlock; struct shader_glsl_priv *priv = device->shader_priv; @@ -4315,7 +4315,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, /* GL locking is done by the caller */ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = device->shader_priv; GLhandleARB program_id = 0; diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 627bd68293f..82a71dab3b9 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -28,7 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION stateblock->device->adapter->gl_info /* GL locking for state handlers is done by the caller. */ @@ -458,8 +458,8 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; - BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage); + BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage); + DWORD mapped_stage = stateblock->device->texUnitMap[stage]; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Setting color op for stage %d\n", stage); @@ -533,7 +533,7 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } /* Set the texture combiners */ - set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage, + set_tex_op_nvrc((IWineD3DDevice *)stateblock->device, FALSE, stage, stateblock->textureState[stage][WINED3DTSS_COLOROP], stateblock->textureState[stage][WINED3DTSS_COLORARG1], stateblock->textureState[stage][WINED3DTSS_COLORARG2], @@ -562,7 +562,7 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD sampler = state - STATE_SAMPLER(0); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler]; + DWORD mapped_stage = stateblock->device->texUnitMap[sampler]; /* No need to enable / disable anything here for unused samplers. The tex_colorop * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop @@ -578,7 +578,7 @@ static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1]; + DWORD mapped_stage = stateblock->device->texUnitMap[stage + 1]; float mat[2][2]; /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c index a5447d07335..c9c6182f726 100644 --- a/dlls/wined3d/palette.c +++ b/dlls/wined3d/palette.c @@ -151,7 +151,8 @@ static HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, /* If the palette is attached to the render target, update all render targets */ - LIST_FOR_EACH_ENTRY(res, &This->wineD3DDevice->resources, IWineD3DResourceImpl, resource.resource_list_entry) { + LIST_FOR_EACH_ENTRY(res, &This->device->resources, IWineD3DResourceImpl, resource.resource_list_entry) + { if(IWineD3DResource_GetType((IWineD3DResource *) res) == WINED3DRTYPE_SURFACE) { IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res; if(impl->palette == This) diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index d15649812b4..a531f093bb6 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -90,15 +90,6 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_GetParent(IWineD3DPixelShader *if return WINED3D_OK; } -static HRESULT WINAPI IWineD3DPixelShaderImpl_GetDevice(IWineD3DPixelShader* iface, IWineD3DDevice **pDevice){ - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; - IWineD3DDevice_AddRef(This->baseShader.device); - *pDevice = This->baseShader.device; - TRACE("(%p) returning %p\n", This, *pDevice); - return WINED3D_OK; -} - - static HRESULT WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader* impl, VOID* pData, UINT* pSizeOfData) { IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)impl; TRACE("(%p) : pData(%p), pSizeOfData(%p)\n", This, pData, pSizeOfData); @@ -353,7 +344,6 @@ static const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl = /*** IWineD3DBase methods ***/ IWineD3DPixelShaderImpl_GetParent, /*** IWineD3DBaseShader methods ***/ - IWineD3DPixelShaderImpl_GetDevice, IWineD3DPixelShaderImpl_GetFunction /*** IWineD3DPixelShader methods ***/ }; diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index 76f519dd04f..f3e51de07bb 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -31,7 +31,7 @@ */ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION This->device->adapter->gl_info /* ******************************************* IWineD3DQuery IUnknown parts follow @@ -98,15 +98,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetParent(IWineD3DQuery *iface, IUnknow return WINED3D_OK; } -static HRESULT WINAPI IWineD3DQueryImpl_GetDevice(IWineD3DQuery* iface, IWineD3DDevice **pDevice){ - IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; - IWineD3DDevice_AddRef((IWineD3DDevice *)This->wineD3DDevice); - *pDevice = (IWineD3DDevice *)This->wineD3DDevice; - TRACE("(%p) returning %p\n", This, *pDevice); - return WINED3D_OK; -} - - static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags){ IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; HRESULT res = S_OK; @@ -272,7 +263,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) { IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface; struct wined3d_occlusion_query *query = This->extendedData; - IWineD3DDeviceImpl *device = This->wineD3DDevice; + IWineD3DDeviceImpl *device = This->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; DWORD* data = pData; @@ -313,7 +304,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, return S_OK; } - context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); ENTER_GL(); @@ -371,7 +362,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void return S_OK; } - context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); ENTER_GL(); @@ -481,17 +472,17 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD if (query->context->tid != GetCurrentThreadId()) { context_free_event_query(query); - context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); context_alloc_event_query(context, query); } else { - context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); } } else { - context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); context_alloc_event_query(context, query); } @@ -529,7 +520,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags) { IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; - IWineD3DDeviceImpl *device = This->wineD3DDevice; + IWineD3DDeviceImpl *device = This->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; if (gl_info->supported[ARB_OCCLUSION_QUERY]) @@ -547,12 +538,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D FIXME("Wrong thread, can't restart query.\n"); context_free_occlusion_query(query); - context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); context_alloc_occlusion_query(context, query); } else { - context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -563,7 +554,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D else { if (query->context) context_free_occlusion_query(query); - context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); context_alloc_occlusion_query(context, query); } @@ -587,7 +578,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D } else { - context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -640,7 +631,6 @@ const IWineD3DQueryVtbl IWineD3DQuery_Vtbl = IWineD3DQueryImpl_Release, /*** IWineD3Dquery methods ***/ IWineD3DQueryImpl_GetParent, - IWineD3DQueryImpl_GetDevice, IWineD3DQueryImpl_GetData, IWineD3DQueryImpl_GetDataSize, IWineD3DQueryImpl_GetType, @@ -655,7 +645,6 @@ const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl = IWineD3DQueryImpl_Release, /*** IWineD3Dquery methods ***/ IWineD3DQueryImpl_GetParent, - IWineD3DQueryImpl_GetDevice, IWineD3DEventQueryImpl_GetData, IWineD3DEventQueryImpl_GetDataSize, IWineD3DQueryImpl_GetType, @@ -670,7 +659,6 @@ const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl = IWineD3DQueryImpl_Release, /*** IWineD3Dquery methods ***/ IWineD3DQueryImpl_GetParent, - IWineD3DQueryImpl_GetDevice, IWineD3DOcclusionQueryImpl_GetData, IWineD3DOcclusionQueryImpl_GetDataSize, IWineD3DQueryImpl_GetType, diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 17f336d4966..b867586096d 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -33,7 +33,7 @@ HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type { struct IWineD3DResourceClass *resource = &((IWineD3DResourceImpl *)iface)->resource; - resource->wineD3DDevice = device; + resource->device = device; resource->parent = parent; resource->resourceType = resource_type; resource->ref = 1; @@ -87,7 +87,7 @@ void resource_cleanup(IWineD3DResource *iface) TRACE("(%p) Cleaning up resource\n", This); if (This->resource.pool == WINED3DPOOL_DEFAULT) { TRACE("Decrementing device memory pool by %u\n", This->resource.size); - WineD3DAdapterChangeGLRam(This->resource.wineD3DDevice, -This->resource.size); + WineD3DAdapterChangeGLRam(This->resource.device, -This->resource.size); } LIST_FOR_EACH_SAFE(e1, e2, &This->resource.privateData) { @@ -102,16 +102,7 @@ void resource_cleanup(IWineD3DResource *iface) This->resource.allocatedMemory = 0; This->resource.heapMemory = 0; - if (This->resource.wineD3DDevice) device_resource_released(This->resource.wineD3DDevice, iface); -} - -HRESULT resource_get_device(IWineD3DResource *iface, IWineD3DDevice** ppDevice) -{ - IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface; - TRACE("(%p) : returning %p\n", This, This->resource.wineD3DDevice); - *ppDevice = (IWineD3DDevice *) This->resource.wineD3DDevice; - IWineD3DDevice_AddRef(*ppDevice); - return WINED3D_OK; + if (This->resource.device) device_resource_released(This->resource.device, iface); } static PrivateData* resource_find_private_data(IWineD3DResourceImpl *This, REFGUID tag) @@ -188,7 +179,8 @@ HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID refguid, void if (data->flags & WINED3DSPD_IUNKNOWN) { *(LPUNKNOWN *)pData = data->ptr.object; - if(((IWineD3DImpl *) This->resource.wineD3DDevice->wineD3D)->dxVersion != 7) { + if (((IWineD3DImpl *)This->resource.device->wined3d)->dxVersion != 7) + { /* D3D8 and D3D9 addref the private data, DDraw does not. This can't be handled in * ddraw because it doesn't know if the pointer returned is an IUnknown * or just a * Blob diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 6df6e548b23..d9ece3399b8 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -95,7 +95,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru } if (stateblock->renderState[WINED3DRS_LIGHTING] - && !stateblock->wineD3DDevice->strided_streams.position_transformed) + && !stateblock->device->strided_streams.position_transformed) { glEnable(GL_LIGHTING); checkGLcall("glEnable GL_LIGHTING"); @@ -108,7 +108,8 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { /* No z test without depth stencil buffers */ - if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) { + if (!stateblock->device->stencilBufferTarget) + { TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ checkGLcall("glDisable GL_DEPTH_TEST"); @@ -241,9 +242,9 @@ static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; int srcBlend = GL_ZERO; int dstBlend = GL_ZERO; - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0]; /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */ if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] || @@ -252,7 +253,8 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct /* Disable blending in all cases even without pixelshaders. With blending on we could face a big performance penalty. * The d3d9 visual test confirms the behavior. */ - if (!(target->resource.format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) + if (context->render_offscreen + && !(target->resource.format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) { glDisable(GL_BLEND); checkGLcall("glDisable GL_BLEND"); @@ -447,8 +449,9 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state, so it may need updating */ - if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) { - const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable; + if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) + { + const struct StateEntry *StateTable = stateblock->device->StateTable; StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } } @@ -502,8 +505,9 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } } - if(enable_ckey || context->last_was_ckey) { - const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable; + if (enable_ckey || context->last_was_ckey) + { + const struct StateEntry *StateTable = stateblock->device->StateTable; StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } context->last_was_ckey = enable_ckey; @@ -539,7 +543,7 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, stru DWORD enable = 0xFFFFFFFF; DWORD disable = 0x00000000; - if (!stateblock->wineD3DDevice->vs_clipping && use_vs(stateblock)) + if (!stateblock->device->vs_clipping && use_vs(stateblock)) { /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't, * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some @@ -747,14 +751,18 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock } } - TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Diffuse.r, stateblock->material.Diffuse.g, - stateblock->material.Diffuse.b, stateblock->material.Diffuse.a); - TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Ambient.r, stateblock->material.Ambient.g, - stateblock->material.Ambient.b, stateblock->material.Ambient.a); - TRACE("(%p) : Specular (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Specular.r, stateblock->material.Specular.g, - stateblock->material.Specular.b, stateblock->material.Specular.a); - TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Emissive.r, stateblock->material.Emissive.g, - stateblock->material.Emissive.b, stateblock->material.Emissive.a); + TRACE("(%p) : Diffuse {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, + stateblock->material.Diffuse.r, stateblock->material.Diffuse.g, + stateblock->material.Diffuse.b, stateblock->material.Diffuse.a); + TRACE("(%p) : Ambient {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, + stateblock->material.Ambient.r, stateblock->material.Ambient.g, + stateblock->material.Ambient.b, stateblock->material.Ambient.a); + TRACE("(%p) : Specular {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, + stateblock->material.Specular.r, stateblock->material.Specular.g, + stateblock->material.Specular.b, stateblock->material.Specular.a); + TRACE("(%p) : Emissive {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device, + stateblock->material.Emissive.r, stateblock->material.Emissive.g, + stateblock->material.Emissive.b, stateblock->material.Emissive.a); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &stateblock->material.Ambient); checkGLcall("glMaterialfv(GL_AMBIENT)"); @@ -816,8 +824,9 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc GLint depthFail_ccw = GL_KEEP; GLint stencilPass_ccw = GL_KEEP; - /* No stencil test without a stencil buffer */ - if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) { + /* No stencil test without a stencil buffer. */ + if (!stateblock->device->stencilBufferTarget) + { glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); return; @@ -899,13 +908,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask; - - if(stateblock->wineD3DDevice->stencilBufferTarget) { - mask = stateblock->renderState[WINED3DRS_STENCILWRITEMASK]; - } else { - mask = 0; - } + DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); @@ -918,13 +921,7 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask; - - if(stateblock->wineD3DDevice->stencilBufferTarget) { - mask = stateblock->renderState[WINED3DRS_STENCILWRITEMASK]; - } else { - mask = 0; - } + DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; glStencilMask(mask); checkGLcall("glStencilMask"); @@ -1198,7 +1195,7 @@ void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; GLenum Parm = 0; /* Depends on the decoded vertex declaration to read the existence of diffuse data. @@ -1367,7 +1364,7 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, str * by zero and is not properly defined in opengl, so avoid it */ if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS] - && (stateblock->wineD3DDevice->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL))) + && (stateblock->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL))) { glEnable(GL_NORMALIZE); checkGLcall("glEnable(GL_NORMALIZE);"); @@ -2973,8 +2970,8 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; - BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage); + BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage); + DWORD mapped_stage = stateblock->device->texUnitMap[stage]; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Setting color op for stage %d\n", stage); @@ -3026,7 +3023,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct if (tex_used) texture_activate_dimensions(stage, stateblock, context); } - set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage, + set_tex_op(context, (IWineD3DDevice *)stateblock->device, FALSE, stage, stateblock->textureState[stage][WINED3DTSS_COLOROP], stateblock->textureState[stage][WINED3DTSS_COLORARG1], stateblock->textureState[stage][WINED3DTSS_COLORARG2], @@ -3036,8 +3033,8 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; - BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage); + BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage); + DWORD mapped_stage = stateblock->device->texUnitMap[stage]; DWORD op, arg1, arg2, arg0; TRACE("Setting alpha op for stage %d\n", stage); @@ -3125,20 +3122,19 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d TRACE("Setting alpha op for stage %d\n", stage); if (context->gl_info->supported[NV_REGISTER_COMBINERS]) { - set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage, - op, arg1, arg2, arg0, - mapped_stage, - stateblock->textureState[stage][WINED3DTSS_RESULTARG]); - } else { - set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage, - op, arg1, arg2, arg0); + set_tex_op_nvrc((IWineD3DDevice *)stateblock->device, TRUE, stage, op, arg1, arg2, arg0, + mapped_stage, stateblock->textureState[stage][WINED3DTSS_RESULTARG]); + } + else + { + set_tex_op(context, (IWineD3DDevice *)stateblock->device, TRUE, stage, op, arg1, arg2, arg0); } } static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit]; + DWORD mapped_stage = stateblock->device->texUnitMap[texUnit]; BOOL generated; int coordIdx; @@ -3159,10 +3155,10 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw, - stateblock->wineD3DDevice->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)) - ? stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format + stateblock->device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)) + ? stateblock->device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format : WINED3DFMT_UNKNOWN, - stateblock->wineD3DDevice->frag_pipe->ffp_proj_control); + stateblock->device->frag_pipe->ffp_proj_control); /* The sampler applying function calls us if this changes */ if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->textures[texUnit]) @@ -3201,7 +3197,7 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl { int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX]; - mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo]; + mapped_stage = stateblock->device->texUnitMap[textureNo]; if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))) @@ -3244,7 +3240,7 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; + DWORD mapped_stage = stateblock->device->texUnitMap[stage]; static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f }; static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f }; static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f }; @@ -3412,13 +3408,13 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru GLuint curVBO = context->gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; unloadTexCoords(context); - loadTexCoords(context, stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO); + loadTexCoords(context, stateblock, &stateblock->device->strided_streams, &curVBO); } } static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them * has an update pending @@ -3470,7 +3466,8 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, s { if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler; else context->lastWasPow2Texture &= ~(1 << sampler); - transform_texture(STATE_TEXTURESTAGE(stateblock->wineD3DDevice->texUnitMap[sampler], WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context); + transform_texture(STATE_TEXTURESTAGE(stateblock->device->texUnitMap[sampler], + WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context); } } } @@ -3478,7 +3475,7 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD sampler = state - STATE_SAMPLER(0); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler]; + DWORD mapped_stage = stateblock->device->texUnitMap[sampler]; const struct wined3d_gl_info *gl_info = context->gl_info; union { float f; @@ -3531,8 +3528,9 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine } /* Trigger shader constant reloading (for NP2 texcoord fixup) */ - if (!tex_impl->baseTexture.pow2Matrix_identity) { - IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice; + if (!tex_impl->baseTexture.pow2Matrix_identity) + { + IWineD3DDeviceImpl *d3ddevice = stateblock->device; d3ddevice->shader_backend->shader_load_np2fixup_constants( (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock)); } @@ -3548,14 +3546,14 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context); } } /* Otherwise tex_colorop disables the stage */ - glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler]); - checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler])"); + glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler]); + checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler])"); } } void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; BOOL use_pshader = use_ps(stateblock); BOOL use_vshader = use_vs(stateblock); int i; @@ -3632,10 +3630,13 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str checkGLcall("glLoadIdentity()"); } else { /* In the general case, the view matrix is the identity matrix */ - if (stateblock->wineD3DDevice->view_ident) { + if (stateblock->device->view_ident) + { glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); checkGLcall("glLoadMatrixf"); - } else { + } + else + { glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); checkGLcall("glLoadMatrixf"); glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); @@ -3710,10 +3711,13 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix */ - if(stateblock->wineD3DDevice->view_ident) { + if (stateblock->device->view_ident) + { glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]); checkGLcall("glLoadMatrixf"); - } else { + } + else + { glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); checkGLcall("glLoadMatrixf"); glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]); @@ -3757,7 +3761,8 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s */ GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1)); - if(!stateblock->wineD3DDevice->vertexBlendUsed) { + if (!stateblock->device->vertexBlendUsed) + { unsigned int i; for (i = 1; i < context->gl_info->limits.blends; ++i) { @@ -3766,7 +3771,7 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context); } } - stateblock->wineD3DDevice->vertexBlendUsed = TRUE; + stateblock->device->vertexBlendUsed = TRUE; } break; @@ -3803,7 +3808,8 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru checkGLcall("glLoadMatrixf(...)"); /* Reset lights. TODO: Call light apply func */ - for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) { + for (k = 0; k < stateblock->device->maxConcurrentLights; ++k) + { light = stateblock->activeLights[k]; if(!light) continue; glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn); @@ -3835,7 +3841,7 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru } /* Avoid looping over a number of matrices if the app never used the functionality */ - if (stateblock->wineD3DDevice->vertexBlendUsed) + if (stateblock->device->vertexBlendUsed) { for (k = 1; k < context->gl_info->limits.blends; ++k) { @@ -3863,7 +3869,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock minZ = stateblock->viewport.MinZ; maxZ = stateblock->viewport.MaxZ; - if(!stateblock->wineD3DDevice->untransformed) { + if (!stateblock->device->untransformed) + { /* Transformed vertices are supposed to bypass the whole transform pipeline including * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to * suppress depth clipping. This can be done because it is an orthogonal projection and @@ -4041,7 +4048,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, DWORD_PTR shift_index; /* Default to no instancing */ - stateblock->wineD3DDevice->instancedDraw = FALSE; + stateblock->device->instancedDraw = FALSE; for (i = 0; i < MAX_ATTRIBS; i++) { if (!(stream_info->use_map & (1 << i))) @@ -4054,7 +4061,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA) { if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); - stateblock->wineD3DDevice->instancedDraw = TRUE; + stateblock->device->instancedDraw = TRUE; continue; } @@ -4216,7 +4223,7 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB TRACE("Using fast vertex array code\n"); /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */ - stateblock->wineD3DDevice->instancedDraw = FALSE; + stateblock->device->instancedDraw = FALSE; /* Blend Data ---------------------------------------------- */ if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT)) @@ -4472,7 +4479,7 @@ static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_i static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; BOOL fixup = FALSE; struct wined3d_stream_info *dataLocations = &device->strided_streams; BOOL useVertexShaderFunction; @@ -4562,9 +4569,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s BOOL updateFog = FALSE; BOOL useVertexShaderFunction = use_vs(stateblock); BOOL usePixelShaderFunction = use_ps(stateblock); + IWineD3DDeviceImpl *device = stateblock->device; BOOL transformed; - /* Some stuff is in the device until we have per context tracking */ - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; BOOL wasrhw = context->last_was_rhw; unsigned int i; @@ -4720,8 +4726,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; UINT width, height; - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0]; WINED3DVIEWPORT vp = stateblock->viewport; if(vp.Width > target->currentDesc.Width) vp.Width = target->currentDesc.Width; @@ -4749,8 +4755,8 @@ static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, { GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height; - stateblock->wineD3DDevice->posFixup[2] = (63.0f / 64.0f) / stateblock->viewport.Width; - stateblock->wineD3DDevice->posFixup[3] = stateblock->wineD3DDevice->posFixup[1] * yoffset; + stateblock->device->posFixup[2] = (63.0f / 64.0f) / stateblock->viewport.Width; + stateblock->device->posFixup[3] = stateblock->device->posFixup[1] * yoffset; if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) { transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context); @@ -4878,16 +4884,16 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; RECT *pRect = &stateblock->scissorRect; UINT height; UINT width; - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0]; target->get_drawable_size(context, &width, &height); /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply * Warning2: Even in windowed mode the coords are relative to the window, not the screen */ - TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height, + TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->device, pRect->left, pRect->bottom - height, pRect->right - pRect->left, pRect->bottom - pRect->top); if (context->render_offscreen) @@ -5686,15 +5692,15 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs) static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context); - stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context); + stateblock->device->multistate_funcs[state][0](state, stateblock, context); + stateblock->device->multistate_funcs[state][1](state, stateblock, context); } static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context); - stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context); - stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context); + stateblock->device->multistate_funcs[state][0](state, stateblock, context); + stateblock->device->multistate_funcs[state][1](state, stateblock, context); + stateblock->device->multistate_funcs[state][2](state, stateblock, context); } HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 41fca71235c..7c47f362704 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -193,7 +193,7 @@ static const DWORD vertex_states_sampler[] = */ static HRESULT stateblock_allocate_shader_constants(IWineD3DStateBlockImpl *object) { - IWineD3DDeviceImpl *device = object->wineD3DDevice; + IWineD3DDeviceImpl *device = object->device; /* Allocate space for floating point constants */ object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, @@ -329,7 +329,7 @@ static void stateblock_savedstates_set_vertex(SAVEDSTATES *states, const DWORD n void stateblock_init_contained_states(IWineD3DStateBlockImpl *stateblock) { - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; unsigned int i, j; for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i) @@ -535,16 +535,6 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { /********************************************************** * IWineD3DStateBlockImpl parts follows **********************************************************/ -static HRESULT WINAPI IWineD3DStateBlockImpl_GetDevice(IWineD3DStateBlock *iface, IWineD3DDevice** ppDevice){ - - IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; - - *ppDevice = (IWineD3DDevice*)This->wineD3DDevice; - IWineD3DDevice_AddRef(*ppDevice); - return WINED3D_OK; - -} - static void record_lights(IWineD3DStateBlockImpl *This, const IWineD3DStateBlockImpl *targetStateBlock) { UINT i; @@ -593,7 +583,7 @@ static void record_lights(IWineD3DStateBlockImpl *This, const IWineD3DStateBlock static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; - IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock; + IWineD3DStateBlockImpl *targetStateBlock = This->device->stateBlock; unsigned int i; DWORD map; @@ -730,7 +720,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) if (This->changed.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl && (This->blockType != WINED3DSBT_RECORDED - || ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion != 9)) + || ((IWineD3DImpl *)This->device->wined3d)->dxVersion != 9)) { TRACE("Updating vertex declaration from %p to %p.\n", This->vertexDecl, targetStateBlock->vertexDecl); @@ -888,7 +878,7 @@ static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl * static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; - IWineD3DDevice *pDevice = (IWineD3DDevice *)This->wineD3DDevice; + IWineD3DDevice *pDevice = (IWineD3DDevice *)This->device; unsigned int i; DWORD map; @@ -971,8 +961,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) if (This->changed.primitive_type) { - This->wineD3DDevice->updateStateBlock->changed.primitive_type = TRUE; - This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type; + This->device->updateStateBlock->changed.primitive_type = TRUE; + This->device->updateStateBlock->gl_primitive_type = This->gl_primitive_type; } if (This->changed.indices) @@ -1038,12 +1028,12 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) IWineD3DDevice_SetClipPlane(pDevice, i, clip); } - This->wineD3DDevice->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1; + This->device->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1; for (i = 0; i < MAX_TEXTURES - 1; ++i) { - if (This->wineD3DDevice->stateBlock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) + if (This->device->stateBlock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) { - This->wineD3DDevice->stateBlock->lowest_disabled_stage = i; + This->device->stateBlock->lowest_disabled_stage = i; break; } } @@ -1054,9 +1044,9 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; - IWineD3DDevice *device = (IWineD3DDevice *)This->wineD3DDevice; + IWineD3DDevice *device = (IWineD3DDevice *)This->device; IWineD3DDeviceImpl *ThisDevice = (IWineD3DDeviceImpl *)device; - const struct wined3d_gl_info *gl_info = &This->wineD3DDevice->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &ThisDevice->adapter->gl_info; union { WINED3DLINEPATTERN lp; DWORD d; @@ -1073,7 +1063,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat /* Note this may have a large overhead but it should only be executed once, in order to initialize the complete state of the device and all opengl equivalents */ - TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, This->wineD3DDevice); + TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, ThisDevice); /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */ This->blockType = WINED3DSBT_INIT; @@ -1321,7 +1311,6 @@ static const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl = IWineD3DStateBlockImpl_AddRef, IWineD3DStateBlockImpl_Release, /* IWineD3DStateBlock */ - IWineD3DStateBlockImpl_GetDevice, IWineD3DStateBlockImpl_Capture, IWineD3DStateBlockImpl_Apply, IWineD3DStateBlockImpl_InitStartupStateBlock @@ -1334,7 +1323,7 @@ HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl * stateblock->lpVtbl = &IWineD3DStateBlock_Vtbl; stateblock->ref = 1; - stateblock->wineD3DDevice = device; + stateblock->device = device; stateblock->blockType = type; for (i = 0; i < LIGHTMAP_SIZE; i++) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index d75c5e900e9..3d2a3378d31 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -38,7 +38,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); static void surface_cleanup(IWineD3DSurfaceImpl *This) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context = NULL; renderbuffer_entry_t *entry, *entry2; @@ -322,11 +322,11 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) { ENTER_GL(); glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); LEAVE_GL(); - active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB]; + active_sampler = This->resource.device->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB]; if (active_sampler != WINED3D_UNMAPPED_STAGE) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler)); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_SAMPLER(active_sampler)); } IWineD3DSurface_BindTexture((IWineD3DSurface *)This, srgb); } @@ -345,7 +345,7 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device) #undef GLINFO_LOCATION -#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION This->resource.device->adapter->gl_info /* This call just downloads data, the caller is responsible for binding the * correct texture. */ @@ -393,14 +393,14 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { int dst_pitch = 0; /* In case of P8 the index is stored in the alpha component if the primary render target uses P8 */ - if (format_desc->format == WINED3DFMT_P8_UINT && primary_render_target_is_p8(This->resource.wineD3DDevice)) + if (format_desc->format == WINED3DFMT_P8_UINT && primary_render_target_is_p8(This->resource.device)) { format = GL_ALPHA; type = GL_UNSIGNED_BYTE; } if (This->Flags & SFLAG_NONPOW2) { - unsigned char alignment = This->resource.wineD3DDevice->surface_alignment; + unsigned char alignment = This->resource.device->surface_alignment; src_pitch = format_desc->byte_count * This->pow2Width; dst_pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This); src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1); @@ -553,7 +553,7 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi * the correct texture. */ /* Context activation is done by the caller. */ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) { - const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; BOOL enable_client_storage = FALSE; const BYTE *mem = NULL; @@ -615,7 +615,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, /* GL locking is done by the caller */ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; renderbuffer_entry_t *entry; GLuint renderbuffer = 0; unsigned int src_width, src_height; @@ -668,6 +668,10 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchai TRACE("(%p) : swapchain %p\n", This, swapchain); if (swapchain_impl->backBuffer && swapchain_impl->backBuffer[0] == iface) { + if(swapchain_impl->render_to_fbo) { + TRACE("Returning GL_COLOR_ATTACHMENT0\n"); + return GL_COLOR_ATTACHMENT0; + } TRACE("Returning GL_BACK\n"); return GL_BACK; } else if (swapchain_impl->frontBuffer == iface) { @@ -753,8 +757,8 @@ void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) { /* TODO: check for locks */ IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + IWineD3DDeviceImpl *device = This->resource.device; IWineD3DBaseTexture *baseTexture = NULL; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; TRACE("(%p)Checking to see if the container is a base texture\n", This); if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { @@ -820,10 +824,34 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *This) { This->Flags &= ~SFLAG_PBO; } +BOOL surface_init_sysmem(IWineD3DSurface *iface) +{ + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; + + if(!This->resource.allocatedMemory) + { + This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT); + if(!This->resource.heapMemory) + { + ERR("Out of memory\n"); + return FALSE; + } + This->resource.allocatedMemory = + (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); + } + else + { + memset(This->resource.allocatedMemory, 0, This->resource.size); + } + + IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); + return TRUE; +} + static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { IWineD3DBaseTexture *texture = NULL; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info; renderbuffer_entry_t *entry, *entry2; struct wined3d_context *context; @@ -836,18 +864,12 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { * or depth stencil. The content may be destroyed, but we still have to tear down * opengl resources, so we cannot leave early. * - * Put the most up to date surface location into the drawable. D3D-wise this content - * is undefined, so it would be nowhere, but that would make the location management - * more complicated. The drawable is a sane location, because if we mark sysmem or - * texture up to date, drawPrim will copy the uninitialized texture or sysmem to the - * uninitialized drawable. That's pointless and we'd have to allocate the texture / - * sysmem copy here. + * Put the surfaces into sysmem, and reset the content. The D3D content is undefined, + * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain + * or the depth stencil into an FBO the texture or render buffer will be removed + * and all flags get lost */ - if (This->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) { - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); - } else { - IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, TRUE); - } + surface_init_sysmem(iface); } else { /* Load the surface into system memory */ IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); @@ -904,9 +926,9 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { ****************************************************** */ /* Read the framebuffer back into the surface */ -static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) { - IWineD3DSwapChainImpl *swapchain; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; +static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, void *dest, UINT pitch) +{ + IWineD3DDeviceImpl *myDevice = This->resource.device; struct wined3d_context *context; BYTE *mem; GLint fmt; @@ -941,16 +963,8 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&swapchain))) + if (surface_is_offscreen((IWineD3DSurface *) This)) { - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain); - TRACE("Locking %#x buffer\n", buffer); - glReadBuffer(buffer); - checkGLcall("glReadBuffer"); - - IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); - srcIsUpsideDown = FALSE; - } else { /* Locking the primary render target which is not on a swapchain(=offscreen render target). * Read from the back buffer */ @@ -958,6 +972,15 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v glReadBuffer(myDevice->offscreenBuffer); srcIsUpsideDown = TRUE; } + else + { + /* Onscreen surfaces are always part of a swapchain */ + GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *) This->container); + TRACE("Locking %#x buffer\n", buffer); + glReadBuffer(buffer); + checkGLcall("glReadBuffer"); + srcIsUpsideDown = FALSE; + } /* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */ if(!rect) { @@ -1148,7 +1171,7 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v /* Read the framebuffer contents into a texture */ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; IWineD3DSwapChainImpl *swapchain; struct wined3d_context *context; int bpp; @@ -1225,7 +1248,7 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; /* Performance optimization: Count how often a surface is locked, if it is locked regularly do not throw away the system memory copy. @@ -1299,7 +1322,7 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; const RECT *pass_rect = pRect; TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory); @@ -1402,7 +1425,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm GLint prev_rasterpos[4]; GLint skipBytes = 0; UINT pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This); /* target is argb, 4 byte */ - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; IWineD3DSwapChainImpl *swapchain; struct wined3d_context *context; @@ -1506,7 +1529,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; BOOL fullsurface; if (!(This->Flags & SFLAG_LOCKED)) { @@ -1681,7 +1704,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD } else { IWineD3DSurfaceImpl *dds_primary; IWineD3DSwapChainImpl *swapchain; - swapchain = (IWineD3DSwapChainImpl *)This->resource.wineD3DDevice->swapchains[0]; + swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0]; dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; @@ -1739,7 +1762,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) { BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT); const struct GlPixelFormatDesc *glDesc = This->resource.format_desc; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; /* Default values: From the surface */ @@ -1752,7 +1775,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ *internal = glDesc->glGammaInternal; } else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET - && !(This->Flags & SFLAG_SWAPCHAIN)) + && surface_is_offscreen((IWineD3DSurface *) This)) { *internal = glDesc->rtInternal; } else { @@ -1966,7 +1989,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; IWineD3DPaletteImpl *pal = This->palette; BOOL index_in_alpha = FALSE; unsigned int i; @@ -1980,7 +2003,7 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4] if (!pal) { - UINT dxVersion = ((IWineD3DImpl *)device->wineD3D)->dxVersion; + UINT dxVersion = ((IWineD3DImpl *)device->wined3d)->dxVersion; /* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */ if (dxVersion <= 7) @@ -2047,7 +2070,7 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4] static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const BYTE *source; BYTE *dest; @@ -2486,7 +2509,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; BYTE table[256][4]; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; d3dfmt_p8_init_palette(This, table, (convert == CONVERT_PALETTED_CK)); @@ -2551,8 +2574,9 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve } } -BOOL palette9_changed(IWineD3DSurfaceImpl *This) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; +BOOL palette9_changed(IWineD3DSurfaceImpl *This) +{ + IWineD3DDeviceImpl *device = This->resource.device; if (This->palette || (This->resource.format_desc->format != WINED3DFMT_P8_UINT && This->resource.format_desc->format != WINED3DFMT_P8_UINT_A8_UNORM)) @@ -2651,8 +2675,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) { /* TODO: check for locks */ IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + IWineD3DDeviceImpl *device = This->resource.device; IWineD3DBaseTexture *baseTexture = NULL; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; TRACE("(%p)Checking to see if the container is a base texture\n", This); if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { @@ -2762,7 +2786,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c glGetIntegerv(GL_READ_BUFFER, &prevRead); checkGLcall("glGetIntegerv"); - glReadBuffer(swapChain ? GL_BACK : This->resource.wineD3DDevice->offscreenBuffer); + glReadBuffer(swapChain ? GL_BACK : This->resource.device->offscreenBuffer); checkGLcall("glReadBuffer"); glCopyTexImage2D(GL_TEXTURE_2D, 0, @@ -3070,7 +3094,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; float xrel, yrel; UINT row; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; @@ -3084,7 +3108,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D /* Bind the target texture */ glBindTexture(This->texture_target, This->texture_name); checkGLcall("glBindTexture"); - if(!swapchain) { + if(surface_is_offscreen(SrcSurface)) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; glReadBuffer(myDevice->offscreenBuffer); @@ -3165,8 +3189,8 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) { + IWineD3DDeviceImpl *myDevice = This->resource.device; GLuint src, backup = 0; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; float left, right, top, bottom; /* Texture coordinates */ UINT fbwidth = Src->currentDesc.Width; @@ -3223,12 +3247,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine Src->Flags &= ~SFLAG_INTEXTURE; } - if(swapchain) { - glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain)); - } else { + if(surface_is_offscreen(SrcSurface)) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; glReadBuffer(myDevice->offscreenBuffer); + } else { + glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain)); } /* TODO: Only back up the part that will be overwritten */ @@ -3418,8 +3442,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { + IWineD3DDeviceImpl *myDevice = This->resource.device; WINED3DRECT rect; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; IWineD3DSwapChainImpl *srcSwapchain = NULL, *dstSwapchain = NULL; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; @@ -3968,7 +3992,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *DestRect, IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx) { - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; float depth; if (Flags & WINEDDBLT_DEPTHFILL) { @@ -4009,7 +4033,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; + TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx); TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage)); @@ -4050,7 +4075,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DSurfaceImpl *srcImpl = (IWineD3DSurfaceImpl *) Source; - IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *myDevice = This->resource.device; + TRACE("(%p)->(%d, %d, %p, %p, %08x\n", iface, dstx, dsty, Source, rsrc, trans); if ( (This->Flags & SFLAG_LOCKED) || (srcImpl->Flags & SFLAG_LOCKED)) @@ -4132,7 +4158,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION)) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */ @@ -4176,7 +4202,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { /** Check against the maximum texture sizes supported by the video card **/ IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; unsigned int pow2Width, pow2Height; This->texture_name = 0; @@ -4366,7 +4392,7 @@ static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, stru /* GL locking is done by the caller */ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target) { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct depth_blt_info info; GLint old_binding = 0; @@ -4425,7 +4451,7 @@ void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) { void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("(%p) New location %#x\n", This, location); @@ -4544,13 +4570,15 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW persistent ? "TRUE" : "FALSE"); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (This->Flags & SFLAG_SWAPCHAIN) + if (surface_is_offscreen(iface)) { - TRACE("Surface %p is an onscreen surface\n", iface); - } else { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); } + else + { + TRACE("Surface %p is an onscreen surface\n", iface); + } } if(persistent) { @@ -4609,12 +4637,12 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) { + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; struct coords coords[4]; RECT rect; IWineD3DSwapChain *swapchain; IWineD3DBaseTexture *texture; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; GLenum bind_target; struct float_rect f; @@ -4803,7 +4831,7 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *****************************************************************************/ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, DWORD flag, const RECT *rect) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; GLenum format, internal, type; CONVERT_TYPES convert; @@ -4811,16 +4839,20 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D int width, pitch, outpitch; BYTE *mem; BOOL drawable_read_ok = TRUE; + BOOL in_fbo = FALSE; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (This->Flags & SFLAG_SWAPCHAIN) + if (surface_is_offscreen(iface)) { - TRACE("Surface %p is an onscreen surface\n", iface); - } else { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. * Prefer SFLAG_INTEXTURE. */ if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE; drawable_read_ok = FALSE; + in_fbo = TRUE; + } + else + { + TRACE("Surface %p is an onscreen surface\n", iface); } } @@ -5045,8 +5077,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D This->Flags |= flag; } - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !(This->Flags & SFLAG_SWAPCHAIN) - && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) { + if (in_fbo && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ This->Flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); } @@ -5103,6 +5134,22 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) { return hr; } +BOOL surface_is_offscreen(IWineD3DSurface *iface) +{ + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) This->container; + + /* Not on a swapchain - must be offscreen */ + if (!(This->Flags & SFLAG_SWAPCHAIN)) return TRUE; + + /* The front buffer is always onscreen */ + if(iface == swapchain->frontBuffer) return FALSE; + + /* If the swapchain is rendered to an FBO, the backbuffer is + * offscreen, otherwise onscreen */ + return swapchain->render_to_fbo; +} + const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = { /* IUnknown */ @@ -5111,7 +5158,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_Release, /* IWineD3DResource */ IWineD3DBaseSurfaceImpl_GetParent, - IWineD3DBaseSurfaceImpl_GetDevice, IWineD3DBaseSurfaceImpl_SetPrivateData, IWineD3DBaseSurfaceImpl_GetPrivateData, IWineD3DBaseSurfaceImpl_FreePrivateData, diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c index ca715f50eab..c737f99c965 100644 --- a/dlls/wined3d/surface_base.c +++ b/dlls/wined3d/surface_base.c @@ -117,10 +117,6 @@ ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface) { /* **************************************************** IWineD3DSurface IWineD3DResource parts follow **************************************************** */ -HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice) { - return resource_get_device((IWineD3DResource *)iface, ppDevice); -} - HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags); } @@ -166,11 +162,8 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFI } /* Standalone surfaces return the device as container. */ - if (This->container) { - container = This->container; - } else { - container = (IWineD3DBase *)This->resource.wineD3DDevice; - } + if (This->container) container = This->container; + else container = (IWineD3DBase *)This->resource.device; TRACE("Relaying to QueryInterface\n"); return IUnknown_QueryInterface(container, riid, ppContainer); @@ -346,7 +339,7 @@ DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) { } else { - unsigned char alignment = This->resource.wineD3DDevice->surface_alignment; + unsigned char alignment = This->resource.device->surface_alignment; ret = This->resource.format_desc->byte_count * This->currentDesc.Width; /* Bytes / row */ ret = (ret + alignment - 1) & ~(alignment - 1); } @@ -511,7 +504,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWin HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, - &This->resource.wineD3DDevice->adapter->gl_info); + &This->resource.device->adapter->gl_info); if (This->resource.format_desc->format != WINED3DFMT_UNKNOWN) { @@ -521,7 +514,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D TRACE("(%p) : Setting texture format to (%d,%s)\n", This, format, debug_d3dformat(format)); - This->resource.size = surface_calculate_size(format_desc, This->resource.wineD3DDevice->surface_alignment, + This->resource.size = surface_calculate_size(format_desc, This->resource.device->surface_alignment, This->pow2Width, This->pow2Height); This->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0; @@ -797,7 +790,7 @@ static IWineD3DSurfaceImpl *surface_convert_format(IWineD3DSurfaceImpl *source, return NULL; } - IWineD3DDevice_CreateSurface((IWineD3DDevice *)source->resource.wineD3DDevice, source->currentDesc.Width, + IWineD3DDevice_CreateSurface((IWineD3DDevice *)source->resource.device, source->currentDesc.Width, source->currentDesc.Height, to_fmt, TRUE /* lockable */, TRUE /* discard */, 0 /* level */, &ret, 0 /* usage */, WINED3DPOOL_SCRATCH, WINED3DMULTISAMPLE_NONE /* TODO: Multisampled conversion */, 0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source), diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index 7867008d6c1..3f09dc3c130 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -429,7 +429,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD } else { IWineD3DSurfaceImpl *dds_primary; IWineD3DSwapChainImpl *swapchain; - swapchain = (IWineD3DSwapChainImpl *)This->resource.wineD3DDevice->swapchains[0]; + swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0]; dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; @@ -646,7 +646,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl = IWineGDISurfaceImpl_Release, /* IWineD3DResource */ IWineD3DBaseSurfaceImpl_GetParent, - IWineD3DBaseSurfaceImpl_GetDevice, IWineD3DBaseSurfaceImpl_SetPrivateData, IWineD3DBaseSurfaceImpl_GetPrivateData, IWineD3DBaseSurfaceImpl_FreePrivateData, diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index a23166a2219..3e4da780f11 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -33,7 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps); -#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION This->device->adapter->gl_info /*IWineD3DSwapChain parts follow: */ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) @@ -76,7 +76,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) for (i = 0; i < This->num_contexts; ++i) { - context_destroy(This->wineD3DDevice, This->context[i]); + context_destroy(This->device, This->context[i]); } /* Restore the screen resolution if we rendered in fullscreen * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9 @@ -88,28 +88,142 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) mode.Height = This->orig_height; mode.RefreshRate = 0; mode.Format = This->orig_fmt; - IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode); + IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode); } HeapFree(GetProcessHeap(), 0, This->context); HeapFree(GetProcessHeap(), 0, This); } +/* A GL context is provided by the caller */ +static inline void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *context) +{ + RECT window; + IWineD3DDeviceImpl *device = This->device; + IWineD3DSurfaceImpl *backbuffer = ((IWineD3DSurfaceImpl *) This->backBuffer[0]); + UINT w = backbuffer->currentDesc.Width; + UINT h = backbuffer->currentDesc.Height; + GLenum gl_filter; + const struct wined3d_gl_info *gl_info = context->gl_info; + + GetClientRect(This->win_handle, &window); + if(w == window.right && h == window.bottom) gl_filter = GL_NEAREST; + else gl_filter = GL_LINEAR; + + if(gl_info->supported[EXT_FRAMEBUFFER_BLIT]) + { + ENTER_GL(); + context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo); + context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, This->backBuffer[0]); + context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE); + + context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL); + glDrawBuffer(GL_BACK); + + glDisable(GL_SCISSOR_TEST); + IWineD3DDeviceImpl_MarkStateDirty(This->device, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); + + /* Note that the texture is upside down */ + gl_info->fbo_ops.glBlitFramebuffer(0, 0, w, h, + window.left, window.bottom, window.right, window.top, + GL_COLOR_BUFFER_BIT, gl_filter); + checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n"); + LEAVE_GL(); + } + else + { + struct wined3d_context *context2; + float tex_left = 0; + float tex_top = 0; + float tex_right = w; + float tex_bottom = h; + + context2 = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_BLIT); + + if(backbuffer->Flags & SFLAG_NORMCOORD) + { + tex_left /= w; + tex_right /= w; + tex_top /= h; + tex_bottom /= h; + } + + ENTER_GL(); + context_bind_fbo(context2, GL_DRAW_FRAMEBUFFER, NULL); + + /* Set up the texture. The surface is not in a IWineD3D*Texture container, + * so there are no d3d texture settings to dirtify + */ + device->blitter->set_shader((IWineD3DDevice *) device, backbuffer->resource.format_desc, + backbuffer->texture_target, backbuffer->pow2Width, + backbuffer->pow2Height); + glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glDrawBuffer(GL_BACK); + + /* Set the viewport to the destination rectandle, disable any projection + * transformation set up by CTXUSAGE_BLIT, and draw a (-1,-1)-(1,1) quad. + * + * Back up viewport and matrix to avoid breaking last_was_blit + * + * Note that CTXUSAGE_BLIT set up viewport and ortho to match the surface + * size - we want the GL drawable(=window) size. + */ + glPushAttrib(GL_VIEWPORT_BIT); + glViewport(window.left, window.top, window.right, window.bottom); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glBegin(GL_QUADS); + /* bottom left */ + glTexCoord2f(tex_left, tex_bottom); + glVertex2i(-1, -1); + + /* top left */ + glTexCoord2f(tex_left, tex_top); + glVertex2i(-1, 1); + + /* top right */ + glTexCoord2f(tex_right, tex_top); + glVertex2i(1, 1); + + /* bottom right */ + glTexCoord2f(tex_right, tex_bottom); + glVertex2i(1, -1); + glEnd(); + + glPopMatrix(); + glPopAttrib(); + + device->blitter->unset_shader((IWineD3DDevice *) device); + checkGLcall("Swapchain present blit(manual)\n"); + LEAVE_GL(); + + context_release(context2); + } +} + static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; struct wined3d_context *context; unsigned int sync; int retval; - context = context_acquire(This->wineD3DDevice, This->backBuffer[0], CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_RESOURCELOAD); /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */ - if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) { + if (This->device->bCursorVisible && This->device->cursorTexture) + { IWineD3DSurfaceImpl cursor; - RECT destRect = {This->wineD3DDevice->xScreenSpace - This->wineD3DDevice->xHotSpot, - This->wineD3DDevice->yScreenSpace - This->wineD3DDevice->yHotSpot, - This->wineD3DDevice->xScreenSpace + This->wineD3DDevice->cursorWidth - This->wineD3DDevice->xHotSpot, - This->wineD3DDevice->yScreenSpace + This->wineD3DDevice->cursorHeight - This->wineD3DDevice->yHotSpot}; + RECT destRect = + { + This->device->xScreenSpace - This->device->xHotSpot, + This->device->yScreenSpace - This->device->yHotSpot, + This->device->xScreenSpace + This->device->cursorWidth - This->device->xHotSpot, + This->device->yScreenSpace + This->device->cursorHeight - This->device->yHotSpot, + }; TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor); /* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by * the application because we are only supposed to copy the information out. Using a fake surface @@ -118,16 +232,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO memset(&cursor, 0, sizeof(cursor)); cursor.lpVtbl = &IWineD3DSurface_Vtbl; cursor.resource.ref = 1; - cursor.resource.wineD3DDevice = This->wineD3DDevice; + cursor.resource.device = This->device; cursor.resource.pool = WINED3DPOOL_SCRATCH; - cursor.resource.format_desc = - getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->wineD3DDevice->adapter->gl_info); + cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, context->gl_info); cursor.resource.resourceType = WINED3DRTYPE_SURFACE; - cursor.texture_name = This->wineD3DDevice->cursorTexture; + cursor.texture_name = This->device->cursorTexture; cursor.texture_target = GL_TEXTURE_2D; cursor.texture_level = 0; - cursor.currentDesc.Width = This->wineD3DDevice->cursorWidth; - cursor.currentDesc.Height = This->wineD3DDevice->cursorHeight; + cursor.currentDesc.Width = This->device->cursorWidth; + cursor.currentDesc.Height = This->device->cursorHeight; cursor.glRect.left = 0; cursor.glRect.top = 0; cursor.glRect.right = cursor.currentDesc.Width; @@ -146,9 +259,11 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT); } - if(This->wineD3DDevice->logo_surface) { - /* Blit the logo into the upper left corner of the drawable */ - IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->wineD3DDevice->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY); + + if (This->device->logo_surface) + { + /* Blit the logo into the upper left corner of the drawable. */ + IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY); } if (pSourceRect || pDestRect) FIXME("Unhandled present rects %s/%s\n", wine_dbgstr_rect(pSourceRect), wine_dbgstr_rect(pDestRect)); @@ -160,6 +275,50 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride); } + /* Rendering to a window of different size, presenting partial rectangles, + * or rendering to a different window needs help from FBO_blit or a textured + * draw. Render the swapchain to a FBO in the future. + * + * Note that FBO_blit from the backbuffer to the frontbuffer cannot solve + * all these issues - this fails if the window is smaller than the backbuffer. + */ + if(This->presentParms.Windowed && !This->render_to_fbo && + wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + RECT window_size; + GetClientRect(This->win_handle, &window_size); + if(window_size.bottom != This->presentParms.BackBufferHeight || + window_size.right != This->presentParms.BackBufferWidth) + { + TRACE("Window size changed from %ux%u to %ux%u, switching to render-to-fbo mode\n", + This->presentParms.BackBufferWidth, This->presentParms.BackBufferHeight, + window_size.right, window_size.bottom); + + IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL); + IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE); + This->render_to_fbo = TRUE; + + /* Force the context manager to update the render target configuration next draw */ + context->current_rt = NULL; + } + } + + if(This->render_to_fbo) + { + /* This codepath should only be hit with the COPY swapeffect. Otherwise a backbuffer- + * window size mismatch is impossible(fullscreen) and src and dst rectangles are + * not allowed(they need the COPY swapeffect) + * + * The DISCARD swap effect is ok as well since any backbuffer content is allowed after + * the swap + */ + if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP ) + { + FIXME("Render-to-fbo with WINED3DSWAPEFFECT_FLIP\n"); + } + swapchain_blit(This, context); + } + SwapBuffers(This->context[0]->hdc); /* TODO: cycle through the swapchain buffers */ TRACE("SwapBuffers called, Starting new frame\n"); @@ -235,13 +394,16 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO if (FALSE && This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) { TRACE("Clearing the color buffer with cyan color\n"); - IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, + IWineD3DDevice_Clear((IWineD3DDevice *)This->device, 0, NULL, WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0); } - if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM || - ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) { - /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */ + if(!This->render_to_fbo && + ( ((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM || + ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) ) { + /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying + * Doesn't work with render_to_fbo because we're not flipping + */ IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; @@ -272,10 +434,12 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO } } - if (This->wineD3DDevice->stencilBufferTarget) { + if (This->device->stencilBufferTarget) + { if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->wineD3DDevice->stencilBufferTarget)->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->wineD3DDevice->stencilBufferTarget, SFLAG_DS_DISCARDED); + || ((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget)->Flags & SFLAG_DISCARD) + { + surface_modify_ds_location(This->device->stencilBufferTarget, SFLAG_DS_DISCARDED); } } @@ -336,16 +500,19 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapCh if(window == This->win_handle) return WINED3D_OK; TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window); - if(This->context[0] == This->wineD3DDevice->contexts[0]) { + if (This->context[0] == This->device->contexts[0]) + { /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts * and reload the resources */ - delete_opengl_contexts((IWineD3DDevice *) This->wineD3DDevice, iface); - This->win_handle = window; - create_primary_opengl_context((IWineD3DDevice *) This->wineD3DDevice, iface); - } else { - This->win_handle = window; + delete_opengl_contexts((IWineD3DDevice *)This->device, iface); + This->win_handle = window; + create_primary_opengl_context((IWineD3DDevice *)This->device, iface); + } + else + { + This->win_handle = window; /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code @@ -356,8 +523,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapCh memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); IWineD3DSurface_UnlockRect(This->backBuffer[0]); - context_destroy(This->wineD3DDevice, This->context[0]); - This->context[0] = context_create(This->wineD3DDevice, (IWineD3DSurfaceImpl *)This->frontBuffer, + context_destroy(This->device, This->context[0]); + This->context[0] = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer, This->win_handle, FALSE /* pbuffer */, &This->presentParms); context_release(This->context[0]); @@ -369,7 +536,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapCh return WINED3D_OK; } -const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl = +static const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl = { /* IUnknown */ IWineD3DBaseSwapChainImpl_QueryInterface, @@ -390,6 +557,359 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl = IWineD3DBaseSwapChainImpl_GetGammaRamp }; +static LONG fullscreen_style(LONG style) +{ + /* Make sure the window is managed, otherwise we won't get keyboard input. */ + style |= WS_POPUP | WS_SYSMENU; + style &= ~(WS_CAPTION | WS_THICKFRAME); + + return style; +} + +static LONG fullscreen_exstyle(LONG exstyle) +{ + /* Filter out window decorations. */ + exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); + + return exstyle; +} + +void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h) +{ + IWineD3DDeviceImpl *device = swapchain->device; + HWND window = swapchain->win_handle; + LONG style, exstyle; + + TRACE("Setting up window %p for fullscreen mode.\n", window); + + if (device->style || device->exStyle) + { + ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", + window, device->style, device->exStyle); + } + + device->style = GetWindowLongW(window, GWL_STYLE); + device->exStyle = GetWindowLongW(window, GWL_EXSTYLE); + + style = fullscreen_style(device->style); + exstyle = fullscreen_exstyle(device->exStyle); + + TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", + device->style, device->exStyle, style, exstyle); + + SetWindowLongW(window, GWL_STYLE, style); + SetWindowLongW(window, GWL_EXSTYLE, exstyle); + SetWindowPos(window, HWND_TOP, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW); +} + +void swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain) +{ + IWineD3DDeviceImpl *device = swapchain->device; + HWND window = swapchain->win_handle; + LONG style, exstyle; + + if (!device->style && !device->exStyle) return; + + TRACE("Restoring window style of window %p to %08x, %08x.\n", + window, device->style, device->exStyle); + + style = GetWindowLongW(window, GWL_STYLE); + exstyle = GetWindowLongW(window, GWL_EXSTYLE); + + /* Only restore the style if the application didn't modify it during the + * fullscreen phase. Some applications change it before calling Reset() + * when switching between windowed and fullscreen modes (HL2), some + * depend on the original style (Eve Online). */ + if (style == fullscreen_style(device->style) && exstyle == fullscreen_exstyle(device->exStyle)) + { + SetWindowLongW(window, GWL_STYLE, device->style); + SetWindowLongW(window, GWL_EXSTYLE, device->exStyle); + } + + /* Delete the old values. */ + device->style = 0; + device->exStyle = 0; + + SetWindowPos(window, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); +} + + +HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type, + IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) +{ + const struct wined3d_adapter *adapter = device->adapter; + const struct GlPixelFormatDesc *format_desc; + BOOL displaymode_set = FALSE; + WINED3DDISPLAYMODE mode; + RECT client_rect; + HWND window; + HRESULT hr; + UINT i; + + if (present_parameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX) + { + FIXME("The application requested %u back buffers, this is not supported.\n", + present_parameters->BackBufferCount); + return WINED3DERR_INVALIDCALL; + } + + if (present_parameters->BackBufferCount > 1) + { + FIXME("The application requested more than one back buffer, this is not properly supported.\n" + "Please configure the application to use double buffering (1 back buffer) if possible.\n"); + } + + switch (surface_type) + { + case SURFACE_GDI: + swapchain->lpVtbl = &IWineGDISwapChain_Vtbl; + break; + + case SURFACE_OPENGL: + swapchain->lpVtbl = &IWineD3DSwapChain_Vtbl; + break; + + case SURFACE_UNKNOWN: + FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain.\n"); + return WINED3DERR_INVALIDCALL; + } + + window = present_parameters->hDeviceWindow ? present_parameters->hDeviceWindow : device->createParms.hFocusWindow; + + swapchain->device = device; + swapchain->parent = parent; + swapchain->ref = 1; + swapchain->win_handle = window; + + if (!present_parameters->Windowed && window) + { + swapchain_setup_fullscreen_window(swapchain, present_parameters->BackBufferWidth, + present_parameters->BackBufferHeight); + } + + IWineD3D_GetAdapterDisplayMode(device->wined3d, adapter->ordinal, &mode); + swapchain->orig_width = mode.Width; + swapchain->orig_height = mode.Height; + swapchain->orig_fmt = mode.Format; + format_desc = getFormatDescEntry(mode.Format, &adapter->gl_info); + + GetClientRect(window, &client_rect); + if (present_parameters->Windowed + && (!present_parameters->BackBufferWidth || !present_parameters->BackBufferHeight + || present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN)) + { + + if (!present_parameters->BackBufferWidth) + { + present_parameters->BackBufferWidth = client_rect.right; + TRACE("Updating width to %u.\n", present_parameters->BackBufferWidth); + } + + if (!present_parameters->BackBufferHeight) + { + present_parameters->BackBufferHeight = client_rect.bottom; + TRACE("Updating height to %u.\n", present_parameters->BackBufferHeight); + } + + if (present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN) + { + present_parameters->BackBufferFormat = swapchain->orig_fmt; + TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt)); + } + } + swapchain->presentParms = *present_parameters; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && (present_parameters->BackBufferWidth != client_rect.right + || present_parameters->BackBufferHeight != client_rect.bottom)) + { + TRACE("Rendering to FBO. Backbuffer %ux%u, window %ux%u.\n", + present_parameters->BackBufferWidth, + present_parameters->BackBufferHeight, + client_rect.right, client_rect.bottom); + swapchain->render_to_fbo = TRUE; + } + + TRACE("Creating front buffer.\n"); + hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, + swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, + swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, + swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer); + if (FAILED(hr)) + { + WARN("Failed to create front buffer, hr %#x.\n", hr); + goto err; + } + + IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain); + ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; + if (surface_type == SURFACE_OPENGL) + { + IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE); + } + + /* MSDN says we're only allowed a single fullscreen swapchain per device, + * so we should really check to see if there is a fullscreen swapchain + * already. Does a single head count as full screen? */ + + if (!present_parameters->Windowed) + { + WINED3DDISPLAYMODE mode; + + /* Change the display settings */ + mode.Width = present_parameters->BackBufferWidth; + mode.Height = present_parameters->BackBufferHeight; + mode.Format = present_parameters->BackBufferFormat; + mode.RefreshRate = present_parameters->FullScreen_RefreshRateInHz; + + hr = IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)device, 0, &mode); + if (FAILED(hr)) + { + WARN("Failed to set display mode, hr %#x.\n", hr); + goto err; + } + displaymode_set = TRUE; + } + + swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context)); + if (!swapchain->context) + { + ERR("Failed to create the context array.\n"); + hr = E_OUTOFMEMORY; + goto err; + } + swapchain->num_contexts = 1; + + if (surface_type == SURFACE_OPENGL) + { + swapchain->context[0] = context_create(device, (IWineD3DSurfaceImpl *)swapchain->frontBuffer, + window, FALSE /* pbuffer */, present_parameters); + if (!swapchain->context[0]) + { + WARN("Failed to create context.\n"); + hr = WINED3DERR_NOTAVAILABLE; + goto err; + } + + swapchain->context[0]->render_offscreen = swapchain->render_to_fbo; + } + else + { + swapchain->context[0] = NULL; + } + + if (swapchain->presentParms.BackBufferCount > 0) + { + swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0, + sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount); + if (!swapchain->backBuffer) + { + ERR("Failed to allocate backbuffer array memory.\n"); + hr = E_OUTOFMEMORY; + goto err; + } + + for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) + { + TRACE("Creating back buffer %u.\n", i); + hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, + swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, + swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, + swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]); + if (FAILED(hr)) + { + WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); + goto err; + } + + IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain); + ((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; + + if (surface_type == SURFACE_OPENGL) + { + ENTER_GL(); + glDrawBuffer(GL_BACK); + checkGLcall("glDrawBuffer(GL_BACK)"); + LEAVE_GL(); + } + } + } + else + { + /* Single buffering - draw to front buffer */ + if (surface_type == SURFACE_OPENGL) + { + ENTER_GL(); + glDrawBuffer(GL_FRONT); + checkGLcall("glDrawBuffer(GL_FRONT)"); + LEAVE_GL(); + } + } + + if (swapchain->context[0]) context_release(swapchain->context[0]); + + /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */ + if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) + { + TRACE("Creating depth/stencil buffer.\n"); + if (!device->auto_depth_stencil_buffer) + { + hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent, + swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, + swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType, + swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, + &device->auto_depth_stencil_buffer); + if (FAILED(hr)) + { + WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); + goto err; + } + + IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL); + } + } + + IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *)swapchain, &swapchain->orig_gamma); + + return WINED3D_OK; + +err: + if (displaymode_set) + { + DEVMODEW devmode; + + ClipCursor(NULL); + + /* Change the display settings */ + memset(&devmode, 0, sizeof(devmode)); + devmode.dmSize = sizeof(devmode); + devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + devmode.dmBitsPerPel = format_desc->byte_count * 8; + devmode.dmPelsWidth = swapchain->orig_width; + devmode.dmPelsHeight = swapchain->orig_height; + ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); + } + + if (swapchain->backBuffer) + { + for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) + { + if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]); + } + HeapFree(GetProcessHeap(), 0, swapchain->backBuffer); + } + + if (swapchain->context && swapchain->context[0]) + { + context_release(swapchain->context[0]); + context_destroy(device, swapchain->context[0]); + } + + if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer); + + return hr; +} + struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *iface) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface; @@ -398,7 +918,7 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId()); - ctx = context_create(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, + ctx = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer, This->context[0]->win_handle, FALSE /* pbuffer */, &This->presentParms); if (!ctx) { @@ -410,7 +930,7 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * This->num_contexts + 1); if(!newArray) { ERR("Out of memory when trying to allocate a new context array\n"); - context_destroy(This->wineD3DDevice, ctx); + context_destroy(This->device, ctx); return NULL; } memcpy(newArray, This->context, sizeof(*newArray) * This->num_contexts); diff --git a/dlls/wined3d/swapchain_base.c b/dlls/wined3d/swapchain_base.c index 31b9d07ad41..9b51e935e75 100644 --- a/dlls/wined3d/swapchain_base.c +++ b/dlls/wined3d/swapchain_base.c @@ -139,7 +139,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface HRESULT hr; TRACE("(%p)->(%p): Calling GetAdapterDisplayMode\n", This, pMode); - hr = IWineD3D_GetAdapterDisplayMode(This->wineD3DDevice->wineD3D, This->wineD3DDevice->adapter->num, pMode); + hr = IWineD3D_GetAdapterDisplayMode(This->device->wined3d, This->device->adapter->ordinal, pMode); TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format)); @@ -149,7 +149,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; - *ppDevice = (IWineD3DDevice *) This->wineD3DDevice; + *ppDevice = (IWineD3DDevice *)This->device; /* Note Calling this method will increase the internal reference count on the IDirect3DDevice9 interface. */ diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c index f795d89b7cf..c437b419f8e 100644 --- a/dlls/wined3d/swapchain_gdi.c +++ b/dlls/wined3d/swapchain_gdi.c @@ -67,7 +67,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) mode.Height = This->orig_height; mode.RefreshRate = 0; mode.Format = This->orig_fmt; - IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode); + IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode); } HeapFree(GetProcessHeap(), 0, This->context); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index b568005e842..1e272144a8a 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -31,7 +31,7 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG { /* Override the IWineD3DResource PreLoad method. */ IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context = NULL; unsigned int i; BOOL srgb_mode; @@ -171,10 +171,6 @@ static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) { /* **************************************************** IWineD3DTexture IWineD3DResource parts follow **************************************************** */ -static HRESULT WINAPI IWineD3DTextureImpl_GetDevice(IWineD3DTexture *iface, IWineD3DDevice** ppDevice) { - return resource_get_device((IWineD3DResource *)iface, ppDevice); -} - static HRESULT WINAPI IWineD3DTextureImpl_SetPrivateData(IWineD3DTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags); } @@ -405,7 +401,6 @@ static const IWineD3DTextureVtbl IWineD3DTexture_Vtbl = IWineD3DTextureImpl_Release, /* IWineD3DResource */ IWineD3DTextureImpl_GetParent, - IWineD3DTextureImpl_GetDevice, IWineD3DTextureImpl_SetPrivateData, IWineD3DTextureImpl_GetPrivateData, IWineD3DTextureImpl_FreePrivateData, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 1b4516afdf4..c1e921da976 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -2227,7 +2227,7 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { *********************************************************************/ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) { - const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; int x1 = Rect->left, x2 = Rect->right; int y1 = Rect->top, y2 = Rect->bottom; GLint maxSize = gl_info->limits.texture_size; @@ -2386,7 +2386,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting unsigned int i; DWORD ttff; DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; - IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + IWineD3DDeviceImpl *device = stateblock->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; for (i = 0; i < gl_info->limits.texture_stages; ++i) @@ -2703,7 +2703,7 @@ void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD sampler = state - STATE_SAMPLER(0); - DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler]; + DWORD mapped_stage = stateblock->device->texUnitMap[sampler]; /* No need to enable / disable anything here for unused samplers. The tex_colorop * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index 88b3f273eec..0bc141acd8c 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -88,16 +88,6 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDecl return WINED3D_OK; } -static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration *iface, IWineD3DDevice** ppDevice) { - IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; - TRACE("(%p) : returning %p\n", This, This->wineD3DDevice); - - *ppDevice = (IWineD3DDevice *) This->wineD3DDevice; - IWineD3DDevice_AddRef(*ppDevice); - - return WINED3D_OK; -} - static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element) { switch(element->usage) @@ -194,7 +184,6 @@ static const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl = IWineD3DVertexDeclarationImpl_Release, /* IWineD3DVertexDeclaration */ IWineD3DVertexDeclarationImpl_GetParent, - IWineD3DVertexDeclarationImpl_GetDevice, }; HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWineD3DDeviceImpl *device, @@ -217,7 +206,7 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWine declaration->ref = 1; declaration->parent = parent; declaration->parent_ops = parent_ops; - declaration->wineD3DDevice = device; + declaration->device = device; declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count); if (!declaration->elements) { diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 63d8c9b9790..f08fd06f86f 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -194,14 +194,6 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetParent(IWineD3DVertexShader *i return WINED3D_OK; } -static HRESULT WINAPI IWineD3DVertexShaderImpl_GetDevice(IWineD3DVertexShader* iface, IWineD3DDevice **pDevice){ - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; - IWineD3DDevice_AddRef(This->baseShader.device); - *pDevice = This->baseShader.device; - TRACE("(%p) returning %p\n", This, *pDevice); - return WINED3D_OK; -} - static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader* impl, VOID* pData, UINT* pSizeOfData) { IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)impl; TRACE("(%p) : pData(%p), pSizeOfData(%p)\n", This, pData, pSizeOfData); @@ -348,7 +340,6 @@ static const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl = /*** IWineD3DBase methods ***/ IWineD3DVertexShaderImpl_GetParent, /*** IWineD3DBaseShader methods ***/ - IWineD3DVertexShaderImpl_GetDevice, IWineD3DVertexShaderImpl_GetFunction, /*** IWineD3DVertexShader methods ***/ IWIneD3DVertexShaderImpl_SetLocalConstantsF diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index 5a80cb6fd52..fa4cb295891 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -25,12 +25,12 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); -#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info +#define GLINFO_LOCATION This->resource.device->adapter->gl_info /* Context activation is done by the caller. */ static void volume_bind_and_dirtify(IWineD3DVolume *iface) { IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; - const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; IWineD3DVolumeTexture *texture; DWORD active_sampler; @@ -51,14 +51,14 @@ static void volume_bind_and_dirtify(IWineD3DVolume *iface) { ENTER_GL(); glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); LEAVE_GL(); - active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB]; + active_sampler = This->resource.device->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB]; } else { active_sampler = 0; } if (active_sampler != WINED3D_UNMAPPED_STAGE) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler)); + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_SAMPLER(active_sampler)); } if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DVolumeTexture, (void **)&texture))) { @@ -138,10 +138,6 @@ static HRESULT WINAPI IWineD3DVolumeImpl_GetParent(IWineD3DVolume *iface, IUnkno return resource_get_parent((IWineD3DResource *)iface, pParent); } -static HRESULT WINAPI IWineD3DVolumeImpl_GetDevice(IWineD3DVolume *iface, IWineD3DDevice** ppDevice) { - return resource_get_device((IWineD3DResource *)iface, ppDevice); -} - static HRESULT WINAPI IWineD3DVolumeImpl_SetPrivateData(IWineD3DVolume *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags); } @@ -361,7 +357,6 @@ static const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl = IWineD3DVolumeImpl_Release, /* IWineD3DResource */ IWineD3DVolumeImpl_GetParent, - IWineD3DVolumeImpl_GetDevice, IWineD3DVolumeImpl_SetPrivateData, IWineD3DVolumeImpl_GetPrivateData, IWineD3DVolumeImpl_FreePrivateData, diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c index 4cea3a01638..e666e2cbccc 100644 --- a/dlls/wined3d/volumetexture.c +++ b/dlls/wined3d/volumetexture.c @@ -30,7 +30,7 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE { /* Override the IWineD3DResource Preload method. */ IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; + IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context = NULL; BOOL srgb_mode = This->baseTexture.is_srgb; @@ -139,10 +139,6 @@ static ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *ifa /* **************************************************** IWineD3DVolumeTexture IWineD3DResource parts follow **************************************************** */ -static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetDevice(IWineD3DVolumeTexture *iface, IWineD3DDevice** ppDevice) { - return resource_get_device((IWineD3DResource *)iface, ppDevice); -} - static HRESULT WINAPI IWineD3DVolumeTextureImpl_SetPrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags); } @@ -322,7 +318,6 @@ static const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = IWineD3DVolumeTextureImpl_Release, /* resource */ IWineD3DVolumeTextureImpl_GetParent, - IWineD3DVolumeTextureImpl_GetDevice, IWineD3DVolumeTextureImpl_SetPrivateData, IWineD3DVolumeTextureImpl_GetPrivateData, IWineD3DVolumeTextureImpl_FreePrivateData, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 39519a10788..e0b4ab1b14b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -26,6 +26,7 @@ #include #include +#include #define NONAMELESSUNION #define NONAMELESSSTRUCT #define COBJMACROS @@ -1186,6 +1187,7 @@ struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN; DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN; void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN; BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; +void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN; void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN; @@ -1324,7 +1326,7 @@ struct wined3d_driver_info /* The adapter structure */ struct wined3d_adapter { - UINT num; + UINT ordinal; BOOL opengl; POINT monitorPoint; struct wined3d_gl_info gl_info; @@ -1459,7 +1461,7 @@ struct IWineD3DDeviceImpl /* WineD3D Information */ IUnknown *parent; IWineD3DDeviceParent *device_parent; - IWineD3D *wineD3D; + IWineD3D *wined3d; struct wined3d_adapter *adapter; /* Window styles to restore when switching fullscreen mode */ @@ -1513,7 +1515,6 @@ struct IWineD3DDeviceImpl /* Internal use fields */ WINED3DDEVICE_CREATION_PARAMETERS createParms; - UINT adapterNo; WINED3DDEVTYPE devType; IWineD3DSwapChain **swapchains; @@ -1597,6 +1598,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN; void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) DECLSPEC_HIDDEN; void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) DECLSPEC_HIDDEN; + static inline BOOL isStateDirty(struct wined3d_context *context, DWORD state) { DWORD idx = state >> 5; @@ -1632,7 +1634,7 @@ typedef struct IWineD3DResourceClass /* WineD3DResource Information */ IUnknown *parent; WINED3DRESOURCETYPE resourceType; - IWineD3DDeviceImpl *wineD3DDevice; + IWineD3DDeviceImpl *device; WINED3DPOOL pool; UINT size; DWORD usage; @@ -1654,7 +1656,6 @@ typedef struct IWineD3DResourceImpl void resource_cleanup(IWineD3DResource *iface) DECLSPEC_HIDDEN; HRESULT resource_free_private_data(IWineD3DResource *iface, REFGUID guid) DECLSPEC_HIDDEN; -HRESULT resource_get_device(IWineD3DResource *iface, IWineD3DDevice **device) DECLSPEC_HIDDEN; HRESULT resource_get_parent(IWineD3DResource *iface, IUnknown **parent) DECLSPEC_HIDDEN; DWORD resource_get_priority(IWineD3DResource *iface) DECLSPEC_HIDDEN; HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid, @@ -1726,6 +1727,8 @@ typedef struct IWineD3DBaseTextureClass } IWineD3DBaseTextureClass; void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; +BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN; +BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN; typedef struct IWineD3DBaseTextureImpl { @@ -1973,7 +1976,6 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj) DECLSPEC_HIDDEN; ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent) DECLSPEC_HIDDEN; -HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, const void *pData, DWORD SizeOfData, DWORD Flags) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, @@ -2134,7 +2136,7 @@ typedef struct IWineD3DVertexDeclarationImpl { IUnknown *parent; const struct wined3d_parent_ops *parent_ops; - IWineD3DDeviceImpl *wineD3DDevice; + IWineD3DDeviceImpl *device; struct wined3d_vertex_declaration_element *elements; UINT element_count; @@ -2194,7 +2196,7 @@ struct IWineD3DStateBlockImpl LONG ref; /* Note: Ref counting not required */ /* IWineD3DStateBlock information */ - IWineD3DDeviceImpl *wineD3DDevice; + IWineD3DDeviceImpl *device; WINED3DSTATEBLOCKTYPE blockType; /* Array indicating whether things have been set or changed */ @@ -2314,7 +2316,7 @@ typedef struct IWineD3DQueryImpl LONG ref; /* Note: Ref counting not required */ IUnknown *parent; - IWineD3DDeviceImpl *wineD3DDevice; + IWineD3DDeviceImpl *device; /* IWineD3DQuery fields */ enum query_state state; @@ -2402,7 +2404,7 @@ typedef struct IWineD3DSwapChainImpl LONG ref; /* Note: Ref counting not required */ IUnknown *parent; - IWineD3DDeviceImpl *wineD3DDevice; + IWineD3DDeviceImpl *device; /* IWineD3DSwapChain fields */ IWineD3DSurface **backBuffer; @@ -2411,6 +2413,7 @@ typedef struct IWineD3DSwapChainImpl DWORD orig_width, orig_height; WINED3DFORMAT orig_fmt; WINED3DGAMMARAMP orig_gamma; + BOOL render_to_fbo; long prev_time, frames; /* Performance tracking */ unsigned int vSyncCounter; @@ -2421,7 +2424,6 @@ typedef struct IWineD3DSwapChainImpl HWND win_handle; } IWineD3DSwapChainImpl; -extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl DECLSPEC_HIDDEN; const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN; void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) DECLSPEC_HIDDEN; @@ -2448,6 +2450,10 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp) DECLSPEC_HIDDEN; struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *iface) DECLSPEC_HIDDEN; +HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type, + IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) DECLSPEC_HIDDEN; +void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h) DECLSPEC_HIDDEN; +void swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain) DECLSPEC_HIDDEN; #define DEFAULT_REFRESH_RATE 0 @@ -2790,7 +2796,7 @@ struct IWineD3DPaletteImpl { LONG ref; IUnknown *parent; - IWineD3DDeviceImpl *wineD3DDevice; + IWineD3DDeviceImpl *device; /* IWineD3DPalette */ HPALETTE hpal; @@ -2866,13 +2872,12 @@ static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock) * style strided data. */ return (stateblock->vertexShader && !((IWineD3DVertexDeclarationImpl *)stateblock->vertexDecl)->position_transformed - && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE); + && stateblock->device->vs_selected_mode != SHADER_NONE); } static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock) { - return (stateblock->pixelShader - && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE); + return (stateblock->pixelShader && stateblock->device->ps_selected_mode != SHADER_NONE); } void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, diff --git a/dlls/wineps.drv/builtin.c b/dlls/wineps.drv/builtin.c index c8c3f9b4c30..e0a3951b03e 100644 --- a/dlls/wineps.drv/builtin.c +++ b/dlls/wineps.drv/builtin.c @@ -27,6 +27,7 @@ #include "winbase.h" #include "winerror.h" #include "wingdi.h" +#include "winnls.h" #include "psdrv.h" #include "wine/debug.h" diff --git a/dlls/wineps.drv/download.c b/dlls/wineps.drv/download.c index e794af60f86..82b70b40258 100644 --- a/dlls/wineps.drv/download.c +++ b/dlls/wineps.drv/download.c @@ -26,6 +26,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winnls.h" #include "psdrv.h" #include "wine/debug.h" diff --git a/dlls/wineps.drv/driver.c b/dlls/wineps.drv/driver.c index 378f4feaa7a..fa077752a43 100644 --- a/dlls/wineps.drv/driver.c +++ b/dlls/wineps.drv/driver.c @@ -33,6 +33,7 @@ #include "psdrv.h" #include "winuser.h" +#include "wine/wingdi16.h" #include "wownt32.h" #include "prsht.h" #include "psdlg.h" diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c index c594bea6aa3..1062b96fafc 100644 --- a/dlls/wineps.drv/escape.c +++ b/dlls/wineps.drv/escape.c @@ -17,13 +17,26 @@ * 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 +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif #include "windef.h" #include "winbase.h" #include "wingdi.h" #include "wine/wingdi16.h" -#include "wownt32.h" +#include "winreg.h" #include "psdrv.h" #include "wine/debug.h" #include "winspool.h" @@ -33,6 +46,111 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv); static const char psbegindocument[] = "%%BeginDocument: Wine passthrough\n"; +/* FIXME: should use winspool functions instead */ +static DWORD create_job(LPCSTR pszOutput) +{ + int fd = -1; + char psCmd[1024]; + const char *psCmdP = psCmd; + HKEY hkey; + + /* TTD convert the 'output device' into a spool file name */ + + if (pszOutput == NULL || *pszOutput == '\0') return 0; + + psCmd[0] = 0; + /* @@ Wine registry key: HKCU\Software\Wine\Printing\Spooler */ + if(!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Printing\\Spooler", &hkey)) + { + DWORD type, count = sizeof(psCmd); + RegQueryValueExA(hkey, pszOutput, 0, &type, (LPBYTE)psCmd, &count); + RegCloseKey(hkey); + } + if (!psCmd[0] && !strncmp("LPR:",pszOutput,4)) + sprintf(psCmd,"|lpr -P'%s'",pszOutput+4); + + TRACE("Got printerSpoolCommand '%s' for output device '%s'\n", + psCmd, pszOutput); + if (!*psCmd) + psCmdP = pszOutput; + else + { + while (*psCmdP && isspace(*psCmdP)) + { + psCmdP++; + } + if (!*psCmdP) return 0; + } + TRACE("command: '%s'\n", psCmdP); +#ifdef HAVE_FORK + if (*psCmdP == '|') + { + int fds[2]; + if (pipe(fds)) { + ERR("pipe() failed!\n"); + return 0; + } + if (fork() == 0) + { + psCmdP++; + + TRACE("In child need to exec %s\n",psCmdP); + close(0); + dup2(fds[0],0); + close (fds[1]); + + /* reset signals that we previously set to SIG_IGN */ + signal( SIGPIPE, SIG_DFL ); + signal( SIGCHLD, SIG_DFL ); + + execl("/bin/sh", "/bin/sh", "-c", psCmdP, NULL); + _exit(1); + + } + close (fds[0]); + fd = fds[1]; + TRACE("Need to execute a cmnd and pipe the output to it\n"); + } + else +#endif + { + char *buffer; + WCHAR psCmdPW[MAX_PATH]; + + TRACE("Just assume it's a file\n"); + + /** + * The file name can be dos based, we have to find its + * corresponding Unix file name. + */ + MultiByteToWideChar(CP_ACP, 0, psCmdP, -1, psCmdPW, MAX_PATH); + if ((buffer = wine_get_unix_file_name(psCmdPW))) + { + if ((fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0) + { + ERR("Failed to create spool file '%s' ('%s'). (error %s)\n", + buffer, psCmdP, strerror(errno)); + } + HeapFree(GetProcessHeap(), 0, buffer); + } + } + return fd + 1; +} + +static int close_job( DWORD id ) +{ + int fd = id - 1; + close( fd ); + return TRUE; +} + +DWORD write_spool( PSDRV_PDEVICE *physDev, const void *data, DWORD num ) +{ + int fd = physDev->job.id - 1; + if (write( fd, data, num) != num) return SP_OUTOFDISK; + return num; +} + /********************************************************************** * ExtEscape (WINEPS.@) */ @@ -252,10 +370,10 @@ INT CDECL PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPC * in_data[0] instead. */ if(!physDev->job.in_passthrough) { - WriteSpool16(physDev->job.hJob, (LPSTR)psbegindocument, sizeof(psbegindocument)-1); + write_spool(physDev, psbegindocument, sizeof(psbegindocument)-1); physDev->job.in_passthrough = TRUE; } - return WriteSpool16(physDev->job.hJob,((char*)in_data)+2,*(const WORD*)in_data); + return write_spool(physDev,((char*)in_data)+2,*(const WORD*)in_data); } case POSTSCRIPT_IGNORE: @@ -388,7 +506,7 @@ static INT PSDRV_StartDocA( PSDRV_PDEVICE *physDev, const DOCINFOA *doc ) PRINTER_INFO_5A *pi5 = (PRINTER_INFO_5A*)buf; DWORD needed; - if(physDev->job.hJob) { + if(physDev->job.id) { FIXME("hJob != 0. Now what?\n"); return 0; } @@ -406,8 +524,8 @@ static INT PSDRV_StartDocA( PSDRV_PDEVICE *physDev, const DOCINFOA *doc ) ClosePrinter(hprn); } - physDev->job.hJob = OpenJob16(output, doc->lpszDocName, HDC_16(physDev->hdc) ); - if(!physDev->job.hJob) { + physDev->job.id = create_job( output ); + if(!physDev->job.id) { WARN("OpenJob failed\n"); return 0; } @@ -423,7 +541,7 @@ static INT PSDRV_StartDocA( PSDRV_PDEVICE *physDev, const DOCINFOA *doc ) } else physDev->job.DocName = NULL; - return physDev->job.hJob; + return physDev->job.id; } /************************************************************************ @@ -474,7 +592,7 @@ INT CDECL PSDRV_StartDoc( PSDRV_PDEVICE *physDev, const DOCINFOW *doc ) INT CDECL PSDRV_EndDoc( PSDRV_PDEVICE *physDev ) { INT ret = 1; - if(!physDev->job.hJob) { + if(!physDev->job.id) { FIXME("hJob == 0. Now what?\n"); return 0; } @@ -485,11 +603,8 @@ INT CDECL PSDRV_EndDoc( PSDRV_PDEVICE *physDev ) } PSDRV_WriteFooter( physDev ); - if( CloseJob16( physDev->job.hJob ) == SP_ERROR ) { - WARN("CloseJob error\n"); - ret = 0; - } - physDev->job.hJob = 0; + ret = close_job( physDev->job.id ); + physDev->job.id = 0; HeapFree(GetProcessHeap(), 0, physDev->job.DocName); physDev->job.DocName = NULL; diff --git a/dlls/wineps.drv/font.c b/dlls/wineps.drv/font.c index 7f54954f1df..d66c5e678d2 100644 --- a/dlls/wineps.drv/font.c +++ b/dlls/wineps.drv/font.c @@ -25,6 +25,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winnls.h" #include "winspool.h" #include "psdrv.h" diff --git a/dlls/wineps.drv/graphics.c b/dlls/wineps.drv/graphics.c index 657599bf283..e9c66d2e3e9 100644 --- a/dlls/wineps.drv/graphics.c +++ b/dlls/wineps.drv/graphics.c @@ -129,7 +129,7 @@ BOOL CDECL PSDRV_Rectangle( PSDRV_PDEVICE *physDev, INT left, INT top, INT right if(physDev->job.in_passthrough && !physDev->job.had_passthrough_rect && GetROP2(physDev->hdc) == R2_NOP) { char buf[256]; sprintf(buf, "N %d %d %d %d B\n", rect.right - rect.left, rect.bottom - rect.top, rect.left, rect.top); - WriteSpool16(physDev->job.hJob, buf, strlen(buf)); + write_spool(physDev, buf, strlen(buf)); physDev->job.had_passthrough_rect = TRUE; return TRUE; } diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 152ee03c975..ef5d9d82340 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -38,8 +38,10 @@ #include "winbase.h" #include "winerror.h" #include "winreg.h" +#include "winnls.h" #include "psdrv.h" #include "winspool.h" +#include "wine/library.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(psdrv); @@ -365,7 +367,7 @@ BOOL CDECL PSDRV_CreateDC( HDC hdc, PSDRV_PDEVICE **pdev, LPCWSTR driver, LPCWST WideCharToMultiByte( CP_ACP, 0, output, -1, physDev->job.output, len, NULL, NULL ); } else physDev->job.output = NULL; - physDev->job.hJob = 0; + physDev->job.id = 0; if(initData) { DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, initData); diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c index 372b373c510..89728fd0429 100644 --- a/dlls/wineps.drv/ps.c +++ b/dlls/wineps.drv/ps.c @@ -196,7 +196,7 @@ DWORD PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPCSTR lpData, DWORD cch) } if(physDev->job.in_passthrough) { /* Was in PASSTHROUGH mode */ - WriteSpool16( physDev->job.hJob, (LPSTR)psenddocument, sizeof(psenddocument)-1 ); + write_spool( physDev, psenddocument, sizeof(psenddocument)-1 ); physDev->job.in_passthrough = physDev->job.had_passthrough_rect = FALSE; } @@ -207,7 +207,7 @@ DWORD PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPCSTR lpData, DWORD cch) do { num = min(num_left, 0x8000); - if(WriteSpool16( physDev->job.hJob, (LPSTR)lpData, num ) != num) + if(write_spool( physDev, lpData, num ) != num) return 0; lpData += num; num_left -= num; @@ -217,19 +217,16 @@ DWORD PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPCSTR lpData, DWORD cch) } -static INT PSDRV_WriteFeature(HANDLE16 hJob, LPCSTR feature, LPCSTR value, LPSTR invocation) +static INT PSDRV_WriteFeature(PSDRV_PDEVICE *physDev, LPCSTR feature, LPCSTR value, LPCSTR invocation) { char *buf = HeapAlloc( PSDRV_Heap, 0, sizeof(psbeginfeature) + strlen(feature) + strlen(value)); - sprintf(buf, psbeginfeature, feature, value); - WriteSpool16( hJob, buf, strlen(buf) ); - - WriteSpool16( hJob, invocation, strlen(invocation) ); - - WriteSpool16( hJob, (LPSTR)psendfeature, strlen(psendfeature) ); + write_spool( physDev, buf, strlen(buf) ); + write_spool( physDev, invocation, strlen(invocation) ); + write_spool( physDev, psendfeature, strlen(psendfeature) ); HeapFree( PSDRV_Heap, 0, buf ); return 1; @@ -321,30 +318,28 @@ INT PSDRV_WriteHeader( PSDRV_PDEVICE *physDev, LPCSTR title ) sprintf(buf, psheader, escaped_title, llx, lly, urx, ury); HeapFree(GetProcessHeap(), 0, escaped_title); - if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) != - strlen(buf) ) { + if( write_spool( physDev, buf, strlen(buf) ) != strlen(buf) ) { WARN("WriteSpool error\n"); HeapFree( PSDRV_Heap, 0, buf ); return 0; } HeapFree( PSDRV_Heap, 0, buf ); - WriteSpool16( physDev->job.hJob, (LPSTR)psbeginprolog, strlen(psbeginprolog) ); - WriteSpool16( physDev->job.hJob, (LPSTR)psprolog, strlen(psprolog) ); - WriteSpool16( physDev->job.hJob, (LPSTR)psendprolog, strlen(psendprolog) ); - - WriteSpool16( physDev->job.hJob, (LPSTR)psbeginsetup, strlen(psbeginsetup) ); + write_spool( physDev, psbeginprolog, strlen(psbeginprolog) ); + write_spool( physDev, psprolog, strlen(psprolog) ); + write_spool( physDev, psendprolog, strlen(psendprolog) ); + write_spool( physDev, psbeginsetup, strlen(psbeginsetup) ); if(physDev->Devmode->dmPublic.u1.s1.dmCopies > 1) { char copies_buf[100]; sprintf(copies_buf, "mark {\n << /NumCopies %d >> setpagedevice\n} stopped cleartomark\n", physDev->Devmode->dmPublic.u1.s1.dmCopies); - WriteSpool16(physDev->job.hJob, copies_buf, strlen(copies_buf)); + write_spool(physDev, copies_buf, strlen(copies_buf)); } for(slot = physDev->pi->ppd->InputSlots; slot; slot = slot->next) { if(slot->WinBin == physDev->Devmode->dmPublic.u1.s1.dmDefaultSource) { if(slot->InvocationString) { - PSDRV_WriteFeature(physDev->job.hJob, "*InputSlot", slot->Name, + PSDRV_WriteFeature(physDev, "*InputSlot", slot->Name, slot->InvocationString); break; } @@ -354,7 +349,7 @@ INT PSDRV_WriteHeader( PSDRV_PDEVICE *physDev, LPCSTR title ) LIST_FOR_EACH_ENTRY(page, &physDev->pi->ppd->PageSizes, PAGESIZE, entry) { if(page->WinPage == physDev->Devmode->dmPublic.u1.s1.dmPaperSize) { if(page->InvocationString) { - PSDRV_WriteFeature(physDev->job.hJob, "*PageSize", page->Name, + PSDRV_WriteFeature(physDev, "*PageSize", page->Name, page->InvocationString); break; } @@ -366,14 +361,14 @@ INT PSDRV_WriteHeader( PSDRV_PDEVICE *physDev, LPCSTR title ) for(duplex = physDev->pi->ppd->Duplexes; duplex; duplex = duplex->next) { if(duplex->WinDuplex == win_duplex) { if(duplex->InvocationString) { - PSDRV_WriteFeature(physDev->job.hJob, "*Duplex", duplex->Name, + PSDRV_WriteFeature(physDev, "*Duplex", duplex->Name, duplex->InvocationString); break; } } } - WriteSpool16( physDev->job.hJob, (LPSTR)psendsetup, strlen(psendsetup) ); + write_spool( physDev, psendsetup, strlen(psendsetup) ); return 1; @@ -392,8 +387,7 @@ INT PSDRV_WriteFooter( PSDRV_PDEVICE *physDev ) sprintf(buf, psfooter, physDev->job.PageNo); - if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) != - strlen(buf) ) { + if( write_spool( physDev, buf, strlen(buf) ) != strlen(buf) ) { WARN("WriteSpool error\n"); HeapFree( PSDRV_Heap, 0, buf ); return 0; @@ -406,8 +400,7 @@ INT PSDRV_WriteFooter( PSDRV_PDEVICE *physDev ) INT PSDRV_WriteEndPage( PSDRV_PDEVICE *physDev ) { - if( WriteSpool16( physDev->job.hJob, (LPSTR)psendpage, sizeof(psendpage)-1 ) != - sizeof(psendpage)-1 ) { + if( write_spool( physDev, psendpage, sizeof(psendpage)-1 ) != sizeof(psendpage)-1 ) { WARN("WriteSpool error\n"); return 0; } @@ -451,8 +444,7 @@ INT PSDRV_WriteNewPage( PSDRV_PDEVICE *physDev ) physDev->logPixelsX, physDev->logPixelsY, xtrans, ytrans, rotation); - if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) != - strlen(buf) ) { + if( write_spool( physDev, buf, strlen(buf) ) != strlen(buf) ) { WARN("WriteSpool error\n"); HeapFree( PSDRV_Heap, 0, buf ); return 0; diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index c9a4a4e9612..9b2ec5096f0 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -26,7 +26,6 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" -#include "wine/wingdi16.h" #include "winspool.h" #include "wine/list.h" @@ -335,7 +334,7 @@ typedef struct { } PSPEN; typedef struct { - HANDLE16 hJob; + DWORD id; /* Job id */ LPSTR output; /* Output file/port */ LPSTR DocName; /* Document Name */ BOOL banding; /* Have we received a NEXTBAND */ @@ -492,6 +491,8 @@ extern BOOL PSDRV_WriteDownloadGlyphShow(PSDRV_PDEVICE *physDev, WORD *glpyhs, UINT count); extern BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev, BOOL write_undef); +extern DWORD write_spool( PSDRV_PDEVICE *physDev, const void *data, DWORD num ); + #define MAX_G_NAME 31 /* max length of PS glyph name */ extern void get_glyph_name(HDC hdc, WORD index, char *name); diff --git a/dlls/wineps.drv/text.c b/dlls/wineps.drv/text.c index 310e1cb39e5..8ed788866e3 100644 --- a/dlls/wineps.drv/text.c +++ b/dlls/wineps.drv/text.c @@ -47,7 +47,7 @@ BOOL CDECL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y, flags, debugstr_wn(str, count), count, lpDx); - if(physDev->job.hJob == 0) return FALSE; + if(physDev->job.id == 0) return FALSE; /* write font if not already written */ PSDRV_SetFont(physDev); diff --git a/dlls/wineps.drv/truetype.c b/dlls/wineps.drv/truetype.c index 59ebe19d6bd..36ee404ead1 100644 --- a/dlls/wineps.drv/truetype.c +++ b/dlls/wineps.drv/truetype.c @@ -67,7 +67,9 @@ #include "winbase.h" #include "winerror.h" #include "winreg.h" +#include "winnls.h" #include "psdrv.h" +#include "wine/library.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(psdrv); diff --git a/dlls/wineps.drv/type1afm.c b/dlls/wineps.drv/type1afm.c index 4feee711b38..e7248c40296 100644 --- a/dlls/wineps.drv/type1afm.c +++ b/dlls/wineps.drv/type1afm.c @@ -47,6 +47,7 @@ #include "winbase.h" #include "winerror.h" #include "winreg.h" +#include "winnls.h" #include "psdrv.h" #include "wine/debug.h" diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index aadb7f13b62..38f1dad02df 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -368,7 +368,7 @@ static BOOL X11DRV_WineGL_InitOpenglInfo(void) /* In general indirect rendering on a local X11 server indicates a driver problem. * Detect a local X11 server by checking whether the X11 socket is a Unix socket. */ - if(!getsockname(fd, &uaddr, &uaddrlen) && uaddr.sun_family == AF_UNIX) + if(!getsockname(fd, (struct sockaddr *)&uaddr, &uaddrlen) && uaddr.sun_family == AF_UNIX) ERR_(winediag)("Direct rendering is disabled, most likely your OpenGL drivers haven't been installed correctly\n"); } diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 3600cd0f850..3bd934b3e06 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -56,6 +56,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv); WINE_DECLARE_DEBUG_CHANNEL(synchronous); +WINE_DECLARE_DEBUG_CHANNEL(winediag); static CRITICAL_SECTION X11DRV_CritSection; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -643,8 +644,7 @@ struct x11drv_thread_data *x11drv_init_thread_data(void) if (!(data->display = XOpenDisplay(NULL))) { wine_tsx11_unlock(); - MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) ); - MESSAGE( "Please ensure that your X server is running and that $DISPLAY is set correctly.\n" ); + ERR_(winediag)( "x11drv: Can't open display: %s. Please ensure that your X server is running and that $DISPLAY is set correctly.\n", XDisplayName(NULL)); ExitProcess(1); } diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 3ed3b1b5e01..034b229d909 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -42,6 +42,8 @@ #undef DSA #endif +#define NONAMELESSUNION + #include "wine/debug.h" #include "wine/library.h" @@ -115,15 +117,18 @@ MAKE_FUNCPTR( SSL_get_verify_result ); MAKE_FUNCPTR( SSL_get_peer_certificate ); MAKE_FUNCPTR( SSL_CTX_set_default_verify_paths ); MAKE_FUNCPTR( SSL_CTX_set_verify ); -MAKE_FUNCPTR( X509_STORE_CTX_get_ex_data ); MAKE_FUNCPTR( BIO_new_fp ); MAKE_FUNCPTR( CRYPTO_num_locks ); MAKE_FUNCPTR( CRYPTO_set_id_callback ); MAKE_FUNCPTR( CRYPTO_set_locking_callback ); +MAKE_FUNCPTR( ERR_free_strings ); MAKE_FUNCPTR( ERR_get_error ); MAKE_FUNCPTR( ERR_error_string ); +MAKE_FUNCPTR( X509_STORE_CTX_get_ex_data ); MAKE_FUNCPTR( i2d_X509 ); +MAKE_FUNCPTR( sk_value ); +MAKE_FUNCPTR( sk_num ); #undef MAKE_FUNCPTR static CRITICAL_SECTION *ssl_locks; @@ -291,7 +296,7 @@ static BOOL netconn_verify_cert( PCCERT_CONTEXT cert, HCERTSTORE store, SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslExtraPolicyPara; CERT_CHAIN_POLICY_STATUS policyStatus; - sslExtraPolicyPara.cbSize = sizeof(sslExtraPolicyPara); + sslExtraPolicyPara.u.cbSize = sizeof(sslExtraPolicyPara); sslExtraPolicyPara.dwAuthType = AUTHTYPE_SERVER; sslExtraPolicyPara.pwszServerName = server; policyPara.cbSize = sizeof(policyPara); @@ -339,11 +344,11 @@ static int netconn_secure_verify( int preverify_ok, X509_STORE_CTX *ctx ) PCCERT_CONTEXT endCert = NULL; ret = TRUE; - for (i = 0; ret && i < ctx->chain->num; i++) + for (i = 0; ret && i < psk_num((struct stack_st *)ctx->chain); i++) { PCCERT_CONTEXT context; - cert = (X509 *)ctx->chain->data[i]; + cert = (X509 *)psk_value((struct stack_st *)ctx->chain, i); if ((context = X509_to_cert_context( cert ))) { if (i == 0) @@ -355,6 +360,7 @@ static int netconn_secure_verify( int preverify_ok, X509_STORE_CTX *ctx ) CertFreeCertificateContext( context ); } } + if (!endCert) ret = FALSE; if (ret) ret = netconn_verify_cert( endCert, store, server ); CertFreeCertificateContext( endCert ); @@ -423,7 +429,6 @@ BOOL netconn_init( netconn_t *conn, BOOL secure ) LOAD_FUNCPTR( SSL_get_peer_certificate ); LOAD_FUNCPTR( SSL_CTX_set_default_verify_paths ); LOAD_FUNCPTR( SSL_CTX_set_verify ); - LOAD_FUNCPTR( X509_STORE_CTX_get_ex_data ); #undef LOAD_FUNCPTR #define LOAD_FUNCPTR(x) \ @@ -438,9 +443,13 @@ BOOL netconn_init( netconn_t *conn, BOOL secure ) LOAD_FUNCPTR( CRYPTO_num_locks ); LOAD_FUNCPTR( CRYPTO_set_id_callback ); LOAD_FUNCPTR( CRYPTO_set_locking_callback ); + LOAD_FUNCPTR( ERR_free_strings ); LOAD_FUNCPTR( ERR_get_error ); LOAD_FUNCPTR( ERR_error_string ); + LOAD_FUNCPTR( X509_STORE_CTX_get_ex_data ); LOAD_FUNCPTR( i2d_X509 ); + LOAD_FUNCPTR( sk_value ); + LOAD_FUNCPTR( sk_num ); #undef LOAD_FUNCPTR pSSL_library_init(); @@ -492,6 +501,7 @@ void netconn_unload( void ) #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) if (libcrypto_handle) { + pERR_free_strings(); wine_dlclose( libcrypto_handle, NULL, 0 ); } if (libssl_handle) diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index fe9bb051d74..342dde2b87b 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -787,7 +787,8 @@ static void test_secure_connection(void) size = sizeof(cert); ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size ); ok(ret, "failed to retrieve certificate context %u\n", GetLastError()); - CertFreeCertificateContext(cert); + if (ret) + CertFreeCertificateContext(cert); size = sizeof(bitness); ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size ); @@ -1000,9 +1001,16 @@ static void test_set_default_proxy_config(void) info.lpszProxy = normalString; SetLastError(0xdeadbeef); ret = WinHttpSetDefaultProxyConfiguration(&info); - ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n", GetLastError()); - - set_default_proxy_reg_value( saved_proxy_settings, len, type ); + if (ret) + { + ok(ret, "always true\n"); + set_default_proxy_reg_value( saved_proxy_settings, len, type ); + } + else if (GetLastError() == ERROR_ACCESS_DENIED) + skip("couldn't set default proxy configuration: access denied\n"); + else + ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n", + GetLastError()); } START_TEST (winhttp) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 024d5d816df..19f854d8463 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1967,6 +1967,7 @@ static DWORD read_gzip_data(http_request_t *req, BYTE *buf, int size, BOOL sync, zstream->avail_out = size-read; zres = inflate(zstream, Z_FULL_FLUSH); read = size - zstream->avail_out; + req->dwContentRead += req->read_size-zstream->avail_in; remove_data(req, req->read_size-zstream->avail_in); if(zres == Z_STREAM_END) { TRACE("end of data\n"); @@ -2086,9 +2087,9 @@ static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD * } finished_reading = !bytes_read && req->dwContentRead == req->dwContentLength; + req->dwContentRead += bytes_read; } done: - req->dwContentRead += bytes_read; *read = bytes_read; TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, req->dwContentRead, req->dwContentLength ); @@ -2953,7 +2954,7 @@ BOOL WINAPI HttpQueryInfoW(HINTERNET hHttpRequest, DWORD dwInfoLevel, DWORD info = dwInfoLevel & HTTP_QUERY_HEADER_MASK; DWORD i; - TRACE("(%p, 0x%08x)--> %d\n", hHttpRequest, dwInfoLevel, dwInfoLevel); + TRACE("(%p, 0x%08x)--> %d\n", hHttpRequest, dwInfoLevel, info); TRACE(" Attribute:"); for (i = 0; i < (sizeof(query_flags) / sizeof(query_flags[0])); i++) { if (query_flags[i].val == info) { @@ -3638,6 +3639,9 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, b = CreateUrlCacheEntryW(url, lpwhr->dwContentLength > 0 ? lpwhr->dwContentLength : 0, NULL, cacheFileName, 0); if(b) { + HeapFree(GetProcessHeap(), 0, lpwhr->lpszCacheFile); + CloseHandle(lpwhr->hCacheFile); + lpwhr->lpszCacheFile = heap_strdupW(cacheFileName); lpwhr->hCacheFile = CreateFileW(lpwhr->lpszCacheFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); @@ -4794,7 +4798,7 @@ static INT HTTP_GetCustomHeaderIndex(http_request_t *lpwhr, LPCWSTR lpszField, { DWORD index; - TRACE("%s\n", debugstr_w(lpszField)); + TRACE("%s, %d, %d\n", debugstr_w(lpszField), requested_index, request_only); for (index = 0; index < lpwhr->nCustHeaders; index++) { diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 8a3340cdb0f..d749e53bc0a 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -1550,7 +1550,7 @@ BOOL WINAPI InternetCrackUrlW(LPCWSTR lpszUrl_orig, DWORD dwUrlLength_orig, DWOR } /* If the scheme is "file" and the host is just one letter, it's not a host */ - if(lpUC->nScheme==INTERNET_SCHEME_FILE && (lpszPort-lpszHost)==1) + if(lpUC->nScheme==INTERNET_SCHEME_FILE && lpszPort <= lpszHost+1) { lpszcp=lpszHost; SetUrlComponentValueW(&lpUC->lpszHostName, &lpUC->dwHostNameLength, @@ -1603,7 +1603,7 @@ BOOL WINAPI InternetCrackUrlW(LPCWSTR lpszUrl_orig, DWORD dwUrlLength_orig, DWOR * :[//][/path][;][?][#] * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ - if (lpszcp != 0 && lpszcp - lpszUrl < dwUrlLength && (!lpszParam || lpszcp < lpszParam)) + if (lpszcp != 0 && lpszcp - lpszUrl < dwUrlLength && (!lpszParam || lpszcp <= lpszParam)) { INT len; diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c index 37c71dafd57..d152601b965 100644 --- a/dlls/wininet/tests/ftp.c +++ b/dlls/wininet/tests/ftp.c @@ -438,7 +438,7 @@ static void test_openfile(HINTERNET hFtp, HINTERNET hConnect) bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef"); error = GetLastError(); ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n"); - ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS, + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); trace_extended_error(error); @@ -446,22 +446,24 @@ static void test_openfile(HINTERNET hFtp, HINTERNET hConnect) bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef"); error = GetLastError(); ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n"); - ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS, + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); trace_extended_error(error); SetLastError(0xdeadbeef); bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0); - ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + error = GetLastError(); + ok ( bRet == FALSE || broken(bRet == TRUE), "Expected FtpGetFileA to fail\n"); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_SUCCESS), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */ SetLastError(0xdeadbeef); hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0); - ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + error = GetLastError(); + ok ( bRet == FALSE || broken(bRet == TRUE), "Expected FtpOpenFileA to fail\n"); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_SUCCESS), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); InternetCloseHandle(hOpenFile2); /* Just in case */ /* Create a temporary local file */ @@ -471,22 +473,25 @@ static void test_openfile(HINTERNET hFtp, HINTERNET hConnect) CloseHandle(hFile); SetLastError(0xdeadbeef); bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); DeleteFileA("now_existing_local"); SetLastError(0xdeadbeef); bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir"); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); SetLastError(0xdeadbeef); bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new"); + error = GetLastError(); ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n"); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError()); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error); } InternetCloseHandle(hOpenFile); @@ -748,6 +753,7 @@ static void test_find_first_file(HINTERNET hFtp, HINTERNET hConnect) HINTERNET hSearch; HINTERNET hSearch2; HINTERNET hOpenFile; + DWORD error; /* NULL as the search file ought to return the first file in the directory */ SetLastError(0xdeadbeef); @@ -793,9 +799,10 @@ static void test_find_first_file(HINTERNET hFtp, HINTERNET hConnect) /* This should fail as the OpenFile handle wasn't closed */ SetLastError(0xdeadbeef); hSearch = FtpFindFirstFileA(hFtp, "welcome.msg", &findData, 0, 0); + error = GetLastError(); ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" ); - ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS, - "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError() ); + ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR), + "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error ); InternetCloseHandle(hSearch); /* Just in case */ InternetCloseHandle(hOpenFile); diff --git a/dlls/wininet/tests/url.c b/dlls/wininet/tests/url.c index 18df3924337..7439cd38e47 100644 --- a/dlls/wininet/tests/url.c +++ b/dlls/wininet/tests/url.c @@ -31,14 +31,6 @@ #include "wine/test.h" #define TEST_URL "http://www.winehq.org/site/about#hi" -#define TEST_URL_HOST "www.winehq.org" -#define TEST_URL_PATH "/site/about" -#define TEST_URL_HASH "#hi" -#define TEST_URL2 "http://www.myserver.com/myscript.php?arg=1" -#define TEST_URL2_SERVER "www.myserver.com" -#define TEST_URL2_PATH "/myscript.php" -#define TEST_URL2_PATHEXTRA "/myscript.php?arg=1" -#define TEST_URL2_EXTRA "?arg=1" #define TEST_URL3 "file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml" #define CREATE_URL1 "http://username:password@www.winehq.org/site/about" @@ -95,6 +87,107 @@ static void zero_compsA( SetLastError(0xfaceabad); } +typedef struct { + const char *url; + int scheme_off; + int scheme_len; + INTERNET_SCHEME scheme; + int host_off; + int host_len; + int host_skip_broken; + INTERNET_PORT port; + int user_off; + int user_len; + int pass_off; + int pass_len; + int path_off; + int path_len; + int extra_off; + int extra_len; +} crack_url_test_t; + +static const crack_url_test_t crack_url_tests[] = { + {"http://www.winehq.org/site/about#hi", + 0, 4, INTERNET_SCHEME_HTTP, 7, 14, -1, 80, -1, 0, -1, 0, 21, 11, 32, 3}, + {"http://www.myserver.com/myscript.php?arg=1", + 0, 4, INTERNET_SCHEME_HTTP, 7, 16, -1, 80, -1, 0, -1, 0, 23, 13, 36, 6}, + {"http://www.winehq.org?test=123", + 0, 4, INTERNET_SCHEME_HTTP, 7, 14, 23, 80, -1, 0, -1, 0, 21, 0, 21, 9}, + {"file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", + 0, 4, INTERNET_SCHEME_FILE, -1, 0, -1, 0, -1, 0, -1, 0, 7, 55, -1, 0}, + {"fide:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", + 0, 4, INTERNET_SCHEME_UNKNOWN, 7, 0, -1, 0, -1, 0, -1, 0, 7, 55, -1, 0}, + {"file://C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml", + 0, 4, INTERNET_SCHEME_FILE, -1, 0, -1, 0, -1, 0, -1, 0, 7, 54, -1, 0}, +}; + +static void test_crack_url(const crack_url_test_t *test) +{ + URL_COMPONENTSA url; + BOOL b; + + zero_compsA(&url, 1, 1, 1, 1, 1, 1); + + b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url); + ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); + + if(test->scheme_off == -1) + ok(!url.lpszScheme, "[%s] url.lpszScheme = %p, expected NULL\n", test->url, url.lpszScheme); + else + ok(url.lpszScheme == test->url+test->scheme_off, "[%s] url.lpszScheme = %p, expected %p\n", + test->url, url.lpszScheme, test->url+test->scheme_off); + ok(url.dwSchemeLength == test->scheme_len, "[%s] url.lpszSchemeLength = %d, expected %d\n", + test->url, url.dwSchemeLength, test->scheme_len); + + ok(url.nScheme == test->scheme, "[%s] url.nScheme = %d, expected %d\n", test->url, url.nScheme, test->scheme); + + if(test->host_off == -1) + ok(!url.lpszHostName, "[%s] url.lpszHostName = %p, expected NULL\n", test->url, url.lpszHostName); + else + ok(url.lpszHostName == test->url+test->host_off, "[%s] url.lpszHostName = %p, expected %p\n", + test->url, url.lpszHostName, test->url+test->host_off); + if(test->host_skip_broken != -1 && url.dwHostNameLength == test->host_skip_broken) { + win_skip("skipping broken dwHostNameLength result\n"); + return; + } + ok(url.dwHostNameLength == test->host_len, "[%s] url.lpszHostNameLength = %d, expected %d\n", + test->url, url.dwHostNameLength, test->host_len); + + ok(url.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, url.nPort, test->port); + + if(test->user_off == -1) + ok(!url.lpszUserName, "[%s] url.lpszUserName = %p\n", test->url, url.lpszUserName); + else + ok(url.lpszUserName == test->url+test->user_off, "[%s] url.lpszUserName = %p, expected %p\n", + test->url, url.lpszUserName, test->url+test->user_off); + ok(url.dwUserNameLength == test->user_len, "[%s] url.lpszUserNameLength = %d, expected %d\n", + test->url, url.dwUserNameLength, test->user_len); + + if(test->pass_off == -1) + ok(!url.lpszPassword, "[%s] url.lpszPassword = %p\n", test->url, url.lpszPassword); + else + ok(url.lpszPassword == test->url+test->pass_off, "[%s] url.lpszPassword = %p, expected %p\n", + test->url, url.lpszPassword, test->url+test->pass_off); + ok(url.dwPasswordLength == test->pass_len, "[%s] url.lpszPasswordLength = %d, expected %d\n", + test->url, url.dwPasswordLength, test->pass_len); + + if(test->path_off == -1) + ok(!url.lpszUrlPath, "[%s] url.lpszPath = %p, expected NULL\n", test->url, url.lpszUrlPath); + else + ok(url.lpszUrlPath == test->url+test->path_off, "[%s] url.lpszPath = %p, expected %p\n", + test->url, url.lpszUrlPath, test->url+test->path_off); + ok(url.dwUrlPathLength == test->path_len, "[%s] url.lpszUrlPathLength = %d, expected %d\n", + test->url, url.dwUrlPathLength, test->path_len); + + if(test->extra_off == -1) + ok(!url.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, url.lpszExtraInfo); + else + ok(url.lpszExtraInfo == test->url+test->extra_off, "[%s] url.lpszExtraInfo = %p, expected %p\n", + test->url, url.lpszExtraInfo, test->url+test->extra_off); + ok(url.dwExtraInfoLength == test->extra_len, "[%s] url.lpszExtraInfoLength = %d, expected %d\n", + test->url, url.dwExtraInfoLength, test->extra_len); +} + static void InternetCrackUrl_test(void) { URL_COMPONENTSA urlSrc, urlComponents; @@ -112,51 +205,6 @@ static void InternetCrackUrl_test(void) urlSrc.lpszUrlPath = path; urlSrc.lpszExtraInfo = extra; - copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024); - ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents); - ok( ret, "InternetCrackUrl failed, error %d\n",GetLastError()); - ok((strcmp(TEST_URL_PATH,path) == 0),"path cracked wrong\n"); - - /* Bug 1805: Confirm the returned lengths are correct: */ - /* 1. When extra info split out explicitly */ - zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 1); - ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed, error %d\n", GetLastError()); - ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATH),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATH), urlComponents.dwUrlPathLength); - ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATH,strlen(TEST_URL2_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATH, urlComponents.lpszUrlPath); - ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength); - ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName); - ok(urlComponents.dwExtraInfoLength == strlen(TEST_URL2_EXTRA),".dwExtraInfoLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_EXTRA), urlComponents.dwExtraInfoLength); - ok(!strncmp(urlComponents.lpszExtraInfo,TEST_URL2_EXTRA,strlen(TEST_URL2_EXTRA)),"lpszExtraInfo should be %s but is %s\n", TEST_URL2_EXTRA, urlComponents.lpszHostName); - - /* 2. When extra info is not split out explicitly and is in url path */ - zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 0); - ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError()); - ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATHEXTRA),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATHEXTRA), urlComponents.dwUrlPathLength); - ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATHEXTRA,strlen(TEST_URL2_PATHEXTRA)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATHEXTRA, urlComponents.lpszUrlPath); - ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength); - ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName); - ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort); - ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme); - - zero_compsA(&urlComponents, 1, 1, 1, 1, 1, 1); - ok(InternetCrackUrlA(TEST_URL, strlen(TEST_URL), 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError()); - ok(urlComponents.dwUrlPathLength == strlen(TEST_URL_PATH),".dwUrlPathLength should be %d, but is %d\n", lstrlenA(TEST_URL_PATH), urlComponents.dwUrlPathLength); - ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL_PATH,strlen(TEST_URL_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL_PATH, urlComponents.lpszUrlPath); - ok(urlComponents.dwHostNameLength == strlen(TEST_URL_HOST),".dwHostNameLength should be %d, but is %d\n", lstrlenA(TEST_URL_HOST), urlComponents.dwHostNameLength); - ok(!strncmp(urlComponents.lpszHostName,TEST_URL_HOST,strlen(TEST_URL_HOST)),"lpszHostName should be %s but is %s\n", TEST_URL_HOST, urlComponents.lpszHostName); - ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort); - ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme); - ok(!urlComponents.lpszUserName, ".lpszUserName should have been set to NULL\n"); - ok(!urlComponents.lpszPassword, ".lpszPassword should have been set to NULL\n"); - ok(urlComponents.dwExtraInfoLength == strlen(TEST_URL_HASH),".dwExtraInfoLength should be %d, but is %d\n", lstrlenA(TEST_URL_HASH), urlComponents.dwExtraInfoLength); - ok(!strncmp(urlComponents.lpszExtraInfo,TEST_URL_HASH,strlen(TEST_URL_HASH)), ".lpszExtraInfo should be %s but is %s\n", TEST_URL_HASH, urlComponents.lpszExtraInfo); - ok(!urlComponents.dwUserNameLength,".dwUserNameLength should be 0, but is %d\n", urlComponents.dwUserNameLength); - ok(!urlComponents.dwPasswordLength,".dwPasswordLength should be 0, but is %d\n", urlComponents.dwPasswordLength); - - /*3. Check for %20 */ - copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024); - ok(InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError()); - /* Tests for lpsz* members pointing to real strings while * some corresponding length members are set to zero. * As of IE7 (wininet 7.0*?) all members are checked. So we @@ -811,6 +859,11 @@ static void InternetCreateUrlA_test(void) START_TEST(url) { + int i; + + for(i=0; i < sizeof(crack_url_tests)/sizeof(*crack_url_tests); i++) + test_crack_url(crack_url_tests+i); + InternetCrackUrl_test(); InternetCrackUrlW_test(); InternetCreateUrlA_test(); diff --git a/dlls/winspool.drv/tests/info.c b/dlls/winspool.drv/tests/info.c index ef726f4a1c1..1f876b3be65 100644 --- a/dlls/winspool.drv/tests/info.c +++ b/dlls/winspool.drv/tests/info.c @@ -2412,7 +2412,8 @@ static void test_DEVMODE(const DEVMODE *dm, LONG dmSize, LPCSTR exp_prn_name) We skip the Tests on this Platform */ if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) { /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */ - ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1), + ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1) || + !strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -2), /* XP+ */ "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName); ok(dm->dmSize + dm->dmDriverExtra == dmSize, "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize); diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c index d9fa5633562..c41a56b1d1a 100644 --- a/dlls/wintrust/crypt.c +++ b/dlls/wintrust/crypt.c @@ -1028,7 +1028,18 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo, /* app hasn't passed buffer, just get the length */ ret = ImageGetCertificateHeader(pSubjectInfo->hFile, dwIndex, &cert); if (ret) - *pcbSignedDataMsg = cert.dwLength; + { + switch (cert.wCertificateType) + { + case WIN_CERT_TYPE_X509: + case WIN_CERT_TYPE_PKCS_SIGNED_DATA: + *pcbSignedDataMsg = cert.dwLength; + break; + default: + WARN("unknown certificate type %d\n", cert.wCertificateType); + ret = FALSE; + } + } } else { @@ -1065,9 +1076,10 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo, *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; break; default: - FIXME("don't know what to do for encoding type %d\n", + WARN("don't know what to do for encoding type %d\n", pCert->wCertificateType); *pdwEncodingType = 0; + ret = FALSE; } } } diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index df9c37d5047..e6668b93038 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -166,6 +166,7 @@ #endif WINE_DEFAULT_DEBUG_CHANNEL(winsock); +WINE_DECLARE_DEBUG_CHANNEL(winediag); /* critical section to protect some non-reentrant net function */ static CRITICAL_SECTION csWSgetXXXbyYYY; @@ -277,10 +278,18 @@ struct per_thread_data int pe_len; }; +/* internal: routing description information */ +struct route { + struct in_addr addr; + DWORD interface; + DWORD metric; +}; + static INT num_startup; /* reference counter */ static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook; /* function prototypes */ +static struct WS_hostent *WS_create_he(char *name, int aliases, int addresses, int fill_addresses); static struct WS_hostent *WS_dup_he(const struct hostent* p_he); static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe); static struct WS_servent *WS_dup_se(const struct servent* p_se); @@ -3547,6 +3556,128 @@ struct WS_hostent* WINAPI WS_gethostbyaddr(const char *addr, int len, int type) } /*********************************************************************** + * WS_get_local_ips (INTERNAL) + * + * Returns the list of local IP addresses by going through the network + * adapters and using the local routing table to sort the addresses + * from highest routing priority to lowest routing priority. This + * functionality is inferred from the description for obtaining local + * IP addresses given in the Knowledge Base Article Q160215. + * + * Please note that the returned hostent is only freed when the thread + * closes and is replaced if another hostent is requested. + */ +static struct WS_hostent* WS_get_local_ips( char *hostname ) +{ + int last_metric, numroutes = 0, i, j; + PIP_ADAPTER_INFO adapters = NULL, k; + struct WS_hostent *hostlist = NULL; + PMIB_IPFORWARDTABLE routes = NULL; + struct route *route_addrs = NULL; + DWORD adap_size, route_size; + + /* Obtain the size of the adapter list and routing table, also allocate memory */ + if (GetAdaptersInfo(NULL, &adap_size) != ERROR_BUFFER_OVERFLOW) + return NULL; + if (GetIpForwardTable(NULL, &route_size, FALSE) != ERROR_INSUFFICIENT_BUFFER) + return NULL; + adapters = HeapAlloc(GetProcessHeap(), 0, adap_size); + routes = HeapAlloc(GetProcessHeap(), 0, route_size); + route_addrs = HeapAlloc(GetProcessHeap(), 0, 0); /* HeapReAlloc doesn't work on NULL */ + if (adapters == NULL || routes == NULL || route_addrs == NULL) + goto cleanup; + /* Obtain the adapter list and the full routing table */ + if (GetAdaptersInfo(adapters, &adap_size) != NO_ERROR) + goto cleanup; + if (GetIpForwardTable(routes, &route_size, FALSE) != NO_ERROR) + goto cleanup; + /* Store the interface associated with each route */ + for (i = 0; i < routes->dwNumEntries; i++) + { + DWORD ifindex, ifmetric, exists = FALSE; + + if (routes->table[i].dwForwardType != MIB_IPROUTE_TYPE_DIRECT) + continue; + ifindex = routes->table[i].dwForwardIfIndex; + ifmetric = routes->table[i].dwForwardMetric1; + /* Only store the lowest valued metric for an interface */ + for (j = 0; j < numroutes; j++) + { + if (route_addrs[j].interface == ifindex) + { + if (route_addrs[j].metric > ifmetric) + route_addrs[j].metric = ifmetric; + exists = TRUE; + } + } + if (exists) + continue; + route_addrs = HeapReAlloc(GetProcessHeap(), 0, route_addrs, (numroutes+1)*sizeof(struct route)); + if (route_addrs == NULL) + goto cleanup; /* Memory allocation error, fail gracefully */ + route_addrs[numroutes].interface = ifindex; + route_addrs[numroutes].metric = ifmetric; + /* If no IP is found in the next step (for whatever reason) + * then fall back to the magic loopback address. + */ + memcpy(&(route_addrs[numroutes].addr.s_addr), magic_loopback_addr, 4); + numroutes++; + } + if (numroutes == 0) + goto cleanup; /* No routes, fall back to the Magic IP */ + /* Find the IP address associated with each found interface */ + for (i = 0; i < numroutes; i++) + { + for (k = adapters; k != NULL; k = k->Next) + { + char *ip = k->IpAddressList.IpAddress.String; + + if (route_addrs[i].interface == k->Index) + route_addrs[i].addr.s_addr = (in_addr_t) inet_addr(ip); + } + } + /* Allocate a hostent and enough memory for all the IPs, + * including the NULL at the end of the list. + */ + hostlist = WS_create_he(hostname, 0, numroutes, TRUE); + hostlist->h_addrtype = AF_INET; + hostlist->h_length = sizeof(struct in_addr); /* = 4 */ + /* Reorder the entries when placing them in the host list, Windows expects + * the IP list in order from highest priority to lowest (the critical thing + * is that most applications expect the first IP to be the default route). + */ + last_metric = -1; + for (i = 0; i < numroutes; i++) + { + struct in_addr addr; + int metric = 0xFFFF; + + memcpy(&addr, magic_loopback_addr, 4); + for (j = 0; j < numroutes; j++) + { + int this_metric = route_addrs[j].metric; + + if (this_metric > last_metric && this_metric < metric) + { + addr = route_addrs[j].addr; + metric = this_metric; + } + } + last_metric = metric; + (*(struct in_addr *) hostlist->h_addr_list[i]) = addr; + } + + /* Cleanup all allocated memory except the address list, + * the address list is used by the calling app. + */ +cleanup: + HeapFree(GetProcessHeap(), 0, route_addrs); + HeapFree(GetProcessHeap(), 0, adapters); + HeapFree(GetProcessHeap(), 0, routes); + return hostlist; +} + +/*********************************************************************** * gethostbyname (WS2_32.52) */ struct WS_hostent* WINAPI WS_gethostbyname(const char* name) @@ -3559,35 +3690,44 @@ struct WS_hostent* WINAPI WS_gethostbyname(const char* name) struct hostent hostentry; int locerr = ENOBUFS; #endif - char buf[100]; - if( !name || !name[0]) { - name = buf; - if( gethostname( buf, 100) == -1) { - SetLastError( WSAENOBUFS); /* appropriate ? */ - return retval; - } + char hostname[100]; + if( gethostname( hostname, 100) == -1) { + SetLastError( WSAENOBUFS); /* appropriate ? */ + return retval; } + if( !name || !name[0]) { + name = hostname; + } + /* If the hostname of the local machine is requested then return the + * complete list of local IP addresses */ + if(strcmp(name, hostname) == 0) + retval = WS_get_local_ips(hostname); + /* If any other hostname was requested (or the routing table lookup failed) + * then return the IP found by the host OS */ + if(retval == NULL) + { #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 - host = NULL; - extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ; - while(extrabuf) { - int res = gethostbyname_r(name, &hostentry, extrabuf, ebufsize, &host, &locerr); - if( res != ERANGE) break; - ebufsize *=2; - extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ; - } - if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr)); + host = NULL; + extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ; + while(extrabuf) { + int res = gethostbyname_r(name, &hostentry, extrabuf, ebufsize, &host, &locerr); + if( res != ERANGE) break; + ebufsize *=2; + extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ; + } + if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr)); #else - EnterCriticalSection( &csWSgetXXXbyYYY ); - host = gethostbyname(name); - if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno)); + EnterCriticalSection( &csWSgetXXXbyYYY ); + host = gethostbyname(name); + if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno)); #endif - if (host) retval = WS_dup_he(host); + if (host) retval = WS_dup_he(host); #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 - HeapFree(GetProcessHeap(),0,extrabuf); + HeapFree(GetProcessHeap(),0,extrabuf); #else - LeaveCriticalSection( &csWSgetXXXbyYYY ); + LeaveCriticalSection( &csWSgetXXXbyYYY ); #endif + } if (retval && retval->h_addr_list[0][0] == 127 && strcmp(name, "localhost") != 0) { @@ -4322,11 +4462,9 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, if (GetLastError() == WSAEACCES) /* raw socket denied */ { if (type == SOCK_RAW) - MESSAGE("WARNING: Trying to create a socket of type SOCK_RAW, this" - " will fail unless you have special permissions.\n"); + ERR_(winediag)("Failed to create a socket of type SOCK_RAW, this requires special permissions.\n"); else - MESSAGE("WS_SOCKET: Failed to create socket, this requires" - " special permissions.\n"); + ERR_(winediag)("Failed to create socket, this requires special permissions.\n"); SetLastError(WSAESOCKTNOSUPPORT); } @@ -4460,33 +4598,78 @@ static int list_dup(char** l_src, char** l_to, int item_size) /* ----- hostent */ -/* duplicate hostent entry - * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*. - * Ditto for protoent and servent. +/* create a hostent entry + * + * Creates the entry with enough memory for the name, aliases + * addresses, and the address pointers. Also copies the name + * and sets up all the pointers. If "fill_address" is set then + * sufficient memory for the addresses is also allocated and the + * address pointers are set to this memory. */ -static struct WS_hostent *WS_dup_he(const struct hostent* p_he) +static struct WS_hostent *WS_create_he(char *name, int aliases, int addresses, int fill_addresses) { - char *p; struct WS_hostent *p_to; + char *p; + + int size = (sizeof(struct WS_hostent) + + strlen(name) + 1 + + sizeof(char *)*aliases + + sizeof(char *)*addresses); - int size = (sizeof(*p_he) + - strlen(p_he->h_name) + 1 + - list_size(p_he->h_aliases, 0) + - list_size(p_he->h_addr_list, p_he->h_length)); + /* Place addresses in the allocated memory, making sure to have enough + * room for the NULL at the end of the list. + */ + if (fill_addresses) + size += sizeof(struct in_addr)*(addresses+1); if (!(p_to = check_buffer_he(size))) return NULL; - p_to->h_addrtype = p_he->h_addrtype; - p_to->h_length = p_he->h_length; + memset(p_to, 0, size); p = (char *)(p_to + 1); p_to->h_name = p; - strcpy(p, p_he->h_name); + strcpy(p, name); p += strlen(p) + 1; - p_to->h_aliases = (char **)p; - p += list_dup(p_he->h_aliases, p_to->h_aliases, 0); + if (aliases != 0) + { + p_to->h_aliases = (char **)p; + p += sizeof(char *)*aliases; + } + if (addresses != 0) + { + p_to->h_addr_list = (char **)p; + p += sizeof(char *)*addresses; + } + if (fill_addresses) + { + int i; + + /* Fill in the list of address pointers and NULL-terminate the list*/ + for (i = 0; i < addresses; i++) + p_to->h_addr_list[i] = (p += sizeof(struct in_addr)); + p_to->h_addr_list[i] = NULL; + p += sizeof(struct in_addr); + } + return p_to; +} + +/* duplicate hostent entry + * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*. + * Ditto for protoent and servent. + */ +static struct WS_hostent *WS_dup_he(const struct hostent* p_he) +{ + int addresses = list_size(p_he->h_addr_list, p_he->h_length); + int aliases = list_size(p_he->h_aliases, 0); + struct WS_hostent *p_to; + + p_to = WS_create_he(p_he->h_name, aliases, addresses, FALSE); + + if (!p_to) return NULL; + p_to->h_addrtype = p_he->h_addrtype; + p_to->h_length = p_he->h_length; - p_to->h_addr_list = (char **)p; + list_dup(p_he->h_aliases, p_to->h_aliases, 0); list_dup(p_he->h_addr_list, p_to->h_addr_list, p_he->h_length); return p_to; } diff --git a/dlls/xinput1_3/xinput1_3_main.c b/dlls/xinput1_3/xinput1_3_main.c index f4386b891f8..fc55cef37b7 100644 --- a/dlls/xinput1_3/xinput1_3_main.c +++ b/dlls/xinput1_3/xinput1_3_main.c @@ -105,7 +105,7 @@ DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPA DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid) { - FIXME("(%d %s %s) Stub!\n", dwUserIndex, debugstr_guid(pDSoundRenderGuid), debugstr_guid(pDSoundCaptureGuid)); + FIXME("(%d %p %p) Stub!\n", dwUserIndex, pDSoundRenderGuid, pDSoundCaptureGuid); if (dwUserIndex < XUSER_MAX_COUNT) { diff --git a/include/Makefile.in b/include/Makefile.in index 0bc1864cd64..b640428b6c4 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -45,6 +45,7 @@ PUBLIC_IDL_H_SRCS = \ mimeinfo.idl \ mimeole.idl \ mlang.idl \ + mmdeviceapi.idl \ mmstream.idl \ mscoree.idl \ msctf.idl \ diff --git a/include/audiopolicy.idl b/include/audiopolicy.idl index 2344f91e85a..1221a54acbb 100644 --- a/include/audiopolicy.idl +++ b/include/audiopolicy.idl @@ -181,7 +181,7 @@ interface IAudioVolumeDuckNotification : IUnknown [in] LPCWSTR sessionID, [in] UINT32 countCommunicationSessions ); - HRESULT OnVolumeUndockNotification( + HRESULT OnVolumeUnduckNotification( [in] LPCWSTR sessionID ); }; diff --git a/include/dbs.idl b/include/dbs.idl index 8b3bb0dd46c..a2ed6567496 100644 --- a/include/dbs.idl +++ b/include/dbs.idl @@ -183,6 +183,11 @@ enum DBSTATUSENUM DBSTATUS_S_DEFAULT = 13 }; +cpp_quote("DEFINE_GUID(DBGUID_SESSION, 0xc8b522f5, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);") +cpp_quote("DEFINE_GUID(DBGUID_ROWSET, 0xc8b522f6, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);") +cpp_quote("DEFINE_GUID(DBGUID_ROW, 0xc8b522f7, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);") +cpp_quote("DEFINE_GUID(DBGUID_STREAM, 0xc8b522f9, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);") + typedef struct tagDBCOLUMNACCESS { void *pData; diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index df0ad5dd488..3bc7238c04a 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1040,6 +1040,7 @@ void WINAPI ExFreePool(PVOID); void WINAPI ExFreePoolWithTag(PVOID,ULONG); NTSTATUS WINAPI IoAllocateDriverObjectExtension(PDRIVER_OBJECT,PVOID,ULONG,PVOID*); +PVOID WINAPI IoAllocateErrorLogEntry(PVOID,UCHAR); PIRP WINAPI IoAllocateIrp(CCHAR,BOOLEAN); NTSTATUS WINAPI IoCreateDevice(DRIVER_OBJECT*,ULONG,UNICODE_STRING*,DEVICE_TYPE,ULONG,BOOLEAN,DEVICE_OBJECT**); NTSTATUS WINAPI IoCreateDriver(UNICODE_STRING*,PDRIVER_INITIALIZE); diff --git a/include/devicetopology.idl b/include/devicetopology.idl index d373b2a96a5..4dc182b2567 100644 --- a/include/devicetopology.idl +++ b/include/devicetopology.idl @@ -31,7 +31,10 @@ import "oaidl.idl"; import "ocidl.idl"; import "propidl.idl"; +cpp_quote("#ifndef E_NOTFOUND") cpp_quote("#define E_NOTFOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND)") +cpp_quote("#endif") + cpp_quote("#define DEVTOPO_HARDWARE_INITIATED_EVENTCONTEXT 'draH'") cpp_quote("DEFINE_GUID(EVENTCONTEXT_VOLUMESLIDER, 0xe2c2e9de, 0x09b1, 0x4b04,0x84,0xe5, 0x07, 0x93, 0x12, 0x25, 0xee, 0x04);") diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 563ee96a101..cd97a70332e 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -45,6 +45,7 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap*,INT,INT,ARGB*); GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap*,GDIPCONST GpRect*,UINT, PixelFormat,BitmapData*); GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap*,INT,INT,ARGB); +GpStatus WINGDIPAPI GdipBitmapSetResolution(GpBitmap*,REAL,REAL); GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap*,BitmapData*); GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL,REAL,REAL,REAL,PixelFormat,GpBitmap*,GpBitmap**); GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT,INT,INT,INT,PixelFormat,GpBitmap*,GpBitmap**); @@ -62,12 +63,19 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromStreamICM(IStream*,GpBitmap**); GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap*,HBITMAP*,ARGB); GpStatus WINGDIPAPI GdipCreateHICONFromBitmap(GpBitmap*,HICON*); GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect*); +GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect*,const VOID*,const UINT); /* Brush */ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush*,GpBrush**); GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush*); GpStatus WINGDIPAPI GdipGetBrushType(GpBrush*,GpBrushType*); +/* CachedBitmap */ +GpStatus WINGDIPAPI GdipCreateCachedBitmap(GpBitmap*,GpGraphics*, + GpCachedBitmap**); +GpStatus WINGDIPAPI GdipDeleteCachedBitmap(GpCachedBitmap*); +GpStatus WINGDIPAPI GdipDrawCachedBitmap(GpGraphics*,GpCachedBitmap*,INT,INT); + /* CustomLineCap */ GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap*,GpCustomLineCap**); GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath*,GpPath*,GpLineCap,REAL, @@ -82,6 +90,7 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap*,GpLineCap, GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap*,GpLineJoin*); GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap*,GpLineJoin); GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap*,REAL*); +GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap*,REAL); GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap*,REAL); /* Font */ @@ -225,6 +234,8 @@ GpStatus WINGDIPAPI GdipGetCompositingQuality(GpGraphics*,CompositingQuality*); GpStatus WINGDIPAPI GdipGetDC(GpGraphics*,HDC*); GpStatus WINGDIPAPI GdipGetDpiX(GpGraphics*,REAL*); GpStatus WINGDIPAPI GdipGetDpiY(GpGraphics*,REAL*); +GpStatus WINGDIPAPI GdipGetImageDecoders(UINT,UINT,ImageCodecInfo*); +GpStatus WINGDIPAPI GdipGetImageDecodersSize(UINT*,UINT*); GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage*,GpGraphics**); GpStatus WINGDIPAPI GdipGetInterpolationMode(GpGraphics*,InterpolationMode*); GpStatus WINGDIPAPI GdipGetNearestColor(GpGraphics*,ARGB*); @@ -251,6 +262,10 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics*,GDIPCONST UINT16*,INT, GpStatus WINGDIPAPI GdipMeasureString(GpGraphics*,GDIPCONST WCHAR*,INT, GDIPCONST GpFont*,GDIPCONST RectF*,GDIPCONST GpStringFormat*,RectF*,INT*,INT*); GpStatus WINGDIPAPI GdipMultiplyWorldTransform(GpGraphics*,GDIPCONST GpMatrix*,GpMatrixOrder); +GpStatus WINGDIPAPI GdipRecordMetafileFileName(GDIPCONST WCHAR*,HDC,EmfType, + GDIPCONST GpRectF*,MetafileFrameUnit,GDIPCONST WCHAR*,GpMetafile**); +GpStatus WINGDIPAPI GdipRecordMetafileFileNameI(GDIPCONST WCHAR*,HDC,EmfType, + GDIPCONST GpRect*,MetafileFrameUnit,GDIPCONST WCHAR*,GpMetafile**); GpStatus WINGDIPAPI GdipRecordMetafileI(HDC,EmfType,GDIPCONST GpRect*, MetafileFrameUnit,GDIPCONST WCHAR*,GpMetafile**); GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics*,HDC); @@ -375,6 +390,7 @@ GpStatus WINGDIPAPI GdipGetImageHeight(GpImage*,UINT*); GpStatus WINGDIPAPI GdipGetImageHorizontalResolution(GpImage*,REAL*); GpStatus WINGDIPAPI GdipGetImageItemData(GpImage*,ImageItemData*); GpStatus WINGDIPAPI GdipGetImagePalette(GpImage*,ColorPalette*,INT); +GpStatus WINGDIPAPI GdipGetImagePaletteSize(GpImage*,INT*); GpStatus WINGDIPAPI GdipGetImagePixelFormat(GpImage*,PixelFormat*); GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage*,GUID*); GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage*,UINT,UINT,GpImage**,GetThumbnailImageAbort,VOID*); @@ -386,6 +402,7 @@ GpStatus WINGDIPAPI GdipGetPropertyIdList(GpImage*,UINT,PROPID*); GpStatus WINGDIPAPI GdipGetPropertyItem(GpImage*,PROPID,UINT,PropertyItem*); GpStatus WINGDIPAPI GdipGetPropertyItemSize(GpImage*,PROPID,UINT*); GpStatus WINGDIPAPI GdipGetPropertySize(GpImage*,UINT*,UINT*); +GpStatus WINGDIPAPI GdipImageForceValidation(GpImage*); GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage*,GDIPCONST GUID*,UINT*); GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage*,UINT*); GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage*,GUID*,UINT); @@ -405,11 +422,27 @@ GpStatus WINGDIPAPI GdipSetPropertyItem(GpImage*,GDIPCONST PropertyItem*); /* ImageAttributes */ GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes**); GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes*); +GpStatus WINGDIPAPI GdipSetImageAttributesCachedBackground(GpImageAttributes*, + BOOL); GpStatus WINGDIPAPI GdipSetImageAttributesColorKeys(GpImageAttributes*, ColorAdjustType,BOOL,ARGB,ARGB); GpStatus WINGDIPAPI GdipSetImageAttributesColorMatrix(GpImageAttributes*, ColorAdjustType,BOOL,GDIPCONST ColorMatrix*,GDIPCONST ColorMatrix*, ColorMatrixFlags); +GpStatus WINGDIPAPI GdipSetImageAttributesGamma(GpImageAttributes*, + ColorAdjustType,BOOL,REAL); +GpStatus WINGDIPAPI GdipSetImageAttributesNoOp(GpImageAttributes*, + ColorAdjustType,BOOL); +GpStatus WINGDIPAPI GdipSetImageAttributesOutputChannel(GpImageAttributes*, + ColorAdjustType,BOOL,ColorChannelFlags); +GpStatus WINGDIPAPI GdipSetImageAttributesOutputChannelColorProfile( + GpImageAttributes*,ColorAdjustType,BOOL,GDIPCONST WCHAR*); +GpStatus WINGDIPAPI GdipSetImageAttributesRemapTable(GpImageAttributes*, + ColorAdjustType,BOOL,UINT,GDIPCONST ColorMap*); +GpStatus WINGDIPAPI GdipSetImageAttributesThreshold(GpImageAttributes*, + ColorAdjustType,BOOL,REAL); +GpStatus WINGDIPAPI GdipSetImageAttributesToIdentity(GpImageAttributes*, + ColorAdjustType); GpStatus WINGDIPAPI GdipSetImageAttributesWrapMode(GpImageAttributes*,WrapMode, ARGB,BOOL); @@ -496,6 +529,10 @@ GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile*,MetafileHeader GpStatus WINGDIPAPI GdipGetMetafileHeaderFromStream(IStream*,MetafileHeader*); GpStatus WINGDIPAPI GdipGetMetafileHeaderFromWmf(HMETAFILE,GDIPCONST WmfPlaceableFileHeader*,MetafileHeader*); +/* Notification */ +GpStatus WINAPI GdiplusNotificationHook(ULONG_PTR*); +void WINAPI GdiplusNotificationUnhook(ULONG_PTR); + /* PathGradientBrush */ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF*,INT,GpWrapMode,GpPathGradient**); GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint*,INT,GpWrapMode,GpPathGradient**); @@ -558,6 +595,8 @@ GpStatus WINGDIPAPI GdipGetPenDashCount(GpPen*,INT*); GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen*,REAL*); GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen*,GpDashStyle*); GpStatus WINGDIPAPI GdipGetPenMode(GpPen*,GpPenAlignment*); +GpStatus WINGDIPAPI GdipResetPenTransform(GpPen*); +GpStatus WINGDIPAPI GdipScalePenTransform(GpPen*,REAL,REAL,GpMatrixOrder); GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen*,GpBrush*); GpStatus WINGDIPAPI GdipSetPenColor(GpPen*,ARGB); GpStatus WINGDIPAPI GdipSetPenCompoundArray(GpPen*,GDIPCONST REAL*,INT); diff --git a/include/ks.h b/include/ks.h index e570fafcbe0..168357ed1cc 100644 --- a/include/ks.h +++ b/include/ks.h @@ -19,6 +19,48 @@ #ifndef _KS_ #define _KS_ -/* FIXME dummy placeholder for now */ +typedef union tagKSIDENTIFIER +{ + struct + { + GUID Set; + ULONG Id; + ULONG Flags; + } DUMMYSTRUCTNAME; + LONGLONG Alignment; +} KSIDENTIFIER; + +typedef KSIDENTIFIER KSPROPERTY, *PKSPROPERTY, KSMETHOD, *PKSMETHOD, KSEVENT, *PKSEVENT; + +typedef enum +{ + KSPIN_DATAFLOW_IN = 1, + KSPIN_DATAFLOW_OUT +} KSPIN_DATAFLOW, *PKSPIN_DATAFLOW; + +#define KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION 0 +#define KSDATAFORMAT_BIT_ATTRIBUTES 1 +#define KSDATAFORMAT_TEMPORAL_COMPRESSION (1 << 0) +#define KSDATAFORMAT_ATTRIBUTES 1 (1 << 1) + +#define KSDATARANGE_BIT_ATTRIBUTES 1 +#define KSDATARANGE_BIT_REQUIRED_ATTRIBUTES 2 +#define KSDATARANGE_ATTRIBUTES (1 << 1) +#define KSDATARANGE_REQUIRED_ATTRIBUTES (1 << 2) + +typedef union unionKSDATAFORMAT +{ + struct + { + ULONG FormatSize; + ULONG Flags; + ULONG SampleSize; + ULONG Reserved; + GUID MajorFormat; + GUID SubFormat; + GUID Specifier; + } DUMMYSTRUCTNAME; + LONGLONG Alignment; +} KSDATAFORMAT, *PKSDATAFORMAT, KSDATARANGE, *PKSDATARANGE; #endif /* _KS_ */ diff --git a/include/mmdeviceapi.idl b/include/mmdeviceapi.idl new file mode 100644 index 00000000000..e452e89cbd6 --- /dev/null +++ b/include/mmdeviceapi.idl @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2009 Maarten Lankhorst + * + * 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 + */ + +import "unknwn.idl"; +import "propsys.idl"; + +cpp_quote("#ifndef E_NOTFOUND") +cpp_quote("#define E_NOTFOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND)") +cpp_quote("#endif") +cpp_quote("#ifndef E_UNSUPPORTED_TYPE") +cpp_quote("#define E_UNSUPPORTED_TYPE HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE)") +cpp_quote("#endif") + + +cpp_quote("#define DEVICE_STATE_ACTIVE 0x1") +cpp_quote("#define DEVICE_STATE_DISABLED 0x2") +cpp_quote("#define DEVICE_STATE_NOTPRESENT 0x4") +cpp_quote("#define DEVICE_STATE_UNPLUGGED 0x8") +cpp_quote("#define DEVICE_STATEMASK_ALL 0xf") + +/* Generic PKEY_AudioEndPoint ID for grepping: {1da5d803-d492-4edd-8c23-e0c0ffee7f0e} */ +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_FormFactor,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,0);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_ControlPanelPageProvider,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,1);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_Association,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,2);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_PhysicalSpeakers,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,3);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_GUID,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,4);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_Disable_SysFx,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,5);") + +cpp_quote("#define ENDPOINT_SYSFX_ENABLED 0") +cpp_quote("#define ENDPOINT_SYSFX_DISABLED 1") + +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_FullRangeSpeakers,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,6);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_Supports_EventDriven_Mode,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,7);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_JackSubType,0x1da5d803,0xd492,0x4edd,0x8c,0x23,0xe0,0xc0,0xff,0xee,0x7f,0x0e,8);") + +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEngine_DeviceFormat,0xf19f064d,0x082c,0x4e27,0xbc,0x73,0x68,0x82,0xa1,0xbb,0x8e,0x4c,0);") +cpp_quote("DEFINE_PROPERTYKEY(PKEY_AudioEngine_OEMFormat,0xe4870e26,0x3cc5,0x4cd2,0xba,0x46,0xca,0x0a,0x9a,0x70,0xed,0x04,3);") + +typedef struct tagDIRECTX_AUDIO_ACTIVATION_PARAMS +{ + DWORD cbDirectXAudioActivationParams; + GUID guidAudioSession; + DWORD dwAudioStreamFlags; +} DIRECTX_AUDIO_ACTIVATION_PARAMS, *PDIRECTX_AUDIO_ACTIVATION_PARAMS; + +typedef enum _EDataFlow +{ + eRender, + eCapture, + eAll, + EDataFlow_enum_count +} EDataFlow; + +typedef enum _ERole +{ + eConsole, + eMultimedia, + eCommunications, + ERole_enum_count +} ERole; + +typedef enum _EndpointFormFactor +{ + RemoteNetworkDevice, + Speakers, + LineLevel, + Headphones, + Microphone, + Headset, + Handset, + UnknownDigitalPassthrough, + SPDIF, + DigitalAudioDisplayDevice, + UnknownFormFactor, + EndpointFormFactor_enum_count +} EndpointFormFactor; + +cpp_quote("#define HDMI DigitalAudioDisplayDevice") + +[ + object, + local, + uuid(7991eec9-7e89-4d85-8390-6c703cec60c0), + nonextensible, + pointer_default(unique) +] +interface IMMNotificationClient : IUnknown +{ + [id(1)] HRESULT OnDeviceStateChanged( + [in] LPCWSTR pwstrDeviceId, + [in] DWORD dwNewState + ); + [id(2)] HRESULT OnDeviceAdded( + [in] LPCWSTR pwstrDeviceId + ); + [id(3)] HRESULT OnDeviceRemoved( + [in] LPCWSTR pwstrDeviceId + ); + [id(4)] HRESULT OnDefaultDeviceChanged( + [in] EDataFlow flow, + [in] ERole role, + [in] LPCWSTR pwstrDeviceId + ); + [id(5)] HRESULT OnPropertyValueChanged( + [in] LPCWSTR pwstrDeviceId, + [in] const PROPERTYKEY key + ); +} + +[ + object, + local, + uuid(d666063f-1587-4e43-81f1-b948e807363f), + nonextensible, + pointer_default(unique) +] +interface IMMDevice : IUnknown +{ + [id(1)] HRESULT Activate( + [in] REFIID iid, + [in] DWORD dwClsCtx, + [in,unique] PROPVARIANT *pActivationParams, + [out,iid_is(iid)] void **ppv + ); + [id(2)] HRESULT OpenPropertyStore( + [in] DWORD stgmAccess, + [out] IPropertyStore **ppProperties + ); + [id(3)] HRESULT GetId( + [out] LPWSTR *ppstrId + ); + [id(4)] HRESULT GetState( + [out] DWORD *pdwState + ); +} + +[ + object, + local, + uuid(0bd7a1be-7a1a-44db-8397-cc5392387b5e), + nonextensible, + pointer_default(unique) +] +interface IMMDeviceCollection : IUnknown +{ + [id(1)] HRESULT GetCount( + [out] UINT *pcDevices + ); + [id(2)] HRESULT Item( + [in] UINT nDevice, + [out] IMMDevice **ppdevice + ); +} + +[ + object, + local, + uuid(1be09788-6894-4089-8586-9a2a6c265ac5), + nonextensible, + pointer_default(unique) +] +interface IMMEndPoint : IUnknown +{ + [id(1)] HRESULT GetDataFlow( + [out] EDataFlow *pDataFlow + ); +} + +[ + object, + local, + uuid(a95664d2-9614-4f35-a746-de8db63617e6), + nonextensible, + pointer_default(unique) +] +interface IMMDeviceEnumerator : IUnknown +{ + [id(1)] HRESULT EnumAudioEndpoints( + [in] EDataFlow dataFlow, + [in] DWORD dwStateMask, + [out] IMMDeviceCollection **ppDevices + ); + [id(2)] HRESULT GetDefaultAudioEndpoint( + [in] EDataFlow dataFlow, + [in] ERole role, + [out] IMMDevice **ppEndpoint + ); + [id(3)] HRESULT GetDevice( + [in] LPCWSTR pwstrId, + [out] IMMDevice **ppDevice + ); + [id(4)] HRESULT RegisterEndpointNotificationCallback( + [in] IMMNotificationClient *pClient + ); + [id(5)] HRESULT UnregisterEndpointNotificationCallback( + [in] IMMNotificationClient *pClient + ); +} + +[ + object, + local, + uuid(3b0d0ea4-d0a9-4b0e-935b-09516746fac0), + nonextensible, + pointer_default(unique) +] +interface IMMDeviceActivator : IUnknown +{ + [id(1)] HRESULT Activate( + [in] REFIID iid, + [in] IMMDevice *pDevice, + [in] PROPVARIANT *pActivationParams, + [out,iid_is(iid)] void **ppv + ); +} + +typedef struct _AudioExtensionParams +{ + LPARAM AddPageParam; + IMMDevice *pEndPoint; + IMMDevice *pPnpInterface; + IMMDevice *pPnpDevnode; +} AudioExtensionParams; + +[ + uuid(2fdaafa3-7523-4f66-9957-9d5e7fe698f6), + version(1.0) +] +library MMDeviceAPILib +{ + [ uuid(bcde0395-e52f-467c-8e3d-c4579291692e) ] coclass MMDeviceEnumerator + { + [default] interface IMMDeviceEnumerator; + } +} diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index 8bcc2a82738..27267c2913d 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -2327,9 +2327,6 @@ interface IWineD3D : IWineD3DBase ] interface IWineD3DResource : IWineD3DBase { - HRESULT GetDevice( - [out] IWineD3DDevice **device - ); HRESULT SetPrivateData( [in] REFGUID guid, [in] const void *data, @@ -2715,9 +2712,6 @@ interface IWineD3DVolumeTexture : IWineD3DBaseTexture ] interface IWineD3DVertexDeclaration : IWineD3DBase { - HRESULT GetDevice( - [out] IWineD3DDevice **device - ); } [ @@ -2727,9 +2721,6 @@ interface IWineD3DVertexDeclaration : IWineD3DBase ] interface IWineD3DStateBlock : IUnknown { - HRESULT GetDevice( - [out] IWineD3DDevice **device - ); HRESULT Capture( ); HRESULT Apply( @@ -2745,9 +2736,6 @@ interface IWineD3DStateBlock : IUnknown ] interface IWineD3DQuery : IWineD3DBase { - HRESULT GetDevice( - [out] IWineD3DDevice **device - ); HRESULT GetData( [out] void *data, [in] DWORD data_size, @@ -2837,9 +2825,6 @@ interface IWineD3DBuffer : IWineD3DResource ] interface IWineD3DBaseShader : IWineD3DBase { - HRESULT GetDevice( - [out] IWineD3DDevice **device - ); HRESULT GetFunction( [out] void *data, [in, out] UINT *data_size diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h index a1898d5f408..3dc984254c9 100644 --- a/include/wine/winuser16.h +++ b/include/wine/winuser16.h @@ -401,9 +401,6 @@ typedef struct #define SBM_SETRANGE16 (WM_USER+2) #define SBM_GETRANGE16 (WM_USER+3) #define SBM_ENABLE_ARROWS16 (WM_USER+4) -#define SBM_SETRANGEREDRAW16 WM_NULL /* Not in Win16 */ -#define SBM_SETSCROLLINFO16 WM_NULL /* Not in Win16 */ -#define SBM_GETSCROLLINFO16 WM_NULL /* Not in Win16 */ /* CBT hook structures */ @@ -449,9 +446,6 @@ typedef struct #define BM_GETSTATE16 (WM_USER+2) #define BM_SETSTATE16 (WM_USER+3) #define BM_SETSTYLE16 (WM_USER+4) -#define BM_CLICK16 WM_NULL /* Does not exist in Win16 */ -#define BM_GETIMAGE16 WM_NULL /* Does not exist in Win16 */ -#define BM_SETIMAGE16 WM_NULL /* Does not exist in Win16 */ /* Static Control Messages */ #define STM_SETICON16 (WM_USER+0) @@ -489,15 +483,6 @@ typedef struct #define EM_SETWORDBREAKPROC16 (WM_USER+32) #define EM_GETWORDBREAKPROC16 (WM_USER+33) #define EM_GETPASSWORDCHAR16 (WM_USER+34) -/* - not in win16: - EM_SETMARGINS16 WM_NULL - EM_GETMARGINS16 WM_NULL - EM_GETLIMITTEXT16 WM_NULL - EM_POSFROMCHAR16 WM_NULL - EM_CHARFROMPOS16 WM_NULL - EM_SETLIMITTEXT16 WM_NULL - no name change in win16 -*/ typedef struct { diff --git a/programs/clock/Makefile.in b/programs/clock/Makefile.in index 1667416d1e0..1a239a555a6 100644 --- a/programs/clock/Makefile.in +++ b/programs/clock/Makefile.in @@ -5,6 +5,7 @@ VPATH = @srcdir@ MODULE = clock.exe APPMODE = -mwindows IMPORTS = comdlg32 shell32 user32 gdi32 kernel32 +EXTRADEFS = -DWINE_NO_UNICODE_MACROS C_SRCS = \ main.c \ diff --git a/programs/clock/main.c b/programs/clock/main.c index 55a9676d25f..752c93bf14b 100644 --- a/programs/clock/main.c +++ b/programs/clock/main.c @@ -38,18 +38,18 @@ CLOCK_GLOBALS Globals; static VOID WineLicense(HWND Wnd) { - char cap[20], text[1024]; - LoadString(Globals.hInstance, IDS_LICENSE, text, sizeof text); - LoadString(Globals.hInstance, IDS_LICENSE_CAPTION, cap, sizeof cap); - MessageBox(Wnd, text, cap, MB_ICONINFORMATION | MB_OK); + WCHAR cap[20], text[1024]; + LoadStringW(Globals.hInstance, IDS_LICENSE, text, sizeof(text)/sizeof(WCHAR)); + LoadStringW(Globals.hInstance, IDS_LICENSE_CAPTION, cap, sizeof(cap)/sizeof(WCHAR)); + MessageBoxW(Wnd, text, cap, MB_ICONINFORMATION | MB_OK); } static VOID WineWarranty(HWND Wnd) { - char cap[20], text[1024]; - LoadString(Globals.hInstance, IDS_WARRANTY, text, sizeof text); - LoadString(Globals.hInstance, IDS_WARRANTY_CAPTION, cap, sizeof cap); - MessageBox(Wnd, text, cap, MB_ICONEXCLAMATION | MB_OK); + WCHAR cap[20], text[1024]; + LoadStringW(Globals.hInstance, IDS_WARRANTY, text, sizeof(text)/sizeof(WCHAR)); + LoadStringW(Globals.hInstance, IDS_WARRANTY_CAPTION, cap, sizeof(cap)/sizeof(WCHAR)); + MessageBoxW(Wnd, text, cap, MB_ICONEXCLAMATION | MB_OK); } static VOID CLOCK_UpdateMenuCheckmarks(VOID) @@ -81,13 +81,13 @@ static VOID CLOCK_UpdateMenuCheckmarks(VOID) static VOID CLOCK_UpdateWindowCaption(VOID) { - CHAR szCaption[MAX_STRING_LEN]; + WCHAR szCaption[MAX_STRING_LEN]; int chars = 0; /* Set frame caption */ if (Globals.bDate) { - chars = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, NULL, NULL, - szCaption, sizeof(szCaption)); + chars = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, NULL, NULL, + szCaption, sizeof(szCaption)/sizeof(WCHAR)); if (chars) { --chars; szCaption[chars++] = ' '; @@ -96,8 +96,8 @@ static VOID CLOCK_UpdateWindowCaption(VOID) szCaption[chars] = '\0'; } } - LoadString(0, IDS_CLOCK, szCaption + chars, sizeof(szCaption) - chars); - SetWindowText(Globals.hMainWnd, szCaption); + LoadStringW(0, IDS_CLOCK, szCaption + chars, MAX_STRING_LEN - chars); + SetWindowTextW(Globals.hMainWnd, szCaption); } /*********************************************************************** @@ -119,9 +119,10 @@ static BOOL CLOCK_ResetTimer(void) period = 1000; if (!SetTimer (Globals.hMainWnd, TIMER_ID, period, NULL)) { - CHAR szApp[MAX_STRING_LEN]; - LoadString(Globals.hInstance, IDS_CLOCK, szApp, sizeof(szApp)); - MessageBox(0, "No available timers", szApp, MB_ICONEXCLAMATION | MB_OK); + static const WCHAR notimersW[] = {'N','o',' ','a','v','a','i','l','a','b','l','e',' ','t','i','m','e','r','s',0}; + WCHAR szApp[MAX_STRING_LEN]; + LoadStringW(Globals.hInstance, IDS_CLOCK, szApp, MAX_STRING_LEN); + MessageBoxW(0, notimersW, szApp, MB_ICONEXCLAMATION | MB_OK); return FALSE; } return TRUE; @@ -151,15 +152,15 @@ static VOID CLOCK_ResetFont(VOID) */ static VOID CLOCK_ChooseFont(VOID) { - LOGFONT lf; - CHOOSEFONT cf; + LOGFONTW lf; + CHOOSEFONTW cf; memset(&cf, 0, sizeof(cf)); lf = Globals.logfont; cf.lStructSize = sizeof(cf); cf.hwndOwner = Globals.hMainWnd; cf.lpLogFont = &lf; cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT; - if (ChooseFont(&cf)) { + if (ChooseFontW(&cf)) { Globals.logfont = lf; CLOCK_ResetFont(); } @@ -172,7 +173,7 @@ static VOID CLOCK_ChooseFont(VOID) static VOID CLOCK_ToggleTitle(VOID) { /* Also shows/hides the menu */ - LONG style = GetWindowLong(Globals.hMainWnd, GWL_STYLE); + LONG style = GetWindowLongW(Globals.hMainWnd, GWL_STYLE); if ((Globals.bWithoutTitle = !Globals.bWithoutTitle)) { style = (style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP|WS_THICKFRAME; SetMenu(Globals.hMainWnd, 0); @@ -182,7 +183,7 @@ static VOID CLOCK_ToggleTitle(VOID) SetMenu(Globals.hMainWnd, Globals.hMainMenu); SetWindowRgn(Globals.hMainWnd, 0, TRUE); } - SetWindowLong(Globals.hMainWnd, GWL_STYLE, style); + SetWindowLongW(Globals.hMainWnd, GWL_STYLE, style); SetWindowPos(Globals.hMainWnd, 0,0,0,0,0, SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER); @@ -215,8 +216,8 @@ static VOID CLOCK_ToggleOnTop(VOID) static int CLOCK_MenuCommand (WPARAM wParam) { - CHAR szApp[MAX_STRING_LEN]; - CHAR szAppRelease[MAX_STRING_LEN]; + WCHAR szApp[MAX_STRING_LEN]; + WCHAR szAppRelease[MAX_STRING_LEN]; switch (wParam) { /* switch to analog */ case IDM_ANALOG: { @@ -279,9 +280,9 @@ static int CLOCK_MenuCommand (WPARAM wParam) } /* show "about" box */ case IDM_ABOUT: { - LoadString(Globals.hInstance, IDS_CLOCK, szApp, sizeof(szApp)); - lstrcpy(szAppRelease,szApp); - ShellAbout(Globals.hMainWnd, szApp, szAppRelease, 0); + LoadStringW(Globals.hInstance, IDS_CLOCK, szApp, sizeof(szApp)/sizeof(WCHAR)); + lstrcpyW(szAppRelease,szApp); + ShellAboutW(Globals.hMainWnd, szApp, szAppRelease, 0); break; } } @@ -341,7 +342,7 @@ static LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM switch (msg) { /* L button drag moves the window */ case WM_NCHITTEST: { - LRESULT ret = DefWindowProc (hWnd, msg, wParam, lParam); + LRESULT ret = DefWindowProcW(hWnd, msg, wParam, lParam); if (ret == HTCLIENT) ret = HTCAPTION; return ret; @@ -398,7 +399,7 @@ static LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM } default: - return DefWindowProc (hWnd, msg, wParam, lParam); + return DefWindowProcW(hWnd, msg, wParam, lParam); } return 0; } @@ -412,10 +413,10 @@ static LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) { MSG msg; - WNDCLASS class; + WNDCLASSW class; - static const char szClassName[] = "CLClass"; /* To make sure className >= 0x10000 */ - static const char szWinName[] = "Clock"; + static const WCHAR szClassName[] = {'C','L','C','l','a','s','s',0}; + static const WCHAR szWinName[] = {'C','l','o','c','k',0}; /* Setup Globals */ memset(&Globals.hFont, 0, sizeof (Globals.hFont)); @@ -428,17 +429,17 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show class.cbClsExtra = 0; class.cbWndExtra = 0; class.hInstance = hInstance; - class.hIcon = LoadIcon (0, IDI_APPLICATION); - class.hCursor = LoadCursor (0, IDC_ARROW); + class.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION); + class.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW); class.hbrBackground = 0; class.lpszMenuName = 0; class.lpszClassName = szClassName; } - if (!RegisterClass (&class)) return FALSE; + if (!RegisterClassW(&class)) return FALSE; Globals.MaxX = Globals.MaxY = INITIAL_WINDOW_SIZE; - Globals.hMainWnd = CreateWindow (szClassName, szWinName, WS_OVERLAPPEDWINDOW, + Globals.hMainWnd = CreateWindowW(szClassName, szWinName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Globals.MaxX, Globals.MaxY, 0, 0, hInstance, 0); @@ -446,7 +447,7 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show if (!CLOCK_ResetTimer()) return FALSE; - Globals.hMainMenu = LoadMenu(0, MAKEINTRESOURCE(MAIN_MENU)); + Globals.hMainMenu = LoadMenuW(0, MAKEINTRESOURCEW(MAIN_MENU)); SetMenu(Globals.hMainWnd, Globals.hMainMenu); CLOCK_UpdateMenuCheckmarks(); CLOCK_UpdateWindowCaption(); @@ -454,9 +455,9 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show ShowWindow (Globals.hMainWnd, show); UpdateWindow (Globals.hMainWnd); - while (GetMessage(&msg, 0, 0, 0)) { + while (GetMessageW(&msg, 0, 0, 0)) { TranslateMessage(&msg); - DispatchMessage(&msg); + DispatchMessageW(&msg); } KillTimer(Globals.hMainWnd, TIMER_ID); diff --git a/programs/clock/main.h b/programs/clock/main.h index 98a8be33b3e..ce4dc33fb02 100644 --- a/programs/clock/main.h +++ b/programs/clock/main.h @@ -25,7 +25,7 @@ typedef struct { - LOGFONT logfont; + LOGFONTW logfont; HFONT hFont; HANDLE hInstance; HWND hMainWnd; diff --git a/programs/clock/winclock.c b/programs/clock/winclock.c index 5b534577fb8..34d18ddac22 100644 --- a/programs/clock/winclock.c +++ b/programs/clock/winclock.c @@ -177,17 +177,17 @@ void AnalogClock(HDC dc, int x, int y, BOOL bSeconds, BOOL border) } -HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONT* font) +HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONTW* font) { SIZE extent; - LOGFONT lf; + LOGFONTW lf; double xscale, yscale; HFONT oldFont, newFont; - CHAR szTime[255]; + WCHAR szTime[255]; int chars; - chars = GetTimeFormat(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL, - NULL, szTime, sizeof (szTime)); + chars = GetTimeFormatW(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL, + NULL, szTime, sizeof(szTime)/sizeof(WCHAR)); if (!chars) return 0; @@ -199,14 +199,14 @@ HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONT* font) x -= 2 * SHADOW_DEPTH; y -= 2 * SHADOW_DEPTH; - oldFont = SelectObject(dc, CreateFontIndirect(&lf)); - GetTextExtentPoint(dc, szTime, chars, &extent); + oldFont = SelectObject(dc, CreateFontIndirectW(&lf)); + GetTextExtentPointW(dc, szTime, chars, &extent); DeleteObject(SelectObject(dc, oldFont)); xscale = (double)x/extent.cx; yscale = (double)y/extent.cy; lf.lfHeight *= min(xscale, yscale); - newFont = CreateFontIndirect(&lf); + newFont = CreateFontIndirectW(&lf); return newFont; } @@ -215,26 +215,25 @@ void DigitalClock(HDC dc, int x, int y, BOOL bSeconds, HFONT font) { SIZE extent; HFONT oldFont; - CHAR szTime[255]; + WCHAR szTime[255]; int chars; - chars = GetTimeFormat(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL, - NULL, szTime, sizeof (szTime)); + chars = GetTimeFormatW(LOCALE_USER_DEFAULT, bSeconds ? 0 : TIME_NOSECONDS, NULL, + NULL, szTime, sizeof(szTime)/sizeof(WCHAR)); if (!chars) return; --chars; oldFont = SelectObject(dc, font); - GetTextExtentPoint(dc, szTime, chars, &extent); + GetTextExtentPointW(dc, szTime, chars, &extent); SetBkColor(dc, BackgroundColor); SetTextColor(dc, ShadowColor); - TextOut(dc, (x - extent.cx)/2 + SHADOW_DEPTH, (y - extent.cy)/2 + SHADOW_DEPTH, - szTime, chars); + TextOutW(dc, (x - extent.cx)/2 + SHADOW_DEPTH, (y - extent.cy)/2 + SHADOW_DEPTH, szTime, chars); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, HandColor); - TextOut(dc, (x - extent.cx)/2, (y - extent.cy)/2, szTime, chars); + TextOutW(dc, (x - extent.cx)/2, (y - extent.cy)/2, szTime, chars); SelectObject(dc, oldFont); } diff --git a/programs/clock/winclock.h b/programs/clock/winclock.h index bcd26374f8e..b5fd715f0a7 100644 --- a/programs/clock/winclock.h +++ b/programs/clock/winclock.h @@ -22,5 +22,5 @@ */ void AnalogClock(HDC dc, int X, int Y, BOOL bSeconds, BOOL border); -HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONT* font); +HFONT SizeFont(HDC dc, int x, int y, BOOL bSeconds, const LOGFONTW* font); void DigitalClock(HDC dc, int X, int Y, BOOL bSeconds, HFONT font); diff --git a/programs/cmd/Makefile.in b/programs/cmd/Makefile.in index aad9cc7c19c..7f13b527014 100644 --- a/programs/cmd/Makefile.in +++ b/programs/cmd/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cmd.exe APPMODE = -mconsole -municode -EXTRADEFS = -DUNICODE +EXTRADEFS = -DWINE_NO_UNICODE_MACROS IMPORTS = shell32 user32 advapi32 kernel32 C_SRCS = \ diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c index 33b54f7e175..21d8694c2ff 100644 --- a/programs/cmd/batch.c +++ b/programs/cmd/batch.c @@ -61,16 +61,16 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN for(i=0; (idirName, subParm); } - } while (FindNextFile(hff, &fd) != 0); + } while (FindNextFileW(hff, &fd) != 0); FindClose (hff); /* Go through each subdir doing the delete */ @@ -710,7 +710,7 @@ void WCMD_echo (const WCHAR *command) { void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { - WIN32_FIND_DATA fd; + WIN32_FIND_DATAW fd; HANDLE hff; int i; const WCHAR inW[] = {'i', 'n', ' ', '\0'}; @@ -816,7 +816,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { and once we have the complete set, we expect a DO */ WINE_TRACE("Looking for 'do' in %p\n", *cmdList); if ((*cmdList == NULL) || - (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, (*cmdList)->command, 3, doW, -1) != 2)) { WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); return; @@ -855,7 +855,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { if (!useNumbers && !doFileset) { if (strpbrkW (item, wildcards)) { - hff = FindFirstFile (item, &fd); + hff = FindFirstFileW(item, &fd); if (hff != INVALID_HANDLE_VALUE) { do { BOOL isDirectory = FALSE; @@ -873,7 +873,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { fd.cFileName, FALSE, TRUE); } - } while (FindNextFile(hff, &fd) != 0); + } while (FindNextFileW(hff, &fd) != 0); FindClose (hff); } } else { @@ -906,20 +906,20 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { itemStart[strlenW(itemStart)-1] = 0x00; /* Get temp filename */ - GetTempPath (sizeof(temp_path)/sizeof(WCHAR), temp_path); - GetTempFileName (temp_path, cmdW, 0, temp_file); + GetTempPathW(sizeof(temp_path)/sizeof(WCHAR), temp_path); + GetTempFileNameW(temp_path, cmdW, 0, temp_file); /* Execute program and redirect output */ - wsprintf (temp_cmd, redirOut, (itemStart+1), temp_file); + wsprintfW(temp_cmd, redirOut, (itemStart+1), temp_file); WCMD_execute (itemStart, temp_cmd, NULL, NULL, NULL); /* Open the file, read line by line and process */ - input = CreateFile (temp_file, GENERIC_READ, FILE_SHARE_READ, + input = CreateFileW(temp_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { /* Open the file, read line by line and process */ - input = CreateFile (item, GENERIC_READ, FILE_SHARE_READ, + input = CreateFileW(item, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } @@ -958,7 +958,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { /* Delete the temporary file */ if (*itemStart == '`' || *itemStart == '\'') { - DeleteFile (temp_file); + DeleteFileW(temp_file); } /* Filesets - A string literal */ @@ -1089,7 +1089,7 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable, /* End of the command - does 'ELSE ' follow as the next command? */ } else { - if (isIF && CompareString (LOCALE_USER_DEFAULT, + if (isIF && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, (*cmdList)->command, 5, ifElse, -1) == 2) { @@ -1133,7 +1133,7 @@ void WCMD_give_help (WCHAR *command) { } else { for (i=0; i<=WCMD_EXIT; i++) { - if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, param1, -1, inbuilt[i], -1) == 2) { WCMD_output_asis (WCMD_LoadMessage(i)); return; @@ -1292,13 +1292,13 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) { WCMD_parameter (p, 2+negate, &command); } else if (!lstrcmpiW (condition, existW)) { - if (GetFileAttributes(WCMD_parameter (p, 1+negate, NULL)) != INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(WCMD_parameter (p, 1+negate, NULL)) != INVALID_FILE_ATTRIBUTES) { test = 1; } WCMD_parameter (p, 2+negate, &command); } else if (!lstrcmpiW (condition, defdW)) { - if (GetEnvironmentVariable(WCMD_parameter (p, 1+negate, NULL), NULL, 0) > 0) { + if (GetEnvironmentVariableW(WCMD_parameter (p, 1+negate, NULL), NULL, 0) > 0) { test = 1; } WCMD_parameter (p, 2+negate, &command); @@ -1327,7 +1327,7 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) { void WCMD_move (void) { int status; - WIN32_FIND_DATA fd; + WIN32_FIND_DATAW fd; HANDLE hff; WCHAR input[MAX_PATH]; WCHAR output[MAX_PATH]; @@ -1348,15 +1348,15 @@ void WCMD_move (void) { /* If 2nd parm is directory, then use original filename */ /* Convert partial path to full path */ - GetFullPathName (param1, sizeof(input)/sizeof(WCHAR), input, NULL); - GetFullPathName (param2, sizeof(output)/sizeof(WCHAR), output, NULL); + GetFullPathNameW(param1, sizeof(input)/sizeof(WCHAR), input, NULL); + GetFullPathNameW(param2, sizeof(output)/sizeof(WCHAR), output, NULL); WINE_TRACE("Move from '%s'('%s') to '%s'\n", wine_dbgstr_w(input), wine_dbgstr_w(param1), wine_dbgstr_w(output)); /* Split into components */ WCMD_splitpath(input, drive, dir, fname, ext); - hff = FindFirstFile (input, &fd); + hff = FindFirstFileW(input, &fd); while (hff != INVALID_HANDLE_VALUE) { WCHAR dest[MAX_PATH]; WCHAR src[MAX_PATH]; @@ -1369,7 +1369,7 @@ void WCMD_move (void) { strcatW(src, dir); /* See if dest is an existing directory */ - attribs = GetFileAttributes(output); + attribs = GetFileAttributesW(output); if (attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY)) { strcpyW(dest, output); @@ -1385,7 +1385,7 @@ void WCMD_move (void) { WINE_TRACE("Dest '%s'\n", wine_dbgstr_w(dest)); /* Check if file is read only, otherwise move it */ - attribs = GetFileAttributes(src); + attribs = GetFileAttributesW(src); if ((attribs != INVALID_FILE_ATTRIBUTES) && (attribs & FILE_ATTRIBUTE_READONLY)) { SetLastError(ERROR_ACCESS_DENIED); @@ -1394,7 +1394,7 @@ void WCMD_move (void) { BOOL ok = TRUE; /* If destination exists, prompt unless /Y supplied */ - if (GetFileAttributes(dest) != INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(dest) != INVALID_FILE_ATTRIBUTES) { BOOL force = FALSE; WCHAR copycmd[MAXSTRING]; int len; @@ -1406,7 +1406,7 @@ void WCMD_move (void) { force = TRUE; else { const WCHAR copyCmdW[] = {'C','O','P','Y','C','M','D','\0'}; - len = GetEnvironmentVariable (copyCmdW, copycmd, sizeof(copycmd)/sizeof(WCHAR)); + len = GetEnvironmentVariableW(copyCmdW, copycmd, sizeof(copycmd)/sizeof(WCHAR)); force = (len && len < (sizeof(copycmd)/sizeof(WCHAR)) && ! lstrcmpiW (copycmd, parmY)); } @@ -1419,12 +1419,12 @@ void WCMD_move (void) { strcpyW(yesChar, WCMD_LoadMessage(WCMD_YES)); /* Ask for confirmation */ - wsprintf(question, WCMD_LoadMessage(WCMD_OVERWRITE), dest); + wsprintfW(question, WCMD_LoadMessage(WCMD_OVERWRITE), dest); ok = WCMD_ask_confirm(question, FALSE, NULL); /* So delete the destination prior to the move */ if (ok) { - if (!DeleteFile (dest)) { + if (!DeleteFileW(dest)) { WCMD_print_error (); errorlevel = 1; ok = FALSE; @@ -1434,7 +1434,7 @@ void WCMD_move (void) { } if (ok) { - status = MoveFile (src, dest); + status = MoveFileW(src, dest); } else { status = 1; /* Anything other than 0 to prevent error msg below */ } @@ -1446,7 +1446,7 @@ void WCMD_move (void) { } /* Step on to next match */ - if (FindNextFile(hff, &fd) == 0) { + if (FindNextFileW(hff, &fd) == 0) { FindClose(hff); hff = INVALID_HANDLE_VALUE; break; @@ -1495,12 +1495,12 @@ void WCMD_remove_dir (WCHAR *command) { /* If subdirectory search not supplied, just try to remove and report error if it fails (eg if it contains a file) */ if (strstrW (quals, parmS) == NULL) { - if (!RemoveDirectory (thisArg)) WCMD_print_error (); + if (!RemoveDirectoryW(thisArg)) WCMD_print_error (); /* Otherwise use ShFileOp to recursively remove a directory */ } else { - SHFILEOPSTRUCT lpDir; + SHFILEOPSTRUCTW lpDir; /* Ask first */ if (strstrW (quals, parmQ) == NULL) { @@ -1509,7 +1509,7 @@ void WCMD_remove_dir (WCHAR *command) { static const WCHAR fmt[] = {'%','s',' ','\0'}; /* Ask for confirmation */ - wsprintf(question, fmt, thisArg); + wsprintfW(question, fmt, thisArg); ok = WCMD_ask_confirm(question, TRUE, NULL); /* Abort if answer is 'N' */ @@ -1522,7 +1522,7 @@ void WCMD_remove_dir (WCHAR *command) { lpDir.pFrom = thisArg; lpDir.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI; lpDir.wFunc = FO_DELETE; - if (SHFileOperation(&lpDir)) WCMD_print_error (); + if (SHFileOperationW(&lpDir)) WCMD_print_error (); } } } @@ -1545,7 +1545,7 @@ void WCMD_rename (void) { int status; HANDLE hff; - WIN32_FIND_DATA fd; + WIN32_FIND_DATAW fd; WCHAR input[MAX_PATH]; WCHAR *dotDst = NULL; WCHAR drive[10]; @@ -1572,7 +1572,7 @@ void WCMD_rename (void) { } /* Convert partial path to full path */ - GetFullPathName (param1, sizeof(input)/sizeof(WCHAR), input, NULL); + GetFullPathNameW(param1, sizeof(input)/sizeof(WCHAR), input, NULL); WINE_TRACE("Rename from '%s'('%s') to '%s'\n", wine_dbgstr_w(input), wine_dbgstr_w(param1), wine_dbgstr_w(param2)); dotDst = strchrW(param2, '.'); @@ -1580,7 +1580,7 @@ void WCMD_rename (void) { /* Split into components */ WCMD_splitpath(input, drive, dir, fname, ext); - hff = FindFirstFile (input, &fd); + hff = FindFirstFileW(input, &fd); while (hff != INVALID_HANDLE_VALUE) { WCHAR dest[MAX_PATH]; WCHAR src[MAX_PATH]; @@ -1624,13 +1624,13 @@ void WCMD_rename (void) { WINE_TRACE("Dest '%s'\n", wine_dbgstr_w(dest)); /* Check if file is read only, otherwise move it */ - attribs = GetFileAttributes(src); + attribs = GetFileAttributesW(src); if ((attribs != INVALID_FILE_ATTRIBUTES) && (attribs & FILE_ATTRIBUTE_READONLY)) { SetLastError(ERROR_ACCESS_DENIED); status = 0; } else { - status = MoveFile (src, dest); + status = MoveFileW(src, dest); } if (!status) { @@ -1639,7 +1639,7 @@ void WCMD_rename (void) { } /* Step on to next match */ - if (FindNextFile(hff, &fd) == 0) { + if (FindNextFileW(hff, &fd) == 0) { FindClose(hff); hff = INVALID_HANDLE_VALUE; break; @@ -1705,7 +1705,7 @@ void WCMD_setlocal (const WCHAR *s) { saved_environment = env_copy; /* Save the current drive letter */ - GetCurrentDirectory (MAX_PATH, cwd); + GetCurrentDirectoryW(MAX_PATH, cwd); env_copy->u.cwd = cwd[0]; } else @@ -1766,15 +1766,15 @@ void WCMD_endlocal (void) { } /* Restore current drive letter */ - if (IsCharAlpha(temp->u.cwd)) { + if (IsCharAlphaW(temp->u.cwd)) { WCHAR envvar[4]; WCHAR cwd[MAX_PATH]; static const WCHAR fmt[] = {'=','%','c',':','\0'}; - wsprintf(envvar, fmt, temp->u.cwd); - if (GetEnvironmentVariable(envvar, cwd, MAX_PATH)) { + wsprintfW(envvar, fmt, temp->u.cwd); + if (GetEnvironmentVariableW(envvar, cwd, MAX_PATH)) { WINE_TRACE("Resetting cwd to %s\n", wine_dbgstr_w(cwd)); - SetCurrentDirectory(cwd); + SetCurrentDirectoryW(cwd); } } @@ -1793,7 +1793,7 @@ void WCMD_setshow_attrib (void) { DWORD count; HANDLE hff; - WIN32_FIND_DATA fd; + WIN32_FIND_DATAW fd; WCHAR flags[9] = {' ',' ',' ',' ',' ',' ',' ',' ','\0'}; WCHAR *name = param1; DWORD attrib_set=0; @@ -1821,11 +1821,11 @@ void WCMD_setshow_attrib (void) { if (strlenW(name) == 0) { static const WCHAR slashStarW[] = {'\\','*','\0'}; - GetCurrentDirectory (sizeof(param2)/sizeof(WCHAR), name); + GetCurrentDirectoryW(sizeof(param2)/sizeof(WCHAR), name); strcatW (name, slashStarW); } - hff = FindFirstFile (name, &fd); + hff = FindFirstFileW(name, &fd); if (hff == INVALID_HANDLE_VALUE) { WCMD_output (WCMD_LoadMessage(WCMD_FILENOTFOUND), name); } @@ -1860,7 +1860,7 @@ void WCMD_setshow_attrib (void) { WCMD_output (fmt, flags, fd.cFileName); for (count=0; count < 8; count++) flags[count] = ' '; } - } while (FindNextFile(hff, &fd) != 0); + } while (FindNextFileW(hff, &fd) != 0); } FindClose (hff); } @@ -1877,21 +1877,21 @@ void WCMD_setshow_default (WCHAR *command) { WCHAR string[1024]; WCHAR cwd[1024]; WCHAR *pos; - WIN32_FIND_DATA fd; + WIN32_FIND_DATAW fd; HANDLE hff; static const WCHAR parmD[] = {'/','D','\0'}; WINE_TRACE("Request change to directory '%s'\n", wine_dbgstr_w(command)); /* Skip /D and trailing whitespace if on the front of the command line */ - if (CompareString (LOCALE_USER_DEFAULT, + if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, command, 2, parmD, -1) == 2) { command += 2; while (*command && *command==' ') command++; } - GetCurrentDirectory (sizeof(cwd)/sizeof(WCHAR), cwd); + GetCurrentDirectoryW(sizeof(cwd)/sizeof(WCHAR), cwd); if (strlenW(command) == 0) { strcatW (cwd, newline); WCMD_output (cwd); @@ -1908,7 +1908,7 @@ void WCMD_setshow_default (WCHAR *command) { /* Search for appropriate directory */ WINE_TRACE("Looking for directory '%s'\n", wine_dbgstr_w(string)); - hff = FindFirstFile (string, &fd); + hff = FindFirstFileW(string, &fd); while (hff != INVALID_HANDLE_VALUE) { if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { WCHAR fpath[MAX_PATH]; @@ -1919,11 +1919,11 @@ void WCMD_setshow_default (WCHAR *command) { static const WCHAR fmt[] = {'%','s','%','s','%','s','\0'}; /* Convert path into actual directory spec */ - GetFullPathName (string, sizeof(fpath)/sizeof(WCHAR), fpath, NULL); + GetFullPathNameW(string, sizeof(fpath)/sizeof(WCHAR), fpath, NULL); WCMD_splitpath(fpath, drive, dir, fname, ext); /* Rebuild path */ - wsprintf(string, fmt, drive, dir, fd.cFileName); + wsprintfW(string, fmt, drive, dir, fd.cFileName); FindClose(hff); hff = INVALID_HANDLE_VALUE; @@ -1931,7 +1931,7 @@ void WCMD_setshow_default (WCHAR *command) { } /* Step on to next match */ - if (FindNextFile(hff, &fd) == 0) { + if (FindNextFileW(hff, &fd) == 0) { FindClose(hff); hff = INVALID_HANDLE_VALUE; break; @@ -1941,7 +1941,7 @@ void WCMD_setshow_default (WCHAR *command) { /* Change to that directory */ WINE_TRACE("Really changing to directory '%s'\n", wine_dbgstr_w(string)); - status = SetCurrentDirectory (string); + status = SetCurrentDirectoryW(string); if (!status) { errorlevel = 1; WCMD_print_error (); @@ -1955,7 +1955,7 @@ void WCMD_setshow_default (WCHAR *command) { CD x:\directory /D (or pushd c:\directory) not supplied */ if ((strstrW(quals, parmD) == NULL) && (param1[1] == ':') && (toupper(param1[0]) != toupper(cwd[0]))) { - SetCurrentDirectory(cwd); + SetCurrentDirectoryW(cwd); } } @@ -1963,13 +1963,13 @@ void WCMD_setshow_default (WCHAR *command) { change of directory, even if path was restored due to missing /D (allows changing drive letter when not resident on that drive */ - if ((string[1] == ':') && IsCharAlpha (string[0])) { + if ((string[1] == ':') && IsCharAlphaW(string[0])) { WCHAR env[4]; strcpyW(env, equalW); memcpy(env+1, string, 2 * sizeof(WCHAR)); env[3] = 0x00; WINE_TRACE("Setting '%s' to '%s'\n", wine_dbgstr_w(env), wine_dbgstr_w(string)); - SetEnvironmentVariable(env, string); + SetEnvironmentVariableW(env, string); } } @@ -1990,7 +1990,7 @@ void WCMD_setshow_date (void) { static const WCHAR parmT[] = {'/','T','\0'}; if (strlenW(param1) == 0) { - if (GetDateFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL, + if (GetDateFormatW(LOCALE_USER_DEFAULT, 0, NULL, NULL, curdate, sizeof(curdate)/sizeof(WCHAR))) { WCMD_output (WCMD_LoadMessage(WCMD_CURRENTDATE), curdate); if (strstrW (quals, parmT) == NULL) { @@ -2016,7 +2016,7 @@ static int WCMD_compare( const void *a, const void *b ) { int r; const WCHAR * const *str_a = a, * const *str_b = b; - r = CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + r = CompareStringW( LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, *str_a, -1, *str_b, -1 ); if( r == CSTR_LESS_THAN ) return -1; if( r == CSTR_GREATER_THAN ) return 1; @@ -2056,7 +2056,7 @@ static int WCMD_setshow_sortenv(const WCHAR *s, const WCHAR *stub) /* print it */ for( i=0; i 0) { @@ -227,7 +227,7 @@ static void WCMD_getfileowner(WCHAR *filename, WCHAR *owner, int ownerlen) { if(!secBuffer) return; /* Get the owners security descriptor */ - if(!GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, secBuffer, + if(!GetFileSecurityW(filename, OWNER_SECURITY_INFORMATION, secBuffer, sizeNeeded, &sizeNeeded)) { HeapFree(GetProcessHeap(),0,secBuffer); return; @@ -240,7 +240,7 @@ static void WCMD_getfileowner(WCHAR *filename, WCHAR *owner, int ownerlen) { } /* Convert to a username */ - if (LookupAccountSid(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) { + if (LookupAccountSidW(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) { static const WCHAR fmt[] = {'%','s','%','c','%','s','\0'}; snprintfW(owner, ownerlen, fmt, domain, '\\', name); } @@ -262,7 +262,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le WCHAR string[1024], datestring[32], timestring[32]; WCHAR real_path[MAX_PATH]; - WIN32_FIND_DATA *fd; + WIN32_FIND_DATAW *fd; FILETIME ft; SYSTEMTIME st; HANDLE hff; @@ -294,7 +294,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le same directory. Note issuing a directory header with no contents mirrors what windows does */ parms = inputparms; - fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATA)); + fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATAW)); while (parms && strcmpW(inputparms->dirName, parms->dirName) == 0) { concurrentDirs++; @@ -304,7 +304,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le /* Load all files into an in memory structure */ WINE_TRACE("Looking for matches to '%s'\n", wine_dbgstr_w(real_path)); - hff = FindFirstFile (real_path, (fd+entry_count)); + hff = FindFirstFileW(real_path, (fd+entry_count)); if (hff != INVALID_HANDLE_VALUE) { do { /* Skip any which are filtered out by attribute */ @@ -319,14 +319,14 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le if (tmpLen > widest) widest = tmpLen; } - fd = HeapReAlloc(GetProcessHeap(),0,fd,(entry_count+1)*sizeof(WIN32_FIND_DATA)); + fd = HeapReAlloc(GetProcessHeap(),0,fd,(entry_count+1)*sizeof(WIN32_FIND_DATAW)); if (fd == NULL) { FindClose (hff); WINE_ERR("Out of memory\n"); errorlevel = 1; return parms->next; } - } while (FindNextFile(hff, (fd+entry_count)) != 0); + } while (FindNextFileW(hff, (fd+entry_count)) != 0); FindClose (hff); } @@ -353,7 +353,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le if (entry_count > 0) { /* Sort the list of files */ - qsort (fd, entry_count, sizeof(WIN32_FIND_DATA), WCMD_dir_sort); + qsort (fd, entry_count, sizeof(WIN32_FIND_DATAW), WCMD_dir_sort); /* Work out the number of columns */ WINE_TRACE("%d entries, maxwidth=%d, widest=%d\n", entry_count, max_width, widest); @@ -402,9 +402,9 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le FileTimeToLocalFileTime (&(fd+i)->ftCreationTime, &ft); } FileTimeToSystemTime (&ft, &st); - GetDateFormat (0, DATE_SHORTDATE, &st, NULL, datestring, + GetDateFormatW(0, DATE_SHORTDATE, &st, NULL, datestring, sizeof(datestring)/sizeof(WCHAR)); - GetTimeFormat (0, TIME_NOSECONDS, &st, + GetTimeFormatW(0, TIME_NOSECONDS, &st, NULL, timestring, sizeof(timestring)/sizeof(WCHAR)); if (wide) { @@ -520,14 +520,14 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le if (recurse) { DIRECTORY_STACK *dirStack = NULL; DIRECTORY_STACK *lastEntry = NULL; - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; /* Build path to search */ strcpyW(string, inputparms->dirName); strcatW(string, starW); WINE_TRACE("Recursive, looking for '%s'\n", wine_dbgstr_w(string)); - hff = FindFirstFile (string, &finddata); + hff = FindFirstFileW(string, &finddata); if (hff != INVALID_HANDLE_VALUE) { do { if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && @@ -563,7 +563,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le parms = parms->next; } } - } while (FindNextFile(hff, &finddata) != 0); + } while (FindNextFileW(hff, &finddata) != 0); FindClose (hff); while (dirStack != NULL) { @@ -601,7 +601,7 @@ static void WCMD_dir_trailer(WCHAR drive) { WCHAR driveName[4] = {'c',':','\\','\0'}; driveName[0] = drive; - status = GetDiskFreeSpaceEx (driveName, &avail, &total, &freebytes); + status = GetDiskFreeSpaceExW(driveName, &avail, &total, &freebytes); WINE_TRACE("Writing trailer for '%s' gave %d(%d)\n", wine_dbgstr_w(driveName), status, GetLastError()); @@ -654,7 +654,7 @@ void WCMD_directory (WCHAR *cmd) { errorlevel = 0; /* Prefill quals with (uppercased) DIRCMD env var */ - if (GetEnvironmentVariable (dircmdW, string, sizeof(string)/sizeof(WCHAR))) { + if (GetEnvironmentVariableW(dircmdW, string, sizeof(string)/sizeof(WCHAR))) { p = string; while ( (*p = toupper(*p)) ) ++p; strcatW(string,quals); @@ -833,7 +833,7 @@ void WCMD_directory (WCHAR *cmd) { argno = 0; argsProcessed = 0; argN = cmd; - GetCurrentDirectory (MAX_PATH, cwd); + GetCurrentDirectoryW(MAX_PATH, cwd); strcatW(cwd, slashW); /* Loop through all args, calculating full effective directory */ @@ -850,10 +850,10 @@ void WCMD_directory (WCHAR *cmd) { } else if (thisArg[1] == ':' && thisArg[2] != '\\') { WCHAR envvar[4]; static const WCHAR envFmt[] = {'=','%','c',':','\0'}; - wsprintf(envvar, envFmt, thisArg[0]); - if (!GetEnvironmentVariable(envvar, fullname, MAX_PATH)) { + wsprintfW(envvar, envFmt, thisArg[0]); + if (!GetEnvironmentVariableW(envvar, fullname, MAX_PATH)) { static const WCHAR noEnvFmt[] = {'%','c',':','\0'}; - wsprintf(fullname, noEnvFmt, thisArg[0]); + wsprintfW(fullname, noEnvFmt, thisArg[0]); } strcatW(fullname, slashW); strcatW(fullname, &thisArg[2]); @@ -866,7 +866,7 @@ void WCMD_directory (WCHAR *cmd) { } WINE_TRACE("Using location '%s'\n", wine_dbgstr_w(fullname)); - status = GetFullPathName (fullname, sizeof(path)/sizeof(WCHAR), path, NULL); + status = GetFullPathNameW(fullname, sizeof(path)/sizeof(WCHAR), path, NULL); /* * If the path supplied does not include a wildcard, and the endpoint of the @@ -874,7 +874,7 @@ void WCMD_directory (WCHAR *cmd) { * directory not the directory file itself. */ if ((strchrW(path, '*') == NULL) && (strchrW(path, '%') == NULL)) { - status = GetFileAttributes (path); + status = GetFileAttributesW(path); if ((status != INVALID_FILE_ATTRIBUTES) && (status & FILE_ATTRIBUTE_DIRECTORY)) { if (path[strlenW(path)-1] == '\\') { strcatW (path, starW); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index fed1fbd3c59..1c55fce7764 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -269,7 +269,7 @@ void WCMD_output_asis (const WCHAR *message) { } } while (((message = ptr) != NULL) && (*ptr)); } else { - WCMD_output_asis_len(message, lstrlen(message), + WCMD_output_asis_len(message, lstrlenW(message), GetStdHandle(STD_OUTPUT_HANDLE)); } } @@ -286,18 +286,18 @@ void WCMD_print_error (void) { int status; error_code = GetLastError (); - status = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL); + status = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error_code, 0, (LPWSTR) &lpMsgBuf, 0, NULL); if (!status) { WINE_FIXME ("Cannot display message for error %d, status %d\n", error_code, GetLastError()); return; } - WCMD_output_asis_len(lpMsgBuf, lstrlen(lpMsgBuf), + WCMD_output_asis_len(lpMsgBuf, lstrlenW(lpMsgBuf), GetStdHandle(STD_ERROR_HANDLE)); LocalFree (lpMsgBuf); - WCMD_output_asis_len (newline, lstrlen(newline), + WCMD_output_asis_len (newline, lstrlenW(newline), GetStdHandle(STD_ERROR_HANDLE)); return; } @@ -317,7 +317,7 @@ static void WCMD_show_prompt (void) { DWORD len; static const WCHAR envPrompt[] = {'P','R','O','M','P','T','\0'}; - len = GetEnvironmentVariable (envPrompt, prompt_string, + len = GetEnvironmentVariableW(envPrompt, prompt_string, sizeof(prompt_string)/sizeof(WCHAR)); if ((len == 0) || (len >= (sizeof(prompt_string)/sizeof(WCHAR)))) { const WCHAR dfltPrompt[] = {'$','P','$','G','\0'}; @@ -347,7 +347,7 @@ static void WCMD_show_prompt (void) { *q++ = '('; break; case 'D': - GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, q, MAX_PATH); + GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, q, MAX_PATH); while (*q) q++; break; case 'E': @@ -366,13 +366,13 @@ static void WCMD_show_prompt (void) { *q++ = '<'; break; case 'N': - status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir); + status = GetCurrentDirectoryW(sizeof(curdir)/sizeof(WCHAR), curdir); if (status) { *q++ = curdir[0]; } break; case 'P': - status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir); + status = GetCurrentDirectoryW(sizeof(curdir)/sizeof(WCHAR), curdir); if (status) { strcatW (q, curdir); while (*q) q++; @@ -385,7 +385,7 @@ static void WCMD_show_prompt (void) { *q++ = ' '; break; case 'T': - GetTimeFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL, q, MAX_PATH); + GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, NULL, q, MAX_PATH); while (*q) q++; break; case 'V': @@ -542,54 +542,54 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { /* Expand to contents, if unchanged, return */ /* Handle DATE, TIME, ERRORLEVEL and CD replacements allowing */ /* override if existing env var called that name */ - if ((CompareString (LOCALE_USER_DEFAULT, + if ((CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, thisVar, 12, ErrorLvlP, -1) == 2) && - (GetEnvironmentVariable(ErrorLvl, thisVarContents, 1) == 0) && + (GetEnvironmentVariableW(ErrorLvl, thisVarContents, 1) == 0) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { static const WCHAR fmt[] = {'%','d','\0'}; - wsprintf(thisVarContents, fmt, errorlevel); + wsprintfW(thisVarContents, fmt, errorlevel); len = strlenW(thisVarContents); - } else if ((CompareString (LOCALE_USER_DEFAULT, + } else if ((CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, thisVar, 6, DateP, -1) == 2) && - (GetEnvironmentVariable(Date, thisVarContents, 1) == 0) && + (GetEnvironmentVariableW(Date, thisVarContents, 1) == 0) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { - GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, + GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, thisVarContents, MAXSTRING); len = strlenW(thisVarContents); - } else if ((CompareString (LOCALE_USER_DEFAULT, + } else if ((CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, thisVar, 6, TimeP, -1) == 2) && - (GetEnvironmentVariable(Time, thisVarContents, 1) == 0) && + (GetEnvironmentVariableW(Time, thisVarContents, 1) == 0) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { - GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL, + GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL, NULL, thisVarContents, MAXSTRING); len = strlenW(thisVarContents); - } else if ((CompareString (LOCALE_USER_DEFAULT, + } else if ((CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, thisVar, 4, CdP, -1) == 2) && - (GetEnvironmentVariable(Cd, thisVarContents, 1) == 0) && + (GetEnvironmentVariableW(Cd, thisVarContents, 1) == 0) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { - GetCurrentDirectory (MAXSTRING, thisVarContents); + GetCurrentDirectoryW(MAXSTRING, thisVarContents); len = strlenW(thisVarContents); - } else if ((CompareString (LOCALE_USER_DEFAULT, + } else if ((CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, thisVar, 8, RandomP, -1) == 2) && - (GetEnvironmentVariable(Random, thisVarContents, 1) == 0) && + (GetEnvironmentVariableW(Random, thisVarContents, 1) == 0) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) { static const WCHAR fmt[] = {'%','d','\0'}; - wsprintf(thisVarContents, fmt, rand() % 32768); + wsprintfW(thisVarContents, fmt, rand() % 32768); len = strlenW(thisVarContents); /* Look for a matching 'for' variable */ } else if (forVar && - (CompareString (LOCALE_USER_DEFAULT, + (CompareStringW(LOCALE_USER_DEFAULT, SORT_STRINGSORT, thisVar, (colonpos - thisVar) - 1, @@ -599,7 +599,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { } else { - len = ExpandEnvironmentStrings(thisVar, thisVarContents, + len = ExpandEnvironmentStringsW(thisVar, thisVarContents, sizeof(thisVarContents)/sizeof(WCHAR)); } @@ -709,9 +709,9 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) { /* Since we need to be case insensitive, copy the 2 buffers */ searchIn = WCMD_strdupW(thisVarContents); - CharUpperBuff(searchIn, strlenW(thisVarContents)); + CharUpperBuffW(searchIn, strlenW(thisVarContents)); searchFor = WCMD_strdupW(colonpos+1); - CharUpperBuff(searchFor, strlenW(colonpos+1)); + CharUpperBuffW(searchFor, strlenW(colonpos+1)); /* Handle wildcard case */ if (*(colonpos+1) == '*') { @@ -809,7 +809,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR WCMD_strsubstW(p, p+2, NULL, 0); } else if (forVariable && - (CompareString (LOCALE_USER_DEFAULT, + (CompareStringW(LOCALE_USER_DEFAULT, SORT_STRINGSORT, p, strlenW(forVariable), @@ -886,14 +886,14 @@ static void WCMD_parse (WCHAR *s, WCHAR *q, WCHAR *p1, WCHAR *p2) } } -static void init_msvcrt_io_block(STARTUPINFO* st) +static void init_msvcrt_io_block(STARTUPINFOW* st) { - STARTUPINFO st_p; + STARTUPINFOW st_p; /* fetch the parent MSVCRT info block if any, so that the child can use the * same handles as its grand-father */ - st_p.cb = sizeof(STARTUPINFO); - GetStartupInfo(&st_p); + st_p.cb = sizeof(STARTUPINFOW); + GetStartupInfoW(&st_p); st->cbReserved2 = st_p.cbReserved2; st->lpReserved2 = st_p.lpReserved2; if (st_p.cbReserved2 && st_p.lpReserved2) @@ -984,7 +984,7 @@ void WCMD_run_program (WCHAR *command, int called) { if (strpbrkW (param1, delims) == NULL) { /* No explicit path given, search path */ static const WCHAR curDir[] = {'.',';','\0'}; strcpyW(pathtosearch, curDir); - len = GetEnvironmentVariable (envPath, &pathtosearch[2], (sizeof(pathtosearch)/sizeof(WCHAR))-2); + len = GetEnvironmentVariableW(envPath, &pathtosearch[2], (sizeof(pathtosearch)/sizeof(WCHAR))-2); if ((len == 0) || (len >= (sizeof(pathtosearch)/sizeof(WCHAR)) - 2)) { static const WCHAR curDir[] = {'.','\0'}; strcpyW (pathtosearch, curDir); @@ -1001,7 +1001,7 @@ void WCMD_run_program (WCHAR *command, int called) { } else { /* Convert eg. ..\fred to include a directory by removing file part */ - GetFullPathName(param1, sizeof(pathtosearch)/sizeof(WCHAR), pathtosearch, NULL); + GetFullPathNameW(param1, sizeof(pathtosearch)/sizeof(WCHAR), pathtosearch, NULL); lastSlash = strrchrW(pathtosearch, '\\'); if (lastSlash && strchrW(lastSlash, '.') != NULL) extensionsupplied = TRUE; strcpyW(stemofsearch, lastSlash+1); @@ -1012,7 +1012,7 @@ void WCMD_run_program (WCHAR *command, int called) { } /* Now extract PATHEXT */ - len = GetEnvironmentVariable (envPathExt, pathext, sizeof(pathext)/sizeof(WCHAR)); + len = GetEnvironmentVariableW(envPathExt, pathext, sizeof(pathext)/sizeof(WCHAR)); if ((len == 0) || (len >= (sizeof(pathext)/sizeof(WCHAR)))) { static const WCHAR dfltPathExt[] = {'.','b','a','t',';', '.','c','o','m',';', @@ -1047,7 +1047,7 @@ void WCMD_run_program (WCHAR *command, int called) { /* Since you can have eg. ..\.. on the path, need to expand to full information */ strcpyW(temp, thisDir); - GetFullPathName(temp, MAX_PATH, thisDir, NULL); + GetFullPathNameW(temp, MAX_PATH, thisDir, NULL); /* 1. If extension supplied, see if that file exists */ strcatW(thisDir, slashW); @@ -1056,7 +1056,7 @@ void WCMD_run_program (WCHAR *command, int called) { /* 1. If extension supplied, see if that file exists */ if (extensionsupplied) { - if (GetFileAttributes(thisDir) != INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(thisDir) != INVALID_FILE_ATTRIBUTES) { found = TRUE; } } @@ -1064,11 +1064,11 @@ void WCMD_run_program (WCHAR *command, int called) { /* 2. Any .* matches? */ if (!found) { HANDLE h; - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; static const WCHAR allFiles[] = {'.','*','\0'}; strcatW(thisDir,allFiles); - h = FindFirstFile(thisDir, &finddata); + h = FindFirstFileW(thisDir, &finddata); FindClose(h); if (h != INVALID_HANDLE_VALUE) { @@ -1087,7 +1087,7 @@ void WCMD_run_program (WCHAR *command, int called) { thisExt = NULL; } - if (GetFileAttributes(thisDir) != INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(thisDir) != INVALID_FILE_ATTRIBUTES) { found = TRUE; thisExt = NULL; } @@ -1109,9 +1109,9 @@ void WCMD_run_program (WCHAR *command, int called) { /* Once found, launch it */ if (found || assumeInternal) { - STARTUPINFO st; + STARTUPINFOW st; PROCESS_INFORMATION pe; - SHFILEINFO psfi; + SHFILEINFOW psfi; DWORD console; HINSTANCE hinst; WCHAR *ext = strrchrW( thisDir, '.' ); @@ -1131,19 +1131,19 @@ void WCMD_run_program (WCHAR *command, int called) { /* thisDir contains the file to be launched, but with what? eg. a.exe will require a.exe to be launched, a.html may be iexplore */ - hinst = FindExecutable (thisDir, NULL, temp); + hinst = FindExecutableW (thisDir, NULL, temp); if ((INT_PTR)hinst < 32) console = 0; else - console = SHGetFileInfo (temp, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE); + console = SHGetFileInfoW(temp, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE); - ZeroMemory (&st, sizeof(STARTUPINFO)); - st.cb = sizeof(STARTUPINFO); + ZeroMemory (&st, sizeof(STARTUPINFOW)); + st.cb = sizeof(STARTUPINFOW); init_msvcrt_io_block(&st); /* Launch the process and if a CUI wait on it to complete Note: Launching internal wine processes cannot specify a full path to exe */ - status = CreateProcess (assumeInternal?NULL : thisDir, + status = CreateProcessW(assumeInternal?NULL : thisDir, command, NULL, NULL, TRUE, 0, NULL, NULL, &st, &pe); if ((opt_c || opt_k) && !opt_s && !status && GetLastError()==ERROR_FILE_NOT_FOUND && command[0]=='\"') { @@ -1228,8 +1228,8 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, piped = TRUE; /* Generate a unique temporary filename */ - GetTempPath (sizeof(temp_path)/sizeof(WCHAR), temp_path); - GetTempFileName (temp_path, cmdW, 0, (*cmdList)->nextcommand->pipeFile); + GetTempPathW(sizeof(temp_path)/sizeof(WCHAR), temp_path); + GetTempFileNameW(temp_path, cmdW, 0, (*cmdList)->nextcommand->pipeFile); WINE_TRACE("Using temporary file of %s\n", wine_dbgstr_w((*cmdList)->nextcommand->pipeFile)); } @@ -1255,7 +1255,7 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, /* If piped output, send stdout to the pipe by appending >filename to redirects */ if (piped) { static const WCHAR redirOut[] = {'%','s',' ','>',' ','%','s','\0'}; - wsprintf (new_redir, redirOut, redirects, (*cmdList)->nextcommand->pipeFile); + wsprintfW (new_redir, redirOut, redirects, (*cmdList)->nextcommand->pipeFile); WINE_TRACE("Redirects now %s\n", wine_dbgstr_w(new_redir)); } else { strcpyW(new_redir, redirects); @@ -1278,7 +1278,7 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, * Changing default drive has to be handled as a special case. */ - if ((cmd[1] == ':') && IsCharAlpha (cmd[0]) && (strlenW(cmd) == 2)) { + if ((cmd[1] == ':') && IsCharAlphaW(cmd[0]) && (strlenW(cmd) == 2)) { WCHAR envvar[5]; WCHAR dir[MAX_PATH]; @@ -1287,13 +1287,13 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, so see if one specified, and if so go back to it */ strcpyW(envvar, equalsW); strcatW(envvar, cmd); - if (GetEnvironmentVariable(envvar, dir, MAX_PATH) == 0) { + if (GetEnvironmentVariableW(envvar, dir, MAX_PATH) == 0) { static const WCHAR fmt[] = {'%','s','\\','\0'}; - wsprintf(cmd, fmt, cmd); + wsprintfW(cmd, fmt, cmd); WINE_TRACE("No special directory settings, using dir of %s\n", wine_dbgstr_w(cmd)); } WINE_TRACE("Got directory %s as %s\n", wine_dbgstr_w(envvar), wine_dbgstr_w(cmd)); - status = SetCurrentDirectory (cmd); + status = SetCurrentDirectoryW(cmd); if (!status) WCMD_print_error (); HeapFree( GetProcessHeap(), 0, cmd ); HeapFree( GetProcessHeap(), 0, new_redir ); @@ -1311,7 +1311,7 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, /* STDIN could come from a preceding pipe, so delete on close if it does */ if (cmdList && (*cmdList)->pipeFile[0] != 0x00) { WINE_TRACE("Input coming from %s\n", wine_dbgstr_w((*cmdList)->pipeFile)); - h = CreateFile ((*cmdList)->pipeFile, GENERIC_READ, + h = CreateFileW((*cmdList)->pipeFile, GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); if (h == INVALID_HANDLE_VALUE) { @@ -1327,7 +1327,7 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, /* Otherwise STDIN could come from a '<' redirect */ } else if ((p = strchrW(new_redir,'<')) != NULL) { - h = CreateFile (WCMD_parameter (++p, 0, NULL), GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, + h = CreateFileW(WCMD_parameter (++p, 0, NULL), GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { WCMD_print_error (); @@ -1374,7 +1374,7 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, } else { WCHAR *param = WCMD_parameter (p, 0, NULL); - h = CreateFile (param, GENERIC_WRITE, 0, &sa, creationDisposition, + h = CreateFileW(param, GENERIC_WRITE, 0, &sa, creationDisposition, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { WCMD_print_error (); @@ -1405,11 +1405,11 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, */ count = 0; - while (IsCharAlphaNumeric(whichcmd[count])) { + while (IsCharAlphaNumericW(whichcmd[count])) { count++; } for (i=0; i<=WCMD_EXIT; i++) { - if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, whichcmd, count, inbuilt[i], -1) == 2) break; } p = WCMD_strtrim_leading_spaces (&whichcmd[count]); @@ -1566,7 +1566,7 @@ WCHAR *WCMD_LoadMessage(UINT id) { static WCHAR msg[2048]; static const WCHAR failedMsg[] = {'F','a','i','l','e','d','!','\0'}; - if (!LoadString(GetModuleHandle(NULL), id, msg, sizeof(msg)/sizeof(WCHAR))) { + if (!LoadStringW(GetModuleHandleW(NULL), id, msg, sizeof(msg)/sizeof(WCHAR))) { WINE_FIXME("LoadString failed with %d\n", GetLastError()); strcpyW(msg, failedMsg); } @@ -1795,12 +1795,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF const WCHAR forDO[] = {'d','o',' ','\0'}; /* If command starts with 'rem', ignore any &&, ( etc */ - if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 4, remCmd, -1) == 2) { inRem = TRUE; /* If command starts with 'for', handle ('s mid line after IN or DO */ - } else if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 4, forCmd, -1) == 2) { inFor = TRUE; @@ -1810,11 +1810,11 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF FIXME: Silly syntax like "if 1(==1( ( echo they equal )" will be parsed wrong */ - } else if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 3, ifCmd, -1) == 2) { inIf = TRUE; - } else if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 5, ifElse, -1) == 2) { inElse = TRUE; lastWasElse = TRUE; @@ -1828,7 +1828,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF whitespace, followed by DO, ie closeBracket inserts a NULL entry, curLen is then 0, and all whitespace is skipped */ } else if (inFor && - (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 3, forDO, -1) == 2)) { WINE_TRACE("Found DO\n"); lastWasDo = TRUE; @@ -1846,7 +1846,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF WINE_TRACE("Found 'FOR', comparing next parm: '%s'\n", wine_dbgstr_w(curPos)); - if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 3, forIN, -1) == 2) { WINE_TRACE("Found IN\n"); lastWasIn = TRUE; @@ -2197,7 +2197,7 @@ int wmain (int argc, WCHAR *argvW[]) /* Pre initialize some messages */ strcpy(ansiVersion, PACKAGE_VERSION); MultiByteToWideChar(CP_ACP, 0, ansiVersion, -1, string, 1024); - wsprintf(version_string, WCMD_LoadMessage(WCMD_VERSION), string); + wsprintfW(version_string, WCMD_LoadMessage(WCMD_VERSION), string); strcpyW(anykey, WCMD_LoadMessage(WCMD_ANYKEY)); args = argc; @@ -2412,7 +2412,7 @@ int wmain (int argc, WCHAR *argvW[]) SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT); - SetConsoleTitle(WCMD_LoadMessage(WCMD_CONSTITLE)); + SetConsoleTitleW(WCMD_LoadMessage(WCMD_CONSTITLE)); /* Note: cmd.exe /c dir does not get a new color, /k dir does */ if (opt_t) { @@ -2435,20 +2435,20 @@ int wmain (int argc, WCHAR *argvW[]) 'C','o','m','m','a','n','d',' ','P','r','o','c','e','s','s','o','r','\0'}; static const WCHAR dfltColorW[] = {'D','e','f','a','u','l','t','C','o','l','o','r','\0'}; - if (RegOpenKeyEx(HKEY_CURRENT_USER, regKeyW, + if (RegOpenKeyExW(HKEY_CURRENT_USER, regKeyW, 0, KEY_READ, &key) == ERROR_SUCCESS) { WCHAR strvalue[4]; /* See if DWORD or REG_SZ */ - if (RegQueryValueEx(key, dfltColorW, NULL, &type, + if (RegQueryValueExW(key, dfltColorW, NULL, &type, NULL, NULL) == ERROR_SUCCESS) { if (type == REG_DWORD) { size = sizeof(DWORD); - RegQueryValueEx(key, dfltColorW, NULL, NULL, + RegQueryValueExW(key, dfltColorW, NULL, NULL, (LPBYTE)&value, &size); } else if (type == REG_SZ) { size = sizeof(strvalue)/sizeof(WCHAR); - RegQueryValueEx(key, dfltColorW, NULL, NULL, + RegQueryValueExW(key, dfltColorW, NULL, NULL, (LPBYTE)strvalue, &size); value = strtoulW(strvalue, NULL, 10); } @@ -2456,20 +2456,20 @@ int wmain (int argc, WCHAR *argvW[]) RegCloseKey(key); } - if (value == 0 && RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKeyW, + if (value == 0 && RegOpenKeyExW(HKEY_LOCAL_MACHINE, regKeyW, 0, KEY_READ, &key) == ERROR_SUCCESS) { WCHAR strvalue[4]; /* See if DWORD or REG_SZ */ - if (RegQueryValueEx(key, dfltColorW, NULL, &type, + if (RegQueryValueExW(key, dfltColorW, NULL, &type, NULL, NULL) == ERROR_SUCCESS) { if (type == REG_DWORD) { size = sizeof(DWORD); - RegQueryValueEx(key, dfltColorW, NULL, NULL, + RegQueryValueExW(key, dfltColorW, NULL, NULL, (LPBYTE)&value, &size); } else if (type == REG_SZ) { size = sizeof(strvalue)/sizeof(WCHAR); - RegQueryValueEx(key, dfltColorW, NULL, NULL, + RegQueryValueExW(key, dfltColorW, NULL, NULL, (LPBYTE)strvalue, &size); value = strtoulW(strvalue, NULL, 10); } @@ -2487,11 +2487,11 @@ int wmain (int argc, WCHAR *argvW[]) } /* Save cwd into appropriate env var */ - GetCurrentDirectory(1024, string); - if (IsCharAlpha(string[0]) && string[1] == ':') { + GetCurrentDirectoryW(1024, string); + if (IsCharAlphaW(string[0]) && string[1] == ':') { static const WCHAR fmt[] = {'=','%','c',':','\0'}; - wsprintf(envvar, fmt, string[0]); - SetEnvironmentVariable(envvar, string); + wsprintfW(envvar, fmt, string[0]); + SetEnvironmentVariableW(envvar, string); WINE_TRACE("Set %s to %s\n", wine_dbgstr_w(envvar), wine_dbgstr_w(string)); } @@ -2508,8 +2508,8 @@ int wmain (int argc, WCHAR *argvW[]) * If there is an AUTOEXEC.BAT file, try to execute it. */ - GetFullPathName (autoexec, sizeof(string)/sizeof(WCHAR), string, NULL); - h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + GetFullPathNameW (autoexec, sizeof(string)/sizeof(WCHAR), string, NULL); + h = CreateFileW(string, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h != INVALID_HANDLE_VALUE) { CloseHandle (h); #if 0 diff --git a/programs/net/Makefile.in b/programs/net/Makefile.in index 4f6f6fc7350..cf30dced26b 100644 --- a/programs/net/Makefile.in +++ b/programs/net/Makefile.in @@ -5,6 +5,7 @@ VPATH = @srcdir@ MODULE = net.exe APPMODE = -mconsole IMPORTS = netapi32 user32 advapi32 kernel32 +EXTRADEFS = -DWINE_NO_UNICODE_MACROS C_SRCS = net.c diff --git a/programs/net/net.c b/programs/net/net.c index 89279fd5f34..e5e47c88320 100644 --- a/programs/net/net.c +++ b/programs/net/net.c @@ -30,7 +30,7 @@ static int output_string(int msg, ...) char msg_buffer[8192]; va_list arguments; - LoadString(GetModuleHandle(NULL), msg, msg_buffer, sizeof(msg_buffer)); + LoadStringA(GetModuleHandleW(NULL), msg, msg_buffer, sizeof(msg_buffer)); va_start(arguments, msg); vprintf(msg_buffer, arguments); va_end(arguments); @@ -92,24 +92,24 @@ static BOOL net_use(int argc, char *argv[]) static BOOL StopService(SC_HANDLE SCManager, SC_HANDLE serviceHandle) { - LPENUM_SERVICE_STATUS dependencies = NULL; + LPENUM_SERVICE_STATUSW dependencies = NULL; DWORD buffer_size = 0; DWORD count = 0, counter; BOOL result; SC_HANDLE dependent_serviceHandle; SERVICE_STATUS_PROCESS ssp; - result = EnumDependentServices(serviceHandle, SERVICE_ACTIVE, dependencies, buffer_size, &buffer_size, &count); + result = EnumDependentServicesW(serviceHandle, SERVICE_ACTIVE, dependencies, buffer_size, &buffer_size, &count); if(!result && (GetLastError() == ERROR_MORE_DATA)) { dependencies = HeapAlloc(GetProcessHeap(), 0, buffer_size); - if(EnumDependentServices(serviceHandle, SERVICE_ACTIVE, dependencies, buffer_size, &buffer_size, &count)) + if(EnumDependentServicesW(serviceHandle, SERVICE_ACTIVE, dependencies, buffer_size, &buffer_size, &count)) { for(counter = 0; counter < count; counter++) { output_string(STRING_STOP_DEP, dependencies[counter].lpDisplayName); - dependent_serviceHandle = OpenService(SCManager, dependencies[counter].lpServiceName, SC_MANAGER_ALL_ACCESS); + dependent_serviceHandle = OpenServiceW(SCManager, dependencies[counter].lpServiceName, SC_MANAGER_ALL_ACCESS); if(dependent_serviceHandle) result = StopService(SCManager, dependent_serviceHandle); CloseServiceHandle(dependent_serviceHandle); if(!result) output_string(STRING_CANT_STOP, dependencies[counter].lpDisplayName); @@ -129,13 +129,13 @@ static BOOL net_service(int operation, char *service_name) char service_display_name[4096]; DWORD buffer_size = sizeof(service_display_name); - SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + SCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!SCManager) { output_string(STRING_NO_SCM); return FALSE; } - serviceHandle = OpenService(SCManager, service_name, SC_MANAGER_ALL_ACCESS); + serviceHandle = OpenServiceA(SCManager, service_name, SC_MANAGER_ALL_ACCESS); if(!serviceHandle) { output_string(STRING_NO_SVCHANDLE); @@ -144,14 +144,14 @@ static BOOL net_service(int operation, char *service_name) } - GetServiceDisplayName(SCManager, service_name, service_display_name, &buffer_size); + GetServiceDisplayNameA(SCManager, service_name, service_display_name, &buffer_size); if (!service_display_name[0]) strcpy(service_display_name, service_name); switch(operation) { case NET_START: output_string(STRING_START_SVC, service_display_name); - result = StartService(serviceHandle, 0, NULL); + result = StartServiceW(serviceHandle, 0, NULL); if(result) output_string(STRING_START_SVC_SUCCESS, service_display_name); else diff --git a/programs/reg/reg.c b/programs/reg/reg.c index f0a8f8bd176..07dbdbff367 100644 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -255,7 +255,8 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, /* FIXME: Prompt for delete */ } - if (!value_name) + /* Delete subtree only if no /v* option is given */ + if (!value_name && !value_empty && !value_all) { if (RegDeleteTreeW(root,p)!=ERROR_SUCCESS) { @@ -293,10 +294,10 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, while (1) { count = maxValue; - rc = RegEnumValueW(subkey, 0, value_name, &count, NULL, NULL, NULL, NULL); + rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL); if (rc == ERROR_SUCCESS) { - rc = RegDeleteValueW(subkey,value_name); + rc = RegDeleteValueW(subkey, szValue); if (rc != ERROR_SUCCESS) break; } diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 6327c9ae9fd..c647cc82867 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -84,6 +84,21 @@ struct sc_lock struct scmdatabase *db; }; +static void free_config_strings(QUERY_SERVICE_CONFIGW *old_cfg, QUERY_SERVICE_CONFIGW *new_cfg) +{ + if (old_cfg->lpBinaryPathName != new_cfg->lpBinaryPathName) + HeapFree(GetProcessHeap(), 0, old_cfg->lpBinaryPathName); + + if (old_cfg->lpLoadOrderGroup != new_cfg->lpLoadOrderGroup) + HeapFree(GetProcessHeap(), 0, old_cfg->lpLoadOrderGroup); + + if (old_cfg->lpServiceStartName != new_cfg->lpServiceStartName) + HeapFree(GetProcessHeap(), 0, old_cfg->lpServiceStartName); + + if (old_cfg->lpDisplayName != new_cfg->lpDisplayName) + HeapFree(GetProcessHeap(), 0, old_cfg->lpDisplayName); +} + /* Check if the given handle is of the required type and allows the requested access. */ static DWORD validate_context_handle(SC_RPC_HANDLE handle, DWORD type, DWORD needed_access, struct sc_handle **out_hdr) { @@ -546,34 +561,28 @@ DWORD svcctl_ChangeServiceConfigW( /* configuration OK. The strings needs to be duplicated */ if (lpBinaryPathName != NULL) - { - HeapFree(GetProcessHeap(), 0, service->service_entry->config.lpBinaryPathName); new_entry.config.lpBinaryPathName = strdupW(lpBinaryPathName); - } if (lpLoadOrderGroup != NULL) - { - HeapFree(GetProcessHeap(), 0, service->service_entry->config.lpLoadOrderGroup); new_entry.config.lpLoadOrderGroup = strdupW(lpLoadOrderGroup); - } if (lpServiceStartName != NULL) - { - HeapFree(GetProcessHeap(), 0, service->service_entry->config.lpServiceStartName); new_entry.config.lpServiceStartName = strdupW(lpServiceStartName); - } if (lpDisplayName != NULL) - { - HeapFree(GetProcessHeap(), 0, service->service_entry->config.lpDisplayName); new_entry.config.lpDisplayName = strdupW(lpDisplayName); - } - *service->service_entry = new_entry; - save_service_config(service->service_entry); + /* try to save to Registry, commit or rollback depending on success */ + err = save_service_config(&new_entry); + if (ERROR_SUCCESS == err) + { + free_config_strings(&service->service_entry->config,&new_entry.config); + *service->service_entry = new_entry; + } + else free_config_strings(&new_entry.config,&service->service_entry->config); service_unlock(service->service_entry); - return ERROR_SUCCESS; + return err; } DWORD svcctl_SetServiceStatus( diff --git a/programs/services/services.c b/programs/services/services.c index 24230e43fac..d6f5e6dd355 100644 --- a/programs/services/services.c +++ b/programs/services/services.c @@ -376,7 +376,7 @@ static DWORD scmdatabase_create(struct scmdatabase **db) InitializeCriticalSection(&(*db)->cs); err = RegCreateKeyExW(HKEY_LOCAL_MACHINE, SZ_SERVICES_KEY, 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, + REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &(*db)->root_key, NULL); if (err != ERROR_SUCCESS) HeapFree(GetProcessHeap(), 0, *db); @@ -417,7 +417,7 @@ static DWORD scmdatabase_load_services(struct scmdatabase *db) break; WINE_TRACE("Loading service %s\n", wine_dbgstr_w(szName)); - err = RegOpenKeyExW(db->root_key, szName, 0, KEY_READ | KEY_WRITE, &hServiceKey); + err = RegOpenKeyExW(db->root_key, szName, 0, KEY_READ, &hServiceKey); if (err == ERROR_SUCCESS) { err = load_service_config(hServiceKey, entry); diff --git a/programs/wineboot/shutdown.c b/programs/wineboot/shutdown.c index 49c03c24137..ed80bf03477 100644 --- a/programs/wineboot/shutdown.c +++ b/programs/wineboot/shutdown.c @@ -31,7 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wineboot); #define MESSAGE_TIMEOUT 5000 -#define PROCQUIT_TIMEOUT 20000 struct window_info { @@ -278,12 +277,13 @@ static DWORD_PTR send_end_session_messages( struct window_info *win, UINT count, return 1; } - /* wait for app to quit on its own for a while */ - ret = WaitForSingleObject( process_handle, PROCQUIT_TIMEOUT ); + /* Check whether the app quit on its own */ + ret = WaitForSingleObject( process_handle, 0 ); CloseHandle( process_handle ); if (ret == WAIT_TIMEOUT) { - /* it didn't quit by itself in time, so terminate it with extreme prejudice */ + /* If not, it returned from all WM_ENDSESSION and is finished cleaning + * up, so we can safely kill the process. */ HANDLE handle = OpenProcess( PROCESS_TERMINATE, FALSE, win[0].pid ); if (handle) { diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index 2587ef58ce5..60a51b704ff 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -956,7 +956,7 @@ int main( int argc, char *argv[] ) { switch(optc) { - case 'e': end_session = kill = 1; break; + case 'e': end_session = 1; break; case 'f': force = 1; break; case 'i': init = 1; break; case 'k': kill = 1; break; diff --git a/programs/winedbg/Makefile.in b/programs/winedbg/Makefile.in index f23298c2394..cf730580f73 100644 --- a/programs/winedbg/Makefile.in +++ b/programs/winedbg/Makefile.in @@ -7,6 +7,7 @@ APPMODE = -mconsole IMPORTS = psapi dbghelp advapi32 kernel32 ntdll DELAYIMPORTS = user32 gdi32 EXTRALIBS = @LIBPOLL@ +EXTRADEFS = -DWINE_NO_UNICODE_MACROS C_SRCS = \ be_alpha.c \ @@ -33,6 +34,7 @@ C_SRCS = \ RC_SRCS = \ rsrc_De.rc \ rsrc_En.rc \ + rsrc_Es.rc \ rsrc_Fr.rc \ rsrc_Ko.rc \ rsrc_Lt.rc \ diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c index c22ef145318..e3e7a8168e9 100644 --- a/programs/winedbg/be_i386.c +++ b/programs/winedbg/be_i386.c @@ -253,40 +253,40 @@ static void be_i386_print_segment_info(HANDLE hThread, const CONTEXT* ctx) static struct dbg_internal_var be_i386_ctx[] = { - {CV_REG_AL, "AL", (DWORD*)FIELD_OFFSET(CONTEXT, Eax), dbg_itype_unsigned_char_int}, - {CV_REG_CL, "CL", (DWORD*)FIELD_OFFSET(CONTEXT, Ecx), dbg_itype_unsigned_char_int}, - {CV_REG_DL, "DL", (DWORD*)FIELD_OFFSET(CONTEXT, Edx), dbg_itype_unsigned_char_int}, - {CV_REG_BL, "BL", (DWORD*)FIELD_OFFSET(CONTEXT, Ebx), dbg_itype_unsigned_char_int}, - {CV_REG_AH, "AH", (DWORD*)(FIELD_OFFSET(CONTEXT, Eax)+1), dbg_itype_unsigned_char_int}, - {CV_REG_CH, "CH", (DWORD*)(FIELD_OFFSET(CONTEXT, Ecx)+1), dbg_itype_unsigned_char_int}, - {CV_REG_DH, "DH", (DWORD*)(FIELD_OFFSET(CONTEXT, Edx)+1), dbg_itype_unsigned_char_int}, - {CV_REG_BH, "BH", (DWORD*)(FIELD_OFFSET(CONTEXT, Ebx)+1), dbg_itype_unsigned_char_int}, - {CV_REG_AX, "AX", (DWORD*)FIELD_OFFSET(CONTEXT, Eax), dbg_itype_unsigned_short_int}, - {CV_REG_CX, "CX", (DWORD*)FIELD_OFFSET(CONTEXT, Ecx), dbg_itype_unsigned_short_int}, - {CV_REG_DX, "DX", (DWORD*)FIELD_OFFSET(CONTEXT, Edx), dbg_itype_unsigned_short_int}, - {CV_REG_BX, "BX", (DWORD*)FIELD_OFFSET(CONTEXT, Ebx), dbg_itype_unsigned_short_int}, - {CV_REG_SP, "SP", (DWORD*)FIELD_OFFSET(CONTEXT, Esp), dbg_itype_unsigned_short_int}, - {CV_REG_BP, "BP", (DWORD*)FIELD_OFFSET(CONTEXT, Ebp), dbg_itype_unsigned_short_int}, - {CV_REG_SI, "SI", (DWORD*)FIELD_OFFSET(CONTEXT, Esi), dbg_itype_unsigned_short_int}, - {CV_REG_DI, "DI", (DWORD*)FIELD_OFFSET(CONTEXT, Edi), dbg_itype_unsigned_short_int}, - {CV_REG_EAX, "EAX", (DWORD*)FIELD_OFFSET(CONTEXT, Eax), dbg_itype_unsigned_int}, - {CV_REG_ECX, "ECX", (DWORD*)FIELD_OFFSET(CONTEXT, Ecx), dbg_itype_unsigned_int}, - {CV_REG_EDX, "EDX", (DWORD*)FIELD_OFFSET(CONTEXT, Edx), dbg_itype_unsigned_int}, - {CV_REG_EBX, "EBX", (DWORD*)FIELD_OFFSET(CONTEXT, Ebx), dbg_itype_unsigned_int}, - {CV_REG_ESP, "ESP", (DWORD*)FIELD_OFFSET(CONTEXT, Esp), dbg_itype_unsigned_int}, - {CV_REG_EBP, "EBP", (DWORD*)FIELD_OFFSET(CONTEXT, Ebp), dbg_itype_unsigned_int}, - {CV_REG_ESI, "ESI", (DWORD*)FIELD_OFFSET(CONTEXT, Esi), dbg_itype_unsigned_int}, - {CV_REG_EDI, "EDI", (DWORD*)FIELD_OFFSET(CONTEXT, Edi), dbg_itype_unsigned_int}, - {CV_REG_ES, "ES", (DWORD*)FIELD_OFFSET(CONTEXT, SegEs), dbg_itype_unsigned_short_int}, - {CV_REG_CS, "CS", (DWORD*)FIELD_OFFSET(CONTEXT, SegCs), dbg_itype_unsigned_short_int}, - {CV_REG_SS, "SS", (DWORD*)FIELD_OFFSET(CONTEXT, SegSs), dbg_itype_unsigned_short_int}, - {CV_REG_DS, "DS", (DWORD*)FIELD_OFFSET(CONTEXT, SegDs), dbg_itype_unsigned_short_int}, - {CV_REG_FS, "FS", (DWORD*)FIELD_OFFSET(CONTEXT, SegFs), dbg_itype_unsigned_short_int}, - {CV_REG_GS, "GS", (DWORD*)FIELD_OFFSET(CONTEXT, SegGs), dbg_itype_unsigned_short_int}, - {CV_REG_IP, "IP", (DWORD*)FIELD_OFFSET(CONTEXT, Eip), dbg_itype_unsigned_short_int}, - {CV_REG_FLAGS, "FLAGS", (DWORD*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_short_int}, - {CV_REG_EIP, "EIP", (DWORD*)FIELD_OFFSET(CONTEXT, Eip), dbg_itype_unsigned_int}, - {CV_REG_EFLAGS, "EFLAGS", (DWORD*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_int}, + {CV_REG_AL, "AL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eax), dbg_itype_unsigned_char_int}, + {CV_REG_CL, "CL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ecx), dbg_itype_unsigned_char_int}, + {CV_REG_DL, "DL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edx), dbg_itype_unsigned_char_int}, + {CV_REG_BL, "BL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebx), dbg_itype_unsigned_char_int}, + {CV_REG_AH, "AH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Eax)+1), dbg_itype_unsigned_char_int}, + {CV_REG_CH, "CH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Ecx)+1), dbg_itype_unsigned_char_int}, + {CV_REG_DH, "DH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Edx)+1), dbg_itype_unsigned_char_int}, + {CV_REG_BH, "BH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Ebx)+1), dbg_itype_unsigned_char_int}, + {CV_REG_AX, "AX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eax), dbg_itype_unsigned_short_int}, + {CV_REG_CX, "CX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ecx), dbg_itype_unsigned_short_int}, + {CV_REG_DX, "DX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edx), dbg_itype_unsigned_short_int}, + {CV_REG_BX, "BX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebx), dbg_itype_unsigned_short_int}, + {CV_REG_SP, "SP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esp), dbg_itype_unsigned_short_int}, + {CV_REG_BP, "BP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebp), dbg_itype_unsigned_short_int}, + {CV_REG_SI, "SI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esi), dbg_itype_unsigned_short_int}, + {CV_REG_DI, "DI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edi), dbg_itype_unsigned_short_int}, + {CV_REG_EAX, "EAX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eax), dbg_itype_unsigned_int}, + {CV_REG_ECX, "ECX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ecx), dbg_itype_unsigned_int}, + {CV_REG_EDX, "EDX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edx), dbg_itype_unsigned_int}, + {CV_REG_EBX, "EBX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebx), dbg_itype_unsigned_int}, + {CV_REG_ESP, "ESP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esp), dbg_itype_unsigned_int}, + {CV_REG_EBP, "EBP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebp), dbg_itype_unsigned_int}, + {CV_REG_ESI, "ESI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esi), dbg_itype_unsigned_int}, + {CV_REG_EDI, "EDI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edi), dbg_itype_unsigned_int}, + {CV_REG_ES, "ES", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegEs), dbg_itype_unsigned_short_int}, + {CV_REG_CS, "CS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegCs), dbg_itype_unsigned_short_int}, + {CV_REG_SS, "SS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegSs), dbg_itype_unsigned_short_int}, + {CV_REG_DS, "DS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegDs), dbg_itype_unsigned_short_int}, + {CV_REG_FS, "FS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegFs), dbg_itype_unsigned_short_int}, + {CV_REG_GS, "GS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegGs), dbg_itype_unsigned_short_int}, + {CV_REG_IP, "IP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eip), dbg_itype_unsigned_short_int}, + {CV_REG_FLAGS, "FLAGS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_short_int}, + {CV_REG_EIP, "EIP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eip), dbg_itype_unsigned_int}, + {CV_REG_EFLAGS, "EFLAGS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_int}, {0, NULL, 0, dbg_itype_none} }; @@ -295,7 +295,7 @@ static const struct dbg_internal_var* be_i386_init_registers(CONTEXT* ctx) struct dbg_internal_var* div; for (div = be_i386_ctx; div->name; div++) - div->pval = (DWORD*)((char*)ctx + (DWORD)div->pval); + div->pval = (DWORD_PTR*)((char*)ctx + (DWORD)div->pval); return be_i386_ctx; } diff --git a/programs/winedbg/be_x86_64.c b/programs/winedbg/be_x86_64.c index 56af50fad92..dc1f2277fa9 100644 --- a/programs/winedbg/be_x86_64.c +++ b/programs/winedbg/be_x86_64.c @@ -97,55 +97,55 @@ static void be_x86_64_print_segment_info(HANDLE hThread, const CONTEXT* ctx) static struct dbg_internal_var be_x86_64_ctx[] = { - {CV_AMD64_AL, "AL", (DWORD*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_char_int}, - {CV_AMD64_BL, "BL", (DWORD*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_char_int}, - {CV_AMD64_CL, "CL", (DWORD*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_char_int}, - {CV_AMD64_DL, "DL", (DWORD*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_char_int}, - {CV_AMD64_AH, "AH", (DWORD*)(FIELD_OFFSET(CONTEXT, Rax)+1), dbg_itype_unsigned_char_int}, - {CV_AMD64_BH, "BH", (DWORD*)(FIELD_OFFSET(CONTEXT, Rbx)+1), dbg_itype_unsigned_char_int}, - {CV_AMD64_CH, "CH", (DWORD*)(FIELD_OFFSET(CONTEXT, Rcx)+1), dbg_itype_unsigned_char_int}, - {CV_AMD64_DH, "DH", (DWORD*)(FIELD_OFFSET(CONTEXT, Rdx)+1), dbg_itype_unsigned_char_int}, - {CV_AMD64_AX, "AX", (DWORD*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_short_int}, - {CV_AMD64_BX, "BX", (DWORD*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_short_int}, - {CV_AMD64_CX, "CX", (DWORD*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_short_int}, - {CV_AMD64_DX, "DX", (DWORD*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_short_int}, - {CV_AMD64_SP, "SP", (DWORD*)FIELD_OFFSET(CONTEXT, Rsp), dbg_itype_unsigned_short_int}, - {CV_AMD64_BP, "BP", (DWORD*)FIELD_OFFSET(CONTEXT, Rbp), dbg_itype_unsigned_short_int}, - {CV_AMD64_SI, "SI", (DWORD*)FIELD_OFFSET(CONTEXT, Rsi), dbg_itype_unsigned_short_int}, - {CV_AMD64_DI, "DI", (DWORD*)FIELD_OFFSET(CONTEXT, Rdi), dbg_itype_unsigned_short_int}, - {CV_AMD64_EAX, "EAX", (DWORD*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_int}, - {CV_AMD64_EBX, "EBX", (DWORD*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_int}, - {CV_AMD64_ECX, "ECX", (DWORD*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_int}, - {CV_AMD64_EDX, "EDX", (DWORD*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_int}, - {CV_AMD64_ESP, "ESP", (DWORD*)FIELD_OFFSET(CONTEXT, Rsp), dbg_itype_unsigned_int}, - {CV_AMD64_EBP, "EBP", (DWORD*)FIELD_OFFSET(CONTEXT, Rbp), dbg_itype_unsigned_int}, - {CV_AMD64_ESI, "ESI", (DWORD*)FIELD_OFFSET(CONTEXT, Rsi), dbg_itype_unsigned_int}, - {CV_AMD64_EDI, "EDI", (DWORD*)FIELD_OFFSET(CONTEXT, Rdi), dbg_itype_unsigned_int}, - {CV_AMD64_ES, "ES", (DWORD*)FIELD_OFFSET(CONTEXT, SegEs), dbg_itype_unsigned_short_int}, - {CV_AMD64_CS, "CS", (DWORD*)FIELD_OFFSET(CONTEXT, SegCs), dbg_itype_unsigned_short_int}, - {CV_AMD64_SS, "SS", (DWORD*)FIELD_OFFSET(CONTEXT, SegSs), dbg_itype_unsigned_short_int}, - {CV_AMD64_DS, "DS", (DWORD*)FIELD_OFFSET(CONTEXT, SegDs), dbg_itype_unsigned_short_int}, - {CV_AMD64_FS, "FS", (DWORD*)FIELD_OFFSET(CONTEXT, SegFs), dbg_itype_unsigned_short_int}, - {CV_AMD64_GS, "GS", (DWORD*)FIELD_OFFSET(CONTEXT, SegGs), dbg_itype_unsigned_short_int}, - {CV_AMD64_FLAGS, "FLAGS", (DWORD*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_short_int}, - {CV_AMD64_EFLAGS, "EFLAGS", (DWORD*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_int}, - {CV_AMD64_RIP, "RIP", (DWORD*)FIELD_OFFSET(CONTEXT, Rip), dbg_itype_unsigned_int}, - {CV_AMD64_RAX, "RAX", (DWORD*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_long_int}, - {CV_AMD64_RBX, "RBX", (DWORD*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_long_int}, - {CV_AMD64_RCX, "RCX", (DWORD*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_long_int}, - {CV_AMD64_RDX, "RDX", (DWORD*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_long_int}, - {CV_AMD64_RSP, "RSP", (DWORD*)FIELD_OFFSET(CONTEXT, Rsp), dbg_itype_unsigned_long_int}, - {CV_AMD64_RBP, "RBP", (DWORD*)FIELD_OFFSET(CONTEXT, Rbp), dbg_itype_unsigned_long_int}, - {CV_AMD64_RSI, "RSI", (DWORD*)FIELD_OFFSET(CONTEXT, Rsi), dbg_itype_unsigned_long_int}, - {CV_AMD64_RDI, "RDI", (DWORD*)FIELD_OFFSET(CONTEXT, Rdi), dbg_itype_unsigned_long_int}, - {CV_AMD64_R8, "R8", (DWORD*)FIELD_OFFSET(CONTEXT, R8), dbg_itype_unsigned_long_int}, - {CV_AMD64_R9, "R9", (DWORD*)FIELD_OFFSET(CONTEXT, R9), dbg_itype_unsigned_long_int}, - {CV_AMD64_R10, "R10", (DWORD*)FIELD_OFFSET(CONTEXT, R10), dbg_itype_unsigned_long_int}, - {CV_AMD64_R11, "R11", (DWORD*)FIELD_OFFSET(CONTEXT, R11), dbg_itype_unsigned_long_int}, - {CV_AMD64_R12, "R12", (DWORD*)FIELD_OFFSET(CONTEXT, R12), dbg_itype_unsigned_long_int}, - {CV_AMD64_R13, "R13", (DWORD*)FIELD_OFFSET(CONTEXT, R13), dbg_itype_unsigned_long_int}, - {CV_AMD64_R14, "R14", (DWORD*)FIELD_OFFSET(CONTEXT, R14), dbg_itype_unsigned_long_int}, - {CV_AMD64_R15, "R15", (DWORD*)FIELD_OFFSET(CONTEXT, R15), dbg_itype_unsigned_long_int}, + {CV_AMD64_AL, "AL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_char_int}, + {CV_AMD64_BL, "BL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_char_int}, + {CV_AMD64_CL, "CL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_char_int}, + {CV_AMD64_DL, "DL", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_char_int}, + {CV_AMD64_AH, "AH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Rax)+1), dbg_itype_unsigned_char_int}, + {CV_AMD64_BH, "BH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Rbx)+1), dbg_itype_unsigned_char_int}, + {CV_AMD64_CH, "CH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Rcx)+1), dbg_itype_unsigned_char_int}, + {CV_AMD64_DH, "DH", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Rdx)+1), dbg_itype_unsigned_char_int}, + {CV_AMD64_AX, "AX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_short_int}, + {CV_AMD64_BX, "BX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_short_int}, + {CV_AMD64_CX, "CX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_short_int}, + {CV_AMD64_DX, "DX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_short_int}, + {CV_AMD64_SP, "SP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rsp), dbg_itype_unsigned_short_int}, + {CV_AMD64_BP, "BP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbp), dbg_itype_unsigned_short_int}, + {CV_AMD64_SI, "SI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rsi), dbg_itype_unsigned_short_int}, + {CV_AMD64_DI, "DI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdi), dbg_itype_unsigned_short_int}, + {CV_AMD64_EAX, "EAX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_int}, + {CV_AMD64_EBX, "EBX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_int}, + {CV_AMD64_ECX, "ECX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_int}, + {CV_AMD64_EDX, "EDX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_int}, + {CV_AMD64_ESP, "ESP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rsp), dbg_itype_unsigned_int}, + {CV_AMD64_EBP, "EBP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbp), dbg_itype_unsigned_int}, + {CV_AMD64_ESI, "ESI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rsi), dbg_itype_unsigned_int}, + {CV_AMD64_EDI, "EDI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdi), dbg_itype_unsigned_int}, + {CV_AMD64_ES, "ES", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegEs), dbg_itype_unsigned_short_int}, + {CV_AMD64_CS, "CS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegCs), dbg_itype_unsigned_short_int}, + {CV_AMD64_SS, "SS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegSs), dbg_itype_unsigned_short_int}, + {CV_AMD64_DS, "DS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegDs), dbg_itype_unsigned_short_int}, + {CV_AMD64_FS, "FS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegFs), dbg_itype_unsigned_short_int}, + {CV_AMD64_GS, "GS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegGs), dbg_itype_unsigned_short_int}, + {CV_AMD64_FLAGS, "FLAGS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_short_int}, + {CV_AMD64_EFLAGS, "EFLAGS", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, EFlags), dbg_itype_unsigned_int}, + {CV_AMD64_RIP, "RIP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rip), dbg_itype_unsigned_int}, + {CV_AMD64_RAX, "RAX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rax), dbg_itype_unsigned_long_int}, + {CV_AMD64_RBX, "RBX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbx), dbg_itype_unsigned_long_int}, + {CV_AMD64_RCX, "RCX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rcx), dbg_itype_unsigned_long_int}, + {CV_AMD64_RDX, "RDX", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdx), dbg_itype_unsigned_long_int}, + {CV_AMD64_RSP, "RSP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rsp), dbg_itype_unsigned_long_int}, + {CV_AMD64_RBP, "RBP", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rbp), dbg_itype_unsigned_long_int}, + {CV_AMD64_RSI, "RSI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rsi), dbg_itype_unsigned_long_int}, + {CV_AMD64_RDI, "RDI", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Rdi), dbg_itype_unsigned_long_int}, + {CV_AMD64_R8, "R8", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R8), dbg_itype_unsigned_long_int}, + {CV_AMD64_R9, "R9", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R9), dbg_itype_unsigned_long_int}, + {CV_AMD64_R10, "R10", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R10), dbg_itype_unsigned_long_int}, + {CV_AMD64_R11, "R11", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R11), dbg_itype_unsigned_long_int}, + {CV_AMD64_R12, "R12", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R12), dbg_itype_unsigned_long_int}, + {CV_AMD64_R13, "R13", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R13), dbg_itype_unsigned_long_int}, + {CV_AMD64_R14, "R14", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R14), dbg_itype_unsigned_long_int}, + {CV_AMD64_R15, "R15", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, R15), dbg_itype_unsigned_long_int}, {0, NULL, 0, dbg_itype_none} }; @@ -154,7 +154,7 @@ static const struct dbg_internal_var* be_x86_64_init_registers(CONTEXT* ctx) struct dbg_internal_var* div; for (div = be_x86_64_ctx; div->name; div++) - div->pval = (DWORD*)((char*)ctx + (DWORD_PTR)div->pval); + div->pval = (DWORD_PTR*)((char*)ctx + (DWORD_PTR)div->pval); return be_x86_64_ctx; } diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c index ddb75a2d188..accf17b3571 100644 --- a/programs/winedbg/break.c +++ b/programs/winedbg/break.c @@ -303,12 +303,12 @@ void break_add_break_from_lineno(int lineno, BOOL swbp) DWORD disp; - DWORD linear = (DWORD)memory_to_linear_addr(&bkln.addr); + DWORD_PTR linear = (DWORD_PTR)memory_to_linear_addr(&bkln.addr); il.SizeOfStruct = sizeof(il); if (!SymGetLineFromAddr(dbg_curr_process->handle, linear, &disp, &il)) { - dbg_printf("Unable to add breakpoint (unknown address %x)\n", linear); + dbg_printf("Unable to add breakpoint (unknown address %lx)\n", linear); return; } bkln.addr.Offset = 0; @@ -475,8 +475,8 @@ static inline BOOL module_is_container(const IMAGEHLP_MODULE* wmod_cntnr, const IMAGEHLP_MODULE* wmod_child) { return wmod_cntnr->BaseOfImage <= wmod_child->BaseOfImage && - (DWORD)wmod_cntnr->BaseOfImage + wmod_cntnr->ImageSize >= - (DWORD)wmod_child->BaseOfImage + wmod_child->ImageSize; + wmod_cntnr->BaseOfImage + wmod_cntnr->ImageSize >= + wmod_child->BaseOfImage + wmod_child->ImageSize; } /****************************************************************** @@ -488,7 +488,7 @@ void break_delete_xpoints_from_module(unsigned long base) { IMAGEHLP_MODULE im, im_elf; int i; - DWORD linear; + DWORD_PTR linear; struct dbg_breakpoint* bp = dbg_curr_process->bp; /* FIXME: should do it also on the ELF sibbling if any */ @@ -499,12 +499,12 @@ void break_delete_xpoints_from_module(unsigned long base) /* try to get in fact the underlying ELF module (if any) */ if (SymGetModuleInfo(dbg_curr_process->handle, im.BaseOfImage - 1, &im_elf) && im_elf.BaseOfImage <= im.BaseOfImage && - (DWORD)im_elf.BaseOfImage + im_elf.ImageSize >= (DWORD)im.BaseOfImage + im.ImageSize) + im_elf.BaseOfImage + im_elf.ImageSize >= im.BaseOfImage + im.ImageSize) im = im_elf; for (i = 0; i < dbg_curr_process->next_bp; i++) { - linear = (DWORD)memory_to_linear_addr(&bp[i].addr); + linear = (DWORD_PTR)memory_to_linear_addr(&bp[i].addr); if (bp[i].refcount && bp[i].enabled && im.BaseOfImage <= linear && linear < im.BaseOfImage + im.ImageSize) { diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index 9b28fd1881c..ea4229d3459 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -45,7 +45,7 @@ static void parser(const char*); { struct dbg_lvalue lvalue; char* string; - int integer; + INT_PTR integer; IMAGEHLP_LINE listing; struct expr* expression; struct type_expr_t type; @@ -556,7 +556,7 @@ void parser_handle(HANDLE input) static void parser(const char* filename) { - HANDLE h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0L, 0); + HANDLE h = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0L, 0); if (h != INVALID_HANDLE_VALUE) { parser_handle(h); @@ -577,8 +577,8 @@ HANDLE parser_generate_command_file(const char* pmt, ...) DWORD w; const char* p; - GetTempPath(sizeof(path), path); - GetTempFileName(path, "WD", 0, file); + GetTempPathA(sizeof(path), path); + GetTempFileNameA(path, "WD", 0, file); hFile = CreateFileA(file, GENERIC_READ|GENERIC_WRITE|DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0); if (hFile != INVALID_HANDLE_VALUE) diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l index 0697f60aeab..9b1e4fa19a9 100644 --- a/programs/winedbg/debug.l +++ b/programs/winedbg/debug.l @@ -149,8 +149,8 @@ STRING \"[^\n"]+\" "[" { return *yytext; } "]" { return *yytext; } -"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &dbg_lval.integer); return tNUM; } -{DIGIT}+ { sscanf(yytext, "%d", &dbg_lval.integer); return tNUM; } +"0x"{HEXDIGIT}+ { sscanf(yytext, "%lx", &dbg_lval.integer); return tNUM; } +{DIGIT}+ { sscanf(yytext, "%ld", &dbg_lval.integer); return tNUM; } "/"{DIGIT}+{FORMAT} { char* last; dbg_lval.integer = strtol(yytext+1, &last, 0) << 8; diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 0c17fb8bd83..d0a06748b61 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -160,7 +160,7 @@ struct dbg_breakpoint typedef struct tagTHREADNAME_INFO { DWORD dwType; /* Must be 0x1000 */ - LPCTSTR szName; /* Pointer to name - limited to 9 bytes (8 characters + terminator) */ + LPCSTR szName; /* Pointer to name - limited to 9 bytes (8 characters + terminator) */ DWORD dwThreadID; /* Thread ID (-1 = caller thread) */ DWORD dwFlags; /* Reserved for future use. Must be zero. */ } THREADNAME_INFO; @@ -186,9 +186,9 @@ struct dbg_thread ADDRESS64 addr_pc; ADDRESS64 addr_frame; ADDRESS64 addr_stack; - DWORD linear_pc; - DWORD linear_frame; - DWORD linear_stack; + DWORD_PTR linear_pc; + DWORD_PTR linear_frame; + DWORD_PTR linear_stack; }* frames; int num_frames; int curr_frame; @@ -243,17 +243,17 @@ struct be_process_io }; extern struct dbg_process* dbg_curr_process; -extern DWORD dbg_curr_pid; +extern DWORD_PTR dbg_curr_pid; extern struct dbg_thread* dbg_curr_thread; -extern DWORD dbg_curr_tid; +extern DWORD_PTR dbg_curr_tid; extern CONTEXT dbg_context; extern BOOL dbg_interactiveP; struct dbg_internal_var { - DWORD val; + DWORD_PTR val; const char* name; - LPDWORD pval; + DWORD_PTR *pval; unsigned long typeid; /* always internal type */ }; @@ -362,7 +362,7 @@ extern BOOL memory_get_current_stack(ADDRESS64* address); extern BOOL memory_get_current_frame(ADDRESS64* address); extern BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size); extern BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size); -extern BOOL memory_get_register(DWORD regno, DWORD** value, char* buffer, int len); +extern BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len); extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count); extern BOOL memory_disasm_one_insn(ADDRESS64* addr); #define MAX_OFFSET_TO_STR_LEN 19 @@ -384,7 +384,7 @@ extern void stack_info(void); extern void stack_backtrace(DWORD threadID); extern BOOL stack_set_frame(int newframe); extern BOOL stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf); -extern BOOL stack_get_register_current_frame(unsigned regno, DWORD** pval); +extern BOOL stack_get_register_current_frame(unsigned regno, DWORD_PTR** pval); extern unsigned stack_fetch_frames(void); extern BOOL stack_get_current_symbol(SYMBOL_INFO* sym); @@ -394,7 +394,7 @@ extern void symbol_read_symtable(const char* filename, unsigned long extern enum dbg_line_status symbol_get_function_line_status(const ADDRESS64* addr); extern BOOL symbol_get_line(const char* filename, const char* func, IMAGEHLP_LINE* ret); extern void symbol_info(const char* str); -extern void symbol_print_local(const SYMBOL_INFO* sym, ULONG base, BOOL detailed); +extern void symbol_print_local(const SYMBOL_INFO* sym, ULONG_PTR base, BOOL detailed); extern int symbol_info_locals(void); extern BOOL symbol_is_local(const char* name); struct sgv_data; @@ -457,7 +457,7 @@ struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid, HANDLE h, vo extern struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid); extern void dbg_del_thread(struct dbg_thread* t); extern BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade); -extern BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD base, DWORD size); +extern BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size); extern BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod); extern void dbg_set_option(const char*, const char*); extern void dbg_start_interactive(HANDLE hFile); diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 4794b06dc1f..4a632325e72 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -1396,7 +1396,7 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx) { if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR) fprintf(stderr, "Wrong sizes %u <> %u\n", - ptr - gdbctx->in_packet + len * 2, gdbctx->in_packet_len); + (int)(ptr - gdbctx->in_packet) + len * 2, gdbctx->in_packet_len); return packet_error; } if (gdbctx->trace & GDBPXY_TRC_COMMAND) @@ -1468,13 +1468,14 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx) { if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR) fprintf(stderr, "Wrong sizes %u <> %u\n", - ptr + 8 - gdbctx->in_packet, gdbctx->in_packet_len); + (int)(ptr + 8 - gdbctx->in_packet), gdbctx->in_packet_len); return packet_error; } if (gdbctx->trace & GDBPXY_TRC_COMMAND) - fprintf(stderr, "Writing reg %u <= %*.*s\n", - reg, gdbctx->in_packet_len - (ptr - gdbctx->in_packet), - gdbctx->in_packet_len - (ptr - gdbctx->in_packet), ptr); + { + int len = gdbctx->in_packet_len - (ptr - gdbctx->in_packet); + fprintf(stderr, "Writing reg %u <= %*.*s\n", reg, len, len, ptr ); + } if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread) { @@ -1501,18 +1502,18 @@ static void packet_query_monitor_wnd_helper(struct gdb_context* gdbctx, HWND hWn HWND child; do { - if (!GetClassName(hWnd, clsName, sizeof(clsName))) + if (!GetClassNameA(hWnd, clsName, sizeof(clsName))) strcpy(clsName, "-- Unknown --"); - if (!GetWindowText(hWnd, wndName, sizeof(wndName))) + if (!GetWindowTextA(hWnd, wndName, sizeof(wndName))) strcpy(wndName, "-- Empty --"); packet_reply_open(gdbctx); packet_reply_catc(gdbctx, 'O'); snprintf(buffer, sizeof(buffer), - "%*s%04lx%*s%-17.17s %08x %08x %.14s\n", + "%*s%04lx%*s%-17.17s %08x %08lx %.14s\n", indent, "", (ULONG_PTR)hWnd, 13 - indent, "", - clsName, GetWindowLong(hWnd, GWL_STYLE), - GetWindowLongPtr(hWnd, GWLP_WNDPROC), wndName); + clsName, GetWindowLongW(hWnd, GWL_STYLE), + (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC), wndName); packet_reply_hex_to_str(gdbctx, buffer); packet_reply_close(gdbctx); diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index a6156b1bab1..87fbebdf51f 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -146,7 +146,7 @@ static const char* get_symtype_str(const IMAGEHLP_MODULE64* mi) struct info_module { IMAGEHLP_MODULE64* mi; - DWORD base; + DWORD_PTR _base; unsigned num_alloc; unsigned num_used; }; @@ -280,9 +280,9 @@ static void class_walker(HWND hWnd, struct class_walker* cw) ATOM atom; HWND child; - if (!GetClassName(hWnd, clsName, sizeof(clsName))) + if (!GetClassNameA(hWnd, clsName, sizeof(clsName))) return; - if ((atom = FindAtom(clsName)) == 0) + if ((atom = FindAtomA(clsName)) == 0) return; for (i = 0; i < cw->used; i++) @@ -310,7 +310,7 @@ static void class_walker(HWND hWnd, struct class_walker* cw) void info_win32_class(HWND hWnd, const char* name) { WNDCLASSEXA wca; - HINSTANCE hInst = hWnd ? (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE) : 0; + HINSTANCE hInst = hWnd ? (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE) : 0; if (!name) { @@ -323,7 +323,7 @@ void info_win32_class(HWND hWnd, const char* name) return; } - if (!GetClassInfoEx(hInst, name, &wca)) + if (!GetClassInfoExA(hInst, name, &wca)) { dbg_printf("Cannot find class '%s'\n", name); return; @@ -366,15 +366,15 @@ static void info_window(HWND hWnd, int indent) do { - if (!GetClassName(hWnd, clsName, sizeof(clsName))) + if (!GetClassNameA(hWnd, clsName, sizeof(clsName))) strcpy(clsName, "-- Unknown --"); - if (!GetWindowText(hWnd, wndName, sizeof(wndName))) + if (!GetWindowTextA(hWnd, wndName, sizeof(wndName))) strcpy(wndName, "-- Empty --"); - dbg_printf("%*s%08lx%*s %-17.17s %08x %08x %08x %.14s\n", + dbg_printf("%*s%08lx%*s %-17.17s %08x %08lx %08x %.14s\n", indent, "", (DWORD_PTR)hWnd, 12 - indent, "", - clsName, GetWindowLong(hWnd, GWL_STYLE), - GetWindowLongPtr(hWnd, GWLP_WNDPROC), + clsName, GetWindowLongW(hWnd, GWL_STYLE), + (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC), GetWindowThreadProcessId(hWnd, NULL), wndName); if ((child = GetWindow(hWnd, GW_CHILD)) != 0) @@ -400,9 +400,9 @@ void info_win32_window(HWND hWnd, BOOL detailed) return; } - if (!GetClassName(hWnd, clsName, sizeof(clsName))) + if (!GetClassNameA(hWnd, clsName, sizeof(clsName))) strcpy(clsName, "-- Unknown --"); - if (!GetWindowText(hWnd, wndName, sizeof(wndName))) + if (!GetWindowTextA(hWnd, wndName, sizeof(wndName))) strcpy(wndName, "-- Empty --"); if (!GetClientRect(hWnd, &clientRect) || !MapWindowPoints(hWnd, 0, (LPPOINT) &clientRect, 2)) @@ -412,31 +412,31 @@ void info_win32_window(HWND hWnd, BOOL detailed) /* FIXME missing fields: hmemTaskQ, hrgnUpdate, dce, flags, pProp, scroll */ dbg_printf("next=%p child=%p parent=%p owner=%p class='%s'\n" - "inst=%p active=%p idmenu=%08x\n" - "style=0x%08x exstyle=0x%08x wndproc=0x%08x text='%s'\n" + "inst=%p active=%p idmenu=%08lx\n" + "style=0x%08x exstyle=0x%08x wndproc=0x%08lx text='%s'\n" "client=%d,%d-%d,%d window=%d,%d-%d,%d sysmenu=%p\n", GetWindow(hWnd, GW_HWNDNEXT), GetWindow(hWnd, GW_CHILD), GetParent(hWnd), GetWindow(hWnd, GW_OWNER), clsName, - (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), + (HINSTANCE)GetWindowLongPtrW(hWnd, GWLP_HINSTANCE), GetLastActivePopup(hWnd), - GetWindowLongPtr(hWnd, GWLP_ID), - GetWindowLong(hWnd, GWL_STYLE), - GetWindowLong(hWnd, GWL_EXSTYLE), - GetWindowLongPtr(hWnd, GWLP_WNDPROC), + (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_ID), + GetWindowLongW(hWnd, GWL_STYLE), + GetWindowLongW(hWnd, GWL_EXSTYLE), + (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC), wndName, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom, windowRect.left, windowRect.top, windowRect.right, windowRect.bottom, GetSystemMenu(hWnd, FALSE)); - if (GetClassLong(hWnd, GCL_CBWNDEXTRA)) + if (GetClassLongW(hWnd, GCL_CBWNDEXTRA)) { UINT i; dbg_printf("Extra bytes:"); - for (i = 0; i < GetClassLong(hWnd, GCL_CBWNDEXTRA) / 2; i++) + for (i = 0; i < GetClassLongW(hWnd, GCL_CBWNDEXTRA) / 2; i++) { w = GetWindowWord(hWnd, i * 2); /* FIXME: depends on i386 endian-ity */ diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c index c103c18837b..c33291080c2 100644 --- a/programs/winedbg/memory.c +++ b/programs/winedbg/memory.c @@ -639,7 +639,7 @@ void memory_disassemble(const struct dbg_lvalue* xstart, memory_disasm_one_insn(&last); } -BOOL memory_get_register(DWORD regno, DWORD** value, char* buffer, int len) +BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len) { const struct dbg_internal_var* div; diff --git a/programs/winedbg/rsrc_Es.rc b/programs/winedbg/rsrc_Es.rc new file mode 100644 index 00000000000..f4f64cdbdfd --- /dev/null +++ b/programs/winedbg/rsrc_Es.rc @@ -0,0 +1,58 @@ +/* + * Spanish Language Support + * + * Copyright 2009 Jaime Rave + * + * 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 "resource.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT + +IDM_DEBUG_POPUP MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "&Depurar", ID_DEBUG + END +END + +IDD_CRASH_DLG DIALOGEX 100, 100, 273, 175 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Error del programa" +FONT 8, "Tahoma" +BEGIN + LTEXT "",IDC_STATIC_BG,0,0,273,52,WS_BORDER,0 + LTEXT "El programa %s ha encontrado un serio problema y necesita \ + cerrarse. Nos disculpamos por los inconvenientes.", + IDC_STATIC_TXT1,27,10,224,30 + LTEXT "Esto puede ser causado por un problema en el programa o a una deficiencia en Wine. \ + Quizá quieras verificar en http://appdb.winehq.org consejos sobre cómo ejecutar \ + esta aplicación.\n\n\ + Si este problema no esta presente en Windows y no ha sido reportado \ + todavía, lo puedes reportar en http://bugs.winehq.org.",IDC_STATIC_TXT2,27,60,224,100 + DEFPUSHBUTTON "Cerrar", IDOK, 205, 151, 60, 16, WS_TABSTOP +END + +STRINGTABLE +BEGIN + IDS_AUTO_CAPTION "Caida del programa Wine" + IDS_INVALID_PARAMS "Errores internos - parámetros invalidos recibidos" + IDS_UNIDENTIFIED "(no identificado)" +END diff --git a/programs/winedbg/source.c b/programs/winedbg/source.c index 72579e03490..95ec209cc64 100644 --- a/programs/winedbg/source.c +++ b/programs/winedbg/source.c @@ -44,7 +44,7 @@ void source_show_path(void) { next = strchr(ptr, ';'); if (next) - dbg_printf("\t%.*s\n", next++ - ptr, ptr); + dbg_printf("\t%.*s\n", (int)(next++ - ptr), ptr); else dbg_printf("\t%s\n", ptr); } @@ -84,11 +84,11 @@ static void* source_map_file(const char* name, HANDLE* hMap, unsigned* size) { HANDLE hFile; - hFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + hFile = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return (void*)-1; if (size != NULL && (*size = GetFileSize(hFile, NULL)) == -1) return (void*)-1; - *hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + *hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL); CloseHandle(hFile); if (!*hMap) return (void*)-1; return MapViewOfFile(*hMap, FILE_MAP_READ, 0, 0, 0); @@ -115,7 +115,7 @@ static BOOL source_locate_file(const char* srcfile, char* path) { BOOL found = FALSE; - if (GetFileAttributes(srcfile) != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesA(srcfile) != INVALID_FILE_ATTRIBUTES) { strcpy(path, srcfile); found = TRUE; @@ -216,7 +216,7 @@ static int source_display(const char* sourcefile, int start, int end) } else tmppath[0] = '\0'; - if (GetFileAttributes(tmppath) == INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesA(tmppath) == INVALID_FILE_ATTRIBUTES) { /* * OK, I guess the user doesn't really want to see it diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c index fbaf228c8ee..92ddd47ca2c 100644 --- a/programs/winedbg/stack.c +++ b/programs/winedbg/stack.c @@ -96,7 +96,7 @@ BOOL stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf) return stack_get_frame(dbg_curr_thread->curr_frame, ihsf); } -BOOL stack_get_register_current_frame(unsigned regno, DWORD** pval) +BOOL stack_get_register_current_frame(unsigned regno, DWORD_PTR** pval) { enum be_cpu_addr kind; @@ -194,11 +194,11 @@ unsigned stack_fetch_frames(void) (nf + 1) * sizeof(dbg_curr_thread->frames[0])); dbg_curr_thread->frames[nf].addr_pc = sf.AddrPC; - dbg_curr_thread->frames[nf].linear_pc = (DWORD)memory_to_linear_addr(&sf.AddrPC); + dbg_curr_thread->frames[nf].linear_pc = (DWORD_PTR)memory_to_linear_addr(&sf.AddrPC); dbg_curr_thread->frames[nf].addr_frame = sf.AddrFrame; - dbg_curr_thread->frames[nf].linear_frame = (DWORD)memory_to_linear_addr(&sf.AddrFrame); + dbg_curr_thread->frames[nf].linear_frame = (DWORD_PTR)memory_to_linear_addr(&sf.AddrFrame); dbg_curr_thread->frames[nf].addr_stack = sf.AddrStack; - dbg_curr_thread->frames[nf].linear_stack = (DWORD)memory_to_linear_addr(&sf.AddrStack); + dbg_curr_thread->frames[nf].linear_stack = (DWORD_PTR)memory_to_linear_addr(&sf.AddrStack); nf++; /* we've probably gotten ourselves into an infinite loop so bail */ if (nf > 200) break; @@ -211,7 +211,7 @@ unsigned stack_fetch_frames(void) struct sym_enum { - DWORD frame; + DWORD_PTR frame; BOOL first; }; @@ -390,7 +390,7 @@ static void backtrace_all(void) dbg_active_wait_for_first_exception(); } - dbg_printf("\nBacktracing for thread %04x in process %04x (%s):\n", + dbg_printf("\nBacktracing for thread %04x in process %04lx (%s):\n", entry.th32ThreadID, dbg_curr_pid, dbg_W2A(dbg_curr_process->imageName, -1)); backtrace_tid(dbg_curr_process, entry.th32ThreadID); diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c index abc7d2de12c..785e380876e 100644 --- a/programs/winedbg/symbol.c +++ b/programs/winedbg/symbol.c @@ -65,13 +65,13 @@ static BOOL symbol_get_debug_start(const struct dbg_type* func, ULONG64* start) return FALSE; } -static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG base, +static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base, struct dbg_lvalue* lvalue, char* buffer, size_t sz) { if (buffer) buffer[0] = '\0'; if (sym->Flags & SYMFLAG_REGISTER) { - DWORD* pval; + DWORD_PTR* pval; if (!memory_get_register(sym->Register, &pval, buffer, sz)) return FALSE; @@ -80,7 +80,7 @@ static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG base, } else if (sym->Flags & SYMFLAG_REGREL) { - DWORD* pval; + DWORD_PTR* pval; if (!memory_get_register(sym->Register, &pval, buffer, sz)) return FALSE; @@ -408,7 +408,7 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno, il.SizeOfStruct = sizeof(il); SymGetLineFromAddr(dbg_curr_process->handle, - (DWORD)memory_to_linear_addr(&sgv.syms[i].lvalue.addr), + (DWORD_PTR)memory_to_linear_addr(&sgv.syms[i].lvalue.addr), &disp, &il); do { @@ -524,7 +524,7 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS64* addr) IMAGEHLP_LINE il; DWORD disp; ULONG64 disp64, start; - DWORD lin = (DWORD)memory_to_linear_addr(addr); + DWORD_PTR lin = (DWORD_PTR)memory_to_linear_addr(addr); char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer; struct dbg_type func; @@ -579,7 +579,7 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line { struct sgv_data sgv; char buffer[512]; - DWORD opt, disp, linear; + DWORD opt, disp; unsigned i, found = FALSE; IMAGEHLP_LINE il; @@ -616,7 +616,7 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line for (i = 0; i < sgv.num; i++) { - linear = (DWORD)memory_to_linear_addr(&sgv.syms[i].lvalue.addr); + DWORD_PTR linear = (DWORD_PTR)memory_to_linear_addr(&sgv.syms[i].lvalue.addr); il.SizeOfStruct = sizeof(il); if (!SymGetLineFromAddr(dbg_curr_process->handle, linear, &disp, &il)) @@ -647,8 +647,7 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line * = (local|pmt ) in detailed form * Note can be an error message in case of error */ -void symbol_print_local(const SYMBOL_INFO* sym, ULONG base, - BOOL detailed) +void symbol_print_local(const SYMBOL_INFO* sym, ULONG_PTR base, BOOL detailed) { struct dbg_lvalue lvalue; char buffer[64]; @@ -682,7 +681,7 @@ static BOOL CALLBACK info_locals_cb(PSYMBOL_INFO sym, ULONG size, PVOID ctx) types_print_type(&type, FALSE); dbg_printf(" "); - symbol_print_local(sym, (ULONG)ctx, TRUE); + symbol_print_local(sym, (ULONG_PTR)ctx, TRUE); dbg_printf("\n"); return TRUE; diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index ff57f4602a3..23917e0cdc3 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -676,12 +676,12 @@ static void dbg_resume_debuggee(DWORD cont) if (dbg_curr_thread) { if (!SetThreadContext(dbg_curr_thread->handle, &dbg_context)) - dbg_printf("Cannot set ctx on %04x\n", dbg_curr_tid); + dbg_printf("Cannot set ctx on %04lx\n", dbg_curr_tid); } } dbg_interactiveP = FALSE; if (!ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, cont)) - dbg_printf("Cannot continue on %04x (%08x)\n", dbg_curr_tid, cont); + dbg_printf("Cannot continue on %04lx (%08x)\n", dbg_curr_tid, cont); } static void wait_exception(void) @@ -745,8 +745,8 @@ static unsigned dbg_start_debuggee(LPSTR cmdLine) flags = DEBUG_PROCESS | CREATE_NEW_CONSOLE; if (!DBG_IVAR(AlsoDebugProcChild)) flags |= DEBUG_ONLY_THIS_PROCESS; - if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, flags, - NULL, NULL, &startup, &info)) + if (!CreateProcessA(NULL, cmdLine, NULL, NULL, FALSE, flags, + NULL, NULL, &startup, &info)) { dbg_printf("Couldn't start process '%s'\n", cmdLine); return FALSE; @@ -796,7 +796,7 @@ void dbg_run_debuggee(const char* args) } } -static BOOL str2int(const char* str, DWORD* val) +static BOOL str2int(const char* str, DWORD_PTR* val) { char* ptr; @@ -813,7 +813,7 @@ static BOOL str2int(const char* str, DWORD* val) */ enum dbg_start dbg_active_attach(int argc, char* argv[]) { - DWORD pid, evt; + DWORD_PTR pid, evt; /* try the form pid */ if (argc == 1 && str2int(argv[0], &pid) && pid != 0) @@ -833,7 +833,7 @@ enum dbg_start dbg_active_attach(int argc, char* argv[]) } if (!SetEvent((HANDLE)evt)) { - WINE_ERR("Invalid event handle: %x\n", evt); + WINE_ERR("Invalid event handle: %lx\n", evt); return start_error_init; } CloseHandle((HANDLE)evt); @@ -950,8 +950,8 @@ enum dbg_start dbg_active_auto(int argc, char* argv[]) { char path[MAX_PATH]; - GetTempPath(sizeof(path), path); - GetTempFileName(path, "WD", 0, tmp + 10); + GetTempPathA(sizeof(path), path); + GetTempFileNameA(path, "WD", 0, tmp + 10); } else strcpy(tmp + 10, file); strcat(tmp, "\""); diff --git a/programs/winedbg/tgt_minidump.c b/programs/winedbg/tgt_minidump.c index 5d22bb6e0b8..7826b78b1ea 100644 --- a/programs/winedbg/tgt_minidump.c +++ b/programs/winedbg/tgt_minidump.c @@ -51,8 +51,8 @@ void minidump_write(const char* file, const EXCEPTION_RECORD* rec) MINIDUMP_EXCEPTION_INFORMATION mei; EXCEPTION_POINTERS ep; - hFile = CreateFile(file, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); + hFile = CreateFileA(file, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return; diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index 4a14143bf8a..50695aaf984 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -567,7 +567,7 @@ static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx) return TRUE; } -static BOOL CALLBACK print_types_mod_cb(PCSTR mod_name, ULONG base, PVOID ctx) +static BOOL CALLBACK print_types_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx) { return SymEnumTypes(dbg_curr_process->handle, base, print_types_cb, ctx); } @@ -579,7 +579,7 @@ int print_types(void) dbg_printf("No known process, cannot print types\n"); return 0; } - SymEnumerateModules(dbg_curr_process->handle, print_types_mod_cb, NULL); + SymEnumerateModules64(dbg_curr_process->handle, print_types_mod_cb, NULL); return 0; } diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index 55841486c5e..911cb6a5d26 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -88,8 +88,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedbg); struct dbg_process* dbg_curr_process = NULL; struct dbg_thread* dbg_curr_thread = NULL; -DWORD dbg_curr_tid; -DWORD dbg_curr_pid; +DWORD_PTR dbg_curr_tid = 0; +DWORD_PTR dbg_curr_pid = 0; CONTEXT dbg_context; BOOL dbg_interactiveP = FALSE; @@ -201,8 +201,8 @@ static unsigned dbg_load_internal_vars(void) { if (!dbg_internal_vars[i].pval) { - if (!RegQueryValueEx(hkey, dbg_internal_vars[i].name, 0, - &type, (LPBYTE)&val, &count)) + if (!RegQueryValueExA(hkey, dbg_internal_vars[i].name, 0, + &type, (LPBYTE)&val, &count)) dbg_internal_vars[i].val = val; dbg_internal_vars[i].pval = &dbg_internal_vars[i].val; } @@ -229,9 +229,9 @@ static unsigned dbg_save_internal_vars(void) { /* FIXME: type should be inferred from basic type -if any- of intvar */ if (dbg_internal_vars[i].pval == &dbg_internal_vars[i].val) - RegSetValueEx(hkey, dbg_internal_vars[i].name, 0, - REG_DWORD, (const void*)dbg_internal_vars[i].pval, - sizeof(*dbg_internal_vars[i].pval)); + RegSetValueExA(hkey, dbg_internal_vars[i].name, 0, + REG_DWORD, (const void*)dbg_internal_vars[i].pval, + sizeof(*dbg_internal_vars[i].pval)); } RegCloseKey(hkey); return TRUE; @@ -402,7 +402,7 @@ struct mod_loader_info IMAGEHLP_MODULE* imh_mod; }; -static BOOL CALLBACK mod_loader_cb(PCSTR mod_name, ULONG base, PVOID ctx) +static BOOL CALLBACK mod_loader_cb(PCSTR mod_name, DWORD64 base, PVOID ctx) { struct mod_loader_info* mli = ctx; @@ -429,13 +429,13 @@ BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod) * enumeration */ SymSetOptions((opt = SymGetOptions()) | 0x40000000); - SymEnumerateModules(hProcess, mod_loader_cb, (void*)&mli); + SymEnumerateModules64(hProcess, mod_loader_cb, (void*)&mli); SymSetOptions(opt); return imh_mod->BaseOfImage != 0; } -BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD base, DWORD size) +BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size) { BOOL ret = SymLoadModuleExW(hProc, NULL, name, NULL, base, size, NULL, 0); if (ret) @@ -565,7 +565,7 @@ void dbg_init_console(void) SetConsoleCtrlHandler(ctrl_c_handler, TRUE); /* set our own title */ - SetConsoleTitle("Wine Debugger"); + SetConsoleTitleA("Wine Debugger"); } static int dbg_winedbg_usage(BOOL advanced) @@ -594,7 +594,7 @@ void dbg_start_interactive(HANDLE hFile) { if (dbg_curr_process) { - dbg_printf("WineDbg starting on pid %04x\n", dbg_curr_pid); + dbg_printf("WineDbg starting on pid %04lx\n", dbg_curr_pid); if (dbg_curr_process->active_debuggee) dbg_active_wait_for_first_exception(); } diff --git a/programs/xcopy/De.rc b/programs/xcopy/De.rc index c13addfdaaa..cd6e1b91384 100644 --- a/programs/xcopy/De.rc +++ b/programs/xcopy/De.rc @@ -75,7 +75,7 @@ Mit:\n\ [/C] Nach Fehlern den Kopiervorgang fortsetzen\n\ [/A] Nur Dateien mit Archivbit kopieren\n\ [/M] Nur Dateien mit Archivbit kopieren, danach Archivbit löschen\n\ -[/D | /D:m-d-y] Kopiere neue Dateien und Dateien, die neuer als das\n\ +[/D | /D:M-T-J] Kopiere neue Dateien und Dateien, die neuer als das\n\ \t\tangegebene Datum sind. Wird kein Datum angegegebn, werden nur\n\ \t\tQuelldateien kopiert, die neuer sind als die Zieldatei\n\n" diff --git a/server/change.c b/server/change.c index d44dd5f4aa6..030a5c7a8c8 100644 --- a/server/change.c +++ b/server/change.c @@ -373,10 +373,10 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd, if (set_info & DACL_SECURITY_INFORMATION) { /* keep the bits that we don't map to access rights in the ACL */ - mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXG); + mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX); mode |= sd_to_mode( sd, owner ); - if (st.st_mode != mode && fchmod( unix_fd, mode ) == -1) + if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1) { file_set_error(); return 0; diff --git a/server/fd.c b/server/fd.c index 7b4a25b0067..e26017d8270 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1732,7 +1732,8 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, int root_fd = -1; int rw_mode; - if ((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE)) + if (((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE)) || + ((options & FILE_DIRECTORY_FILE) && (flags & O_TRUNC))) { set_error( STATUS_INVALID_PARAMETER ); return NULL; @@ -1785,9 +1786,13 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1) { /* if we tried to open a directory for write access, retry read-only */ - if (errno != EISDIR || - !(access & FILE_UNIX_WRITE_ACCESS) || - (fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode )) == -1) + if (errno == EISDIR) + { + if ((access & FILE_UNIX_WRITE_ACCESS) || (flags & O_CREAT)) + fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode ); + } + + if (fd->unix_fd == -1) { file_set_error(); goto error; @@ -1836,7 +1841,16 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, return NULL; } strcpy( closed_fd->unlink, unlink_name ); - if (flags & O_TRUNC) ftruncate( fd->unix_fd, 0 ); + if (flags & O_TRUNC) + { + if (S_ISDIR(st.st_mode)) + { + release_object( fd ); + set_error( STATUS_OBJECT_NAME_COLLISION ); + return NULL; + } + ftruncate( fd->unix_fd, 0 ); + } } else /* special file */ { diff --git a/server/file.c b/server/file.c index f49592462ca..d28e04bbeb4 100644 --- a/server/file.c +++ b/server/file.c @@ -441,12 +441,25 @@ static struct security_descriptor *file_get_sd( struct object *obj ) return sd; } +static mode_t file_access_to_mode( unsigned int access ) +{ + mode_t mode = 0; + + access = generic_file_map_access( access ); + if (access & FILE_READ_DATA) mode |= 4; + if (access & FILE_WRITE_DATA) mode |= 2; + if (access & FILE_EXECUTE) mode |= 1; + return mode; +} + mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) { mode_t new_mode = 0; mode_t denied_mode = 0; + mode_t mode; int present; const ACL *dacl = sd_get_dacl( sd, &present ); + const SID *user = token_get_user( current->process->token ); if (present && dacl) { const ACE_HEADER *ace = (const ACE_HEADER *)(dacl + 1); @@ -464,49 +477,37 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) case ACCESS_DENIED_ACE_TYPE: ad_ace = (const ACCESS_DENIED_ACE *)ace; sid = (const SID *)&ad_ace->SidStart; + mode = file_access_to_mode( ad_ace->Mask ); if (security_equal_sid( sid, security_world_sid )) { - unsigned int access = generic_file_map_access( ad_ace->Mask ); - if (access & FILE_READ_DATA) - denied_mode |= S_IRUSR|S_IRGRP|S_IROTH; - if (access & FILE_WRITE_DATA) - denied_mode |= S_IWUSR|S_IWGRP|S_IWOTH; - if (access & FILE_EXECUTE) - denied_mode |= S_IXUSR|S_IXGRP|S_IXOTH; + denied_mode |= (mode << 6) | (mode << 3) | mode; /* all */ } else if (security_equal_sid( sid, owner )) { - unsigned int access = generic_file_map_access( ad_ace->Mask ); - if (access & FILE_READ_DATA) - denied_mode |= S_IRUSR; - if (access & FILE_WRITE_DATA) - denied_mode |= S_IWUSR; - if (access & FILE_EXECUTE) - denied_mode |= S_IXUSR; + denied_mode |= (mode << 6); /* user only */ + } + else if ((security_equal_sid( user, owner ) && + token_sid_present( current->process->token, sid, TRUE ))) + { + denied_mode |= (mode << 6) | (mode << 3); /* user + group */ } break; case ACCESS_ALLOWED_ACE_TYPE: aa_ace = (const ACCESS_ALLOWED_ACE *)ace; sid = (const SID *)&aa_ace->SidStart; + mode = file_access_to_mode( aa_ace->Mask ); if (security_equal_sid( sid, security_world_sid )) { - unsigned int access = generic_file_map_access( aa_ace->Mask ); - if (access & FILE_READ_DATA) - new_mode |= S_IRUSR|S_IRGRP|S_IROTH; - if (access & FILE_WRITE_DATA) - new_mode |= S_IWUSR|S_IWGRP|S_IWOTH; - if (access & FILE_EXECUTE) - new_mode |= S_IXUSR|S_IXGRP|S_IXOTH; + new_mode |= (mode << 6) | (mode << 3) | mode; /* all */ } else if (security_equal_sid( sid, owner )) { - unsigned int access = generic_file_map_access( aa_ace->Mask ); - if (access & FILE_READ_DATA) - new_mode |= S_IRUSR; - if (access & FILE_WRITE_DATA) - new_mode |= S_IWUSR; - if (access & FILE_EXECUTE) - new_mode |= S_IXUSR; + new_mode |= (mode << 6); /* user only */ + } + else if ((security_equal_sid( user, owner ) && + token_sid_present( current->process->token, sid, FALSE ))) + { + new_mode |= (mode << 6) | (mode << 3); /* user + group */ } break; } @@ -514,7 +515,7 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) } else /* no ACL means full access rights to anyone */ - new_mode = S_IRWXU | S_IRWXO; + new_mode = S_IRWXU | S_IRWXG | S_IRWXO; return new_mode & ~denied_mode; } @@ -557,10 +558,10 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd if (set_info & DACL_SECURITY_INFORMATION) { /* keep the bits that we don't map to access rights in the ACL */ - mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXG); + mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX); mode |= sd_to_mode( sd, owner ); - if (st.st_mode != mode && fchmod( unix_fd, mode ) == -1) + if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1) { file_set_error(); return 0; diff --git a/server/security.h b/server/security.h index 39b1d2f72ff..33cf5da3cf0 100644 --- a/server/security.h +++ b/server/security.h @@ -55,6 +55,7 @@ extern int token_check_privileges( struct token *token, int all_required, extern const ACL *token_get_default_dacl( struct token *token ); extern const SID *token_get_user( struct token *token ); extern const SID *token_get_primary_group( struct token *token ); +extern int token_sid_present( struct token *token, const SID *sid, int deny); static inline const ACE_HEADER *ace_next( const ACE_HEADER *ace ) { diff --git a/server/token.c b/server/token.c index 4c45d50ac77..69ffab79090 100644 --- a/server/token.c +++ b/server/token.c @@ -776,7 +776,7 @@ int token_check_privileges( struct token *token, int all_required, return (enabled_count > 0); } -static int token_sid_present( struct token *token, const SID *sid, int deny ) +int token_sid_present( struct token *token, const SID *sid, int deny ) { struct group *group; diff --git a/tools/wine.inf.in b/tools/wine.inf.in index f676898f3af..623ea0afdb1 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -2385,6 +2385,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,itss.dll,1 11,,jscript.dll,1 11,,mlang.dll,1 +11,,mmdevapi.dll,1 11,,msctf.dll,1 11,,msdaps.dll,1 11,,mshtml.dll,1 diff --git a/tools/winedump/debug.c b/tools/winedump/debug.c index be8150f4936..4f2cedf9988 100644 --- a/tools/winedump/debug.c +++ b/tools/winedump/debug.c @@ -512,70 +512,72 @@ static const char *get_coff_name( const IMAGE_SYMBOL *coff_sym, const char *coff return nampnt; } -void dump_coff(unsigned long coffbase, unsigned long len, const void* pmt) +static const char* storage_class(BYTE sc) +{ + static char tmp[7]; + switch (sc) + { + case IMAGE_SYM_CLASS_STATIC: return "static"; + case IMAGE_SYM_CLASS_EXTERNAL: return "extrnl"; + case IMAGE_SYM_CLASS_LABEL: return "label "; + } + sprintf(tmp, "#%d", sc); + return tmp; +} + +void dump_coff_symbol_table(const IMAGE_SYMBOL *coff_symbols, unsigned num_sym, + const IMAGE_SECTION_HEADER *sectHead) { - const IMAGE_COFF_SYMBOLS_HEADER *coff = PRD(coffbase, len); const IMAGE_SYMBOL *coff_sym; - const IMAGE_SYMBOL *coff_symbols = - (const IMAGE_SYMBOL *) ((const char *)coff + coff->LvaToFirstSymbol); - const char *coff_strtab = (const char *) (coff_symbols + coff->NumberOfSymbols); - const IMAGE_SECTION_HEADER *sectHead = pmt; + const char *coff_strtab = (const char *) (coff_symbols + num_sym); unsigned int i; const char *nampnt; int naux; - printf("\nDebug table: COFF format. modbase %p, coffbase %p\n", PRD(0, 0), coff); - printf(" ID | seg:offs [ abs ] | symbol/function name\n"); - for(i=0; i < coff->NumberOfSymbols; i++ ) + printf("\nDebug table: COFF format.\n"); + printf(" ID | seg:offs [ abs ] | Kind | symbol/function name\n"); + for (i=0; i < num_sym; i++) { - coff_sym = coff_symbols + i; - naux = coff_sym->NumberOfAuxSymbols; - - if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE ) - { - printf("file %s\n", (const char *) (coff_sym + 1)); - i += naux; - continue; - } - - if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC) - && (naux == 0) - && (coff_sym->SectionNumber == 1) ) - { - DWORD base = sectHead[coff_sym->SectionNumber - 1].VirtualAddress; - /* - * This is a normal static function when naux == 0. - * Just register it. The current file is the correct - * one in this instance. - */ - nampnt = get_coff_name( coff_sym, coff_strtab ); - - printf("%05d | %02d:%08x [%08x] | %s\n", i, coff_sym->SectionNumber - 1, coff_sym->Value - base, coff_sym->Value, nampnt); - i += naux; - continue; - } + coff_sym = coff_symbols + i; + naux = coff_sym->NumberOfAuxSymbols; - if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) - && ISFCN(coff_sym->Type) - && (coff_sym->SectionNumber > 0) ) + switch (coff_sym->StorageClass) { - DWORD base = sectHead[coff_sym->SectionNumber - 1].VirtualAddress; - - nampnt = get_coff_name( coff_sym, coff_strtab ); + case IMAGE_SYM_CLASS_FILE: + printf("file %s\n", (const char *) (coff_sym + 1)); + break; + case IMAGE_SYM_CLASS_STATIC: + case IMAGE_SYM_CLASS_EXTERNAL: + case IMAGE_SYM_CLASS_LABEL: + if (coff_sym->SectionNumber > 0) + { + DWORD base = sectHead[coff_sym->SectionNumber - 1].VirtualAddress; + nampnt = get_coff_name( coff_sym, coff_strtab ); - /* FIXME: add code to find out the file this symbol belongs to, - * see winedbg */ - printf("%05d | %02d:%08x [%08x] | %s\n", i, coff_sym->SectionNumber - 1, coff_sym->Value - base, coff_sym->Value, nampnt); - i += naux; - continue; - } + printf("%05d | %02d:%08x [%08x] | %s | %s\n", + i, coff_sym->SectionNumber - 1, coff_sym->Value, + base + coff_sym->Value, + storage_class(coff_sym->StorageClass), nampnt); + } + break; + default: + printf("%05d | %s\n", i, storage_class(coff_sym->StorageClass)); + } + /* + * For now, skip past the aux entries. + */ + i += naux; + } +} - /* - * For now, skip past the aux entries. - */ - i += naux; +void dump_coff(unsigned long coffbase, unsigned long len, const void* pmt) +{ + const IMAGE_COFF_SYMBOLS_HEADER *coff = PRD(coffbase, len); + const IMAGE_SYMBOL *coff_symbols = + (const IMAGE_SYMBOL *) ((const char *)coff + coff->LvaToFirstSymbol); + const IMAGE_SECTION_HEADER *sectHead = pmt; - } + dump_coff_symbol_table(coff_symbols, coff->NumberOfSymbols, sectHead); } void dump_codeview(unsigned long base, unsigned long len) diff --git a/tools/winedump/main.c b/tools/winedump/main.c index 3524a1e3788..d5f39b5164e 100644 --- a/tools/winedump/main.c +++ b/tools/winedump/main.c @@ -187,9 +187,15 @@ static void do_dumpall(const char *arg) { globals.do_dumpheader = 1; globals.do_dump_rawdata = 1; + globals.do_symbol_table = 1; globals.dumpsect = "ALL"; } +static void do_symtable(const char* arg) +{ + globals.do_symbol_table = 1; +} + struct my_option { const char *name; @@ -222,6 +228,7 @@ static const struct my_option option_table[] = { {"-f", DUMP, 0, do_dumphead, "-f Dumps file header information"}, {"-G", DUMP, 0, do_rawdebug, "-G Dumps raw debug information"}, {"-j", DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls, clr)"}, + {"-t", DUMP, 0, do_symtable, "-t Dumps symbol table"}, {"-x", DUMP, 0, do_dumpall, "-x Dumps everything"}, {NULL, NONE, 0, NULL, NULL} }; diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c index 9761215e951..a79593ceace 100644 --- a/tools/winedump/pe.c +++ b/tools/winedump/pe.c @@ -1399,6 +1399,24 @@ static void dump_debug(void) dump_stabs(stabs, szstabs, stabstr, szstr); } +static void dump_symbol_table(void) +{ + const IMAGE_SYMBOL* sym; + int numsym; + const char* strtable; + + numsym = PE_nt_headers->FileHeader.NumberOfSymbols; + if (!PE_nt_headers->FileHeader.PointerToSymbolTable || !numsym) + return; + sym = (const IMAGE_SYMBOL*)PRD(PE_nt_headers->FileHeader.PointerToSymbolTable, + sizeof(*sym) * numsym); + if (!sym) return; + /* FIXME: no way to get strtable size */ + strtable = (const char*)&sym[numsym]; + + dump_coff_symbol_table(sym, numsym, IMAGE_FIRST_SECTION(PE_nt_headers)); +} + enum FileSig get_kind_exec(void) { const WORD* pw; @@ -1468,6 +1486,8 @@ void pe_dump(void) if (all || !strcmp(globals.dumpsect, "except")) dump_dir_exceptions(); } + if (globals.do_symbol_table) + dump_symbol_table(); if (globals.do_debug) dump_debug(); } diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h index 15a8cdbbfd4..9ad20a53ff3 100644 --- a/tools/winedump/winedump.h +++ b/tools/winedump/winedump.h @@ -123,6 +123,7 @@ typedef struct __globals int do_dumpheader; /* -f */ int do_dump_rawdata; /* -x */ int do_debug; /* -G == 1, -g == 2 */ + int do_symbol_table; /* -t */ /* Option arguments: spec mode */ int start_ordinal; /* -s */ @@ -263,6 +264,8 @@ void codeview_dump_linetab2(const char* linetab, DWORD size, const ch void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr); void dump_codeview(unsigned long ptr, unsigned long len); void dump_coff(unsigned long coffbase, unsigned long len, const void* sect_map); +void dump_coff_symbol_table(const IMAGE_SYMBOL *coff_symbols, unsigned num_sym, + const IMAGE_SECTION_HEADER *sectHead); void dump_frame_pointer_omission(unsigned long base, unsigned long len); FILE *open_file (const char *name, const char *ext, const char *mode); -- 2.11.4.GIT