Sync with trunk r63637.
authorDavid Quintana <gigaherz@gmail.com>
Mon, 23 Jun 2014 23:28:38 +0000 (23:28 +0000)
committerDavid Quintana <gigaherz@gmail.com>
Mon, 23 Jun 2014 23:28:38 +0000 (23:28 +0000)
svn path=/branches/shell-experiments/; revision=63640

399 files changed:
1  2 
base/applications/cacls/lang/pl-PL.rc
base/applications/calc/winmain.c
base/applications/cmdutils/reg/CMakeLists.txt
base/applications/cmdutils/reg/reg.c
base/applications/magnify/magnifier.c
base/applications/mplay32/lang/pl-PL.rc
base/applications/mscutils/eventvwr/CMakeLists.txt
base/applications/mscutils/eventvwr/eventvwr.c
base/applications/mscutils/eventvwr/lang/bg-BG.rc
base/applications/mscutils/eventvwr/lang/cs-CZ.rc
base/applications/mscutils/eventvwr/lang/de-DE.rc
base/applications/mscutils/eventvwr/lang/el-GR.rc
base/applications/mscutils/eventvwr/lang/en-US.rc
base/applications/mscutils/eventvwr/lang/es-ES.rc
base/applications/mscutils/eventvwr/lang/fr-FR.rc
base/applications/mscutils/eventvwr/lang/he-IL.rc
base/applications/mscutils/eventvwr/lang/it-IT.rc
base/applications/mscutils/eventvwr/lang/ja-JP.rc
base/applications/mscutils/eventvwr/lang/ko-KR.rc
base/applications/mscutils/eventvwr/lang/no-NO.rc
base/applications/mscutils/eventvwr/lang/pl-PL.rc
base/applications/mscutils/eventvwr/lang/pt-BR.rc
base/applications/mscutils/eventvwr/lang/ro-RO.rc
base/applications/mscutils/eventvwr/lang/ru-RU.rc
base/applications/mscutils/eventvwr/lang/sk-SK.rc
base/applications/mscutils/eventvwr/lang/sq-AL.rc
base/applications/mscutils/eventvwr/lang/sv-SE.rc
base/applications/mscutils/eventvwr/lang/tr-TR.rc
base/applications/mscutils/eventvwr/lang/uk-UA.rc
base/applications/mscutils/eventvwr/lang/zh-CN.rc
base/applications/mscutils/eventvwr/resource.h
base/applications/mspaint/dialogs.c
base/applications/network/net/CMakeLists.txt
base/applications/network/net/cmdAccounts.c
base/applications/network/net/cmdContinue.c
base/applications/network/net/cmdHelpMsg.c
base/applications/network/net/cmdPause.c
base/applications/network/net/cmdStart.c
base/applications/network/net/cmdStop.c
base/applications/network/net/help.c
base/applications/network/net/lang/en-US.rc
base/applications/network/net/main.c
base/applications/network/net/net.h
base/applications/network/net/net.rc
base/applications/network/net/resource.h
base/applications/rapps/lang/en-US.rc
base/applications/rapps/rapps/abyss.txt
base/applications/rapps/rapps/bochs.txt
base/applications/rapps/rapps/boswars.txt
base/applications/rapps/rapps/codeblocks.txt
base/applications/rapps/rapps/codeblocks_gcc.txt
base/applications/rapps/rapps/codeblocks_gcc_2.txt
base/applications/rapps/rapps/devcpp_mingw32.txt
base/applications/rapps/rapps/devcpp_tdm_gcc_x64.txt
base/applications/rapps/rapps/doublecommander.txt
base/applications/rapps/rapps/dplus.txt
base/applications/rapps/rapps/dvdwritenow.txt
base/applications/rapps/rapps/fap.txt
base/applications/rapps/rapps/fira.txt
base/applications/rapps/rapps/firefox.txt
base/applications/rapps/rapps/lazaruside.txt
base/applications/rapps/rapps/libreoffice.txt
base/applications/rapps/rapps/mcwin32.txt
base/applications/rapps/rapps/mirandaim.txt
base/applications/rapps/rapps/mpc.txt
base/applications/rapps/rapps/npp.txt
base/applications/rapps/rapps/openoffice.txt
base/applications/rapps/rapps/opera.txt
base/applications/rapps/rapps/peazip.txt
base/applications/rapps/rapps/putty.txt
base/applications/rapps/rapps/python.txt
base/applications/rapps/rapps/qmmp.txt
base/applications/rapps/rapps/rosbe.txt
base/applications/rapps/rapps/scite.txt
base/applications/rapps/rapps/sdl_runtime.txt
base/applications/rapps/rapps/seamonkey.txt
base/applications/rapps/rapps/sumatrapdf.txt
base/applications/rapps/rapps/thunderbird.txt
base/applications/rapps/rapps/totalcommander.txt
base/applications/rapps/rapps/utorrent.txt
base/applications/rapps/rapps/vb5run.txt
base/applications/rapps/rapps/vb6run.txt
base/applications/rapps/rapps/vc2005sp1run.txt
base/applications/rapps/rapps/vc2008sp1run.txt
base/applications/rapps/rapps/vc2010run.txt
base/applications/rapps/rapps/vc6run.txt
base/applications/rapps/rapps/winboard.txt
base/applications/rapps/rapps/zaz.txt
base/applications/setup16/main.c
base/applications/shutdown/lang/pl-PL.rc
base/applications/sndrec32/lang/pl-PL.rc
base/applications/taskmgr/applpage.c
base/applications/taskmgr/taskmgr.c
base/services/umpnpmgr/CMakeLists.txt
base/services/umpnpmgr/umpnpmgr.c
base/setup/usetup/interface/usetup.c
base/setup/usetup/lang/bg-BG.h
base/setup/usetup/lang/cs-CZ.h
base/setup/usetup/lang/de-DE.h
base/setup/usetup/lang/el-GR.h
base/setup/usetup/lang/en-US.h
base/setup/usetup/lang/es-ES.h
base/setup/usetup/lang/et-EE.h
base/setup/usetup/lang/fr-FR.h
base/setup/usetup/lang/he-IL.h
base/setup/usetup/lang/it-IT.h
base/setup/usetup/lang/ja-JP.h
base/setup/usetup/lang/lt-LT.h
base/setup/usetup/lang/nl-NL.h
base/setup/usetup/lang/pl-PL.h
base/setup/usetup/lang/pt-BR.h
base/setup/usetup/lang/ro-RO.h
base/setup/usetup/lang/ru-RU.h
base/setup/usetup/lang/sk-SK.h
base/setup/usetup/lang/sq-AL.h
base/setup/usetup/lang/sv-SE.h
base/setup/usetup/lang/tr-TR.h
base/setup/usetup/lang/uk-UA.h
base/setup/usetup/mui.h
base/setup/usetup/partlist.c
base/setup/usetup/partlist.h
base/setup/usetup/usetup.h
base/shell/explorer/explorer.cpp
base/shell/explorer/shell/mainframe.cpp
base/shell/explorer/shell/shellfs.cpp
base/shell/explorer/taskbar/quicklaunch.cpp
base/system/services/services.c
boot/bootdata/txtsetup.sif
cmake/CMakeParseArguments.cmake
cmake/gcc.cmake
dll/3rdparty/libtiff/CMakeLists.txt
dll/cpl/appwiz/addons.c
dll/cpl/appwiz/lang/pl-PL.rc
dll/cpl/desk/lang/pl-PL.rc
dll/cpl/desk/screensaver.c
dll/cpl/odbccp32/odbccp32.c
dll/cpl/sysdm/lang/en-US.rc
dll/cpl/wined3dcfg/lang/pl-PL.rc
dll/directx/wine/devenum/CMakeLists.txt
dll/directx/wine/devenum/createdevenum.c
dll/directx/wine/quartz/CMakeLists.txt
dll/directx/wine/quartz/filesource.c
dll/directx/wine/quartz/filtermapper.c
dll/directx/wine/quartz/quartz_private.h
dll/directx/wine/quartz/regsvr.c
dll/keyboard/kbdcz/kbdcz.c
dll/keyboard/kbdcz1/kbdcz1.c
dll/ntdll/include/ntdll.h
dll/ntdll/ldr/ldrapi.c
dll/ntdll/ldr/ldrpe.c
dll/ntdll/ldr/ldrutils.c
dll/ntdll/rtl/libsupp.c
dll/opengl/mesa/drivers/common/driverfuncs.c
dll/opengl/mesa/drivers/common/meta.c
dll/opengl/mesa/drivers/common/meta.h
dll/opengl/mesa/main/CMakeLists.txt
dll/opengl/mesa/main/api_arrayelt.c
dll/opengl/mesa/main/api_exec.c
dll/opengl/mesa/main/api_loopback.c
dll/opengl/mesa/main/api_validate.c
dll/opengl/mesa/main/api_validate.h
dll/opengl/mesa/main/attrib.c
dll/opengl/mesa/main/blend.c
dll/opengl/mesa/main/blend.h
dll/opengl/mesa/main/bufferobj.c
dll/opengl/mesa/main/config.h
dll/opengl/mesa/main/context.c
dll/opengl/mesa/main/dd.h
dll/opengl/mesa/main/dispatch.h
dll/opengl/mesa/main/dlist.c
dll/opengl/mesa/main/enable.c
dll/opengl/mesa/main/extensions.c
dll/opengl/mesa/main/fog.c
dll/opengl/mesa/main/format_pack.c
dll/opengl/mesa/main/format_unpack.c
dll/opengl/mesa/main/formats.c
dll/opengl/mesa/main/formats.h
dll/opengl/mesa/main/get.c
dll/opengl/mesa/main/get.h
dll/opengl/mesa/main/getstring.c
dll/opengl/mesa/main/glheader.h
dll/opengl/mesa/main/image.c
dll/opengl/mesa/main/imports.c
dll/opengl/mesa/main/imports.h
dll/opengl/mesa/main/light.c
dll/opengl/mesa/main/mfeatures.h
dll/opengl/mesa/main/mtypes.h
dll/opengl/mesa/main/pack.c
dll/opengl/mesa/main/precomp.h
dll/opengl/mesa/main/rastpos.c
dll/opengl/mesa/main/shared.c
dll/opengl/mesa/main/state.c
dll/opengl/mesa/main/state.h
dll/opengl/mesa/main/texformat.c
dll/opengl/mesa/main/texgetimage.c
dll/opengl/mesa/main/teximage.c
dll/opengl/mesa/main/teximage.h
dll/opengl/mesa/main/texobj.c
dll/opengl/mesa/main/texparam.c
dll/opengl/mesa/main/texstate.c
dll/opengl/mesa/main/texstorage.c
dll/opengl/mesa/main/texstore.c
dll/opengl/mesa/main/texstore.h
dll/opengl/mesa/main/varray.c
dll/opengl/mesa/main/varray.h
dll/opengl/mesa/main/version.c
dll/opengl/mesa/main/vtxfmt.c
dll/opengl/mesa/swrast/CMakeLists.txt
dll/opengl/mesa/swrast/s_aaline.c
dll/opengl/mesa/swrast/s_aatriangle.c
dll/opengl/mesa/swrast/s_alpha.c
dll/opengl/mesa/swrast/s_blend.c
dll/opengl/mesa/swrast/s_context.c
dll/opengl/mesa/swrast/s_context.h
dll/opengl/mesa/swrast/s_copypix.c
dll/opengl/mesa/swrast/s_drawpix.c
dll/opengl/mesa/swrast/s_feedback.c
dll/opengl/mesa/swrast/s_fog.c
dll/opengl/mesa/swrast/s_lines.c
dll/opengl/mesa/swrast/s_linetemp.h
dll/opengl/mesa/swrast/s_logic.c
dll/opengl/mesa/swrast/s_masking.c
dll/opengl/mesa/swrast/s_points.c
dll/opengl/mesa/swrast/s_span.c
dll/opengl/mesa/swrast/s_texfetch.c
dll/opengl/mesa/swrast/s_texfetch_tmp.h
dll/opengl/mesa/swrast/s_texfilter.c
dll/opengl/mesa/swrast/s_texture.c
dll/opengl/mesa/swrast/s_triangle.c
dll/opengl/mesa/swrast/s_tritemp.h
dll/opengl/mesa/swrast/s_zoom.c
dll/opengl/mesa/swrast/swrast.h
dll/opengl/mesa/swrast_setup/ss_context.c
dll/opengl/mesa/swrast_setup/ss_triangle.c
dll/opengl/mesa/swrast_setup/ss_tritmp.h
dll/opengl/mesa/tnl/t_context.c
dll/opengl/mesa/tnl/t_context.h
dll/opengl/mesa/tnl/t_draw.c
dll/opengl/mesa/tnl/t_rasterpos.c
dll/opengl/mesa/tnl/t_vb_light.c
dll/opengl/mesa/tnl/t_vb_lighttmp.h
dll/opengl/mesa/tnl/t_vertex_generic.c
dll/opengl/mesa/vbo/vbo_attrib.h
dll/opengl/mesa/vbo/vbo_attrib_tmp.h
dll/opengl/mesa/vbo/vbo_exec_api.c
dll/opengl/mesa/vbo/vbo_exec_array.c
dll/opengl/mesa/vbo/vbo_exec_eval.c
dll/opengl/mesa/vbo/vbo_noop.c
dll/opengl/mesa/vbo/vbo_save_api.c
dll/opengl/mesa/vbo/vbo_save_draw.c
dll/opengl/mesa/x86/gen_matypes.c
dll/opengl/mesa/x86/mmx.h
dll/opengl/mesa/x86/mmx_blend.S
dll/opengl/opengl32/swimpl.c
dll/win32/advapi32/advapi32.spec
dll/win32/advapi32/misc/shutdown.c
dll/win32/advapi32/misc/sysfunc.c
dll/win32/atl/CMakeLists.txt
dll/win32/atl/registrar.c
dll/win32/atl100/CMakeLists.txt
dll/win32/atl80/CMakeLists.txt
dll/win32/browseui/CMakeLists.txt
dll/win32/crypt32/CMakeLists.txt
dll/win32/crypt32/regstore.c
dll/win32/kernel32/client/file/copy.c
dll/win32/kernel32/include/kernel32.h
dll/win32/localspl/CMakeLists.txt
dll/win32/localspl/provider.c
dll/win32/mciseq/CMakeLists.txt
dll/win32/mciwave/mciwave.c
dll/win32/msctf/CMakeLists.txt
dll/win32/msctf/categorymgr.c
dll/win32/msctf/inputprocessor.c
dll/win32/msctf/msctf_internal.h
dll/win32/msgina/lang/pl-PL.rc
dll/win32/msi/action.c
dll/win32/msi/classes.c
dll/win32/msi/registry.c
dll/win32/msvcrt/msvcrt.spec
dll/win32/newdev/newdev.c
dll/win32/newdev/newdev.spec
dll/win32/newdev/wizard.c
dll/win32/ntmarta/CMakeLists.txt
dll/win32/ntmarta/ntmarta.c
dll/win32/ole32/ole32.spec
dll/win32/oleaut32/oleaut32.spec
dll/win32/rpcrt4/CMakeLists.txt
dll/win32/rpcrt4/cproxy.c
dll/win32/rpcrt4/cpsf.c
dll/win32/rpcrt4/cstub.c
dll/win32/rpcrt4/ndr_stubless.c
dll/win32/rpcrt4/rpc_transport.c
dll/win32/rpcrt4/rpcrt4.spec
dll/win32/rpcrt4/rpcrt4_ros.diff
dll/win32/samsrv/samrpc.c
dll/win32/setupapi/setupapi.spec
dll/win32/shell32/CMakeLists.txt
dll/win32/shell32/desktop.cpp
dll/win32/shell32/openwithmenu.cpp
dll/win32/shell32/shlexec.cpp
dll/win32/shell32/vista.c
dll/win32/windowscodecs/regsvr.c
dll/win32/winmm/CMakeLists.txt
dll/win32/ws2_32/misc/ns.c
dll/win32/ws2_32/misc/stubs.c
drivers/crypto/ksecdd/CMakeLists.txt
drivers/crypto/ksecdd/stubs.c
drivers/hid/hidparse/hidparse.c
drivers/ksfilter/ks/filterfactory.c
drivers/storage/ide/uniata/id_ata.cpp
include/crt/_mingw.h
include/crt/crtdefs.h
include/crt/excpt.h
include/crt/mingw32/intrin_x86.h
include/crt/stdarg.h
include/crt/vadefs.h
include/psdk/basetyps.h
include/psdk/guiddef.h
include/psdk/ntdef.h
include/psdk/winnls.h
include/psdk/winnt.h
include/reactos/idl/pnp.idl
include/reactos/wine/exception.h
include/reactos/wine/test.h
lib/3rdparty/libmpg123/CMakeLists.txt
lib/cmlib/hivewrt.c
lib/drivers/hidparser/hidparser.h
lib/sdk/crt/except/stack.c
lib/sdk/crt/string/scanf.h
media/doc/README.WINE
media/inf/NET_NIC.inf
media/inf/bth.inf
media/inf/c_image.inf
media/inf/flpydisk.inf
media/inf/keyboard.inf
media/inf/monitor.inf
media/inf/unknown.inf
modules/CMakeLists.txt
ntoskrnl/cache/section/data.c
ntoskrnl/config/cmapi.c
ntoskrnl/config/cmcheck.c
ntoskrnl/config/cminit.c
ntoskrnl/config/cmkcbncb.c
ntoskrnl/config/cmparse.c
ntoskrnl/config/cmsysini.c
ntoskrnl/include/internal/cm.h
ntoskrnl/mm/ARM3/virtual.c
ntoskrnl/mm/marea.c
ntoskrnl/mm/section.c
ntoskrnl/ps/query.c
ntoskrnl/rtl/libsupp.c
subsystems/ntvdm/bios/bios.h
subsystems/ntvdm/bios/vidbios.c
subsystems/ntvdm/dos/dos32krnl/dos.c
subsystems/ntvdm/lang/pl-PL.rc
subsystems/win32/csrsrv/api.h
subsystems/win32/csrsrv/csrsrv.spec
subsystems/win32/csrsrv/procsup.c
win32ss/gdi/eng/floatobj.h
win32ss/gdi/eng/ldevobj.c
win32ss/gdi/ntgdi/freetype.c
win32ss/include/ntuser.h
win32ss/user/ntuser/desktop.c
win32ss/user/ntuser/focus.c
win32ss/user/ntuser/msgqueue.c
win32ss/user/ntuser/painting.c
win32ss/user/ntuser/winsta.c
win32ss/user/ntuser/winsta.h
win32ss/user/user32/controls/appswitch.c
win32ss/user/user32/windows/font.c
win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
win32ss/user/winsrv/consrv/frontends/gui/conwnd.h
win32ss/user/winsrv/consrv/frontends/gui/graphics.c
win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
win32ss/user/winsrv/consrv/frontends/gui/lang/bg-BG.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/cs-CZ.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/de-DE.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/el-GR.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/en-US.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/es-ES.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/fr-FR.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/he-IL.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/id-ID.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/it-IT.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/ja-JP.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/no-NO.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/pl-PL.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/pt-BR.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/ro-RO.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/ru-RU.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/sk-SK.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/sv-SE.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/tr-TR.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/uk-UA.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/zh-CN.rc
win32ss/user/winsrv/consrv/frontends/gui/lang/zh-TW.rc
win32ss/user/winsrv/consrv/frontends/gui/resource.h
win32ss/user/winsrv/consrv/frontends/gui/text.c
win32ss/user/winsrv/init.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc cmake/gcc.cmake
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index dee148b,0000000..808dcfb
mode 100644,000000..100644
--- /dev/null
@@@ -1,73 -1,0 +1,77 @@@
 +PROJECT(SHELL)
 +
 +set_cpp(WITH_RUNTIME)
 +
 +remove_definitions(-D_WIN32_WINNT=0x502)
 +add_definitions(-D_WIN32_WINNT=0x600)
 +
 +include_directories(${REACTOS_SOURCE_DIR}/lib/atl)
 +
 +spec2def(browseui.dll browseui.spec ADD_IMPORTLIB)
 +
 +list(APPEND SOURCE
 +    aclmulti.cpp
 +    addressband.cpp
 +    addresseditbox.cpp
 +    bandproxy.cpp
 +    bandsite.cpp
 +    bandsitemenu.cpp
 +    basebar.cpp
 +    basebarsite.cpp
 +    brandband.cpp
 +    browseui.cpp
 +    browseuiord.cpp
 +    commonbrowser.cpp
 +    globalfoldersettings.cpp
 +    internettoolbar.cpp
 +    regtreeoptions.cpp
 +    shellbrowser.cpp
 +    toolsband.cpp
 +    travellog.cpp
 +    utility.cpp
 +    precomp.h)
 +
 +add_library(browseui SHARED
 +    ${SOURCE}
 +    dllinstall.c
 +    browseui.rc
 +    ${CMAKE_CURRENT_BINARY_DIR}/browseui.def)
 +
 +set_module_type(browseui win32dll UNICODE)
 +
 +target_link_libraries(browseui
 +    atlnew
 +    uuid
 +    wine)
 +
 +add_importlibs(browseui
 +    shlwapi
 +    shell32
 +    comctl32
 +    gdi32
 +    ole32
 +    oleaut32
 +    user32
 +    advapi32
 +    msvcrt
 +    kernel32
 +    ntdll)
 +
 +add_pch(browseui precomp.h SOURCE)
 +add_cd_file(TARGET browseui DESTINATION reactos/system32 FOR all)
 +
++if(NOT MSVC)
++    add_target_compile_flags(browseui "-Wno-unused-but-set-variable")
++endif()
++
 +add_custom_command(TARGET browseui POST_BUILD 
 +  COMMAND "${CMAKE_COMMAND}" -E copy 
 +     "$<TARGET_FILE:browseui>"
 +     "$<TARGET_FILE_DIR:filebrowser>/$<TARGET_FILE_NAME:browseui>" 
 +  COMMENT "Copying to output directory")
 +
 +add_custom_command(TARGET browseui POST_BUILD 
 +  COMMAND "${CMAKE_COMMAND}" -E copy 
 +     "$<TARGET_FILE:browseui>"
 +     "$<TARGET_FILE_DIR:filebrowser>/$<TARGET_FILE_NAME:browseui>" 
 +  COMMENT "Copying to output directory")
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 3dbc5a9,0000000..651600e
mode 100644,000000..100644
--- /dev/null
@@@ -1,113 -1,0 +1,114 @@@
 +PROJECT(SHELL)
 +
 +set_cpp(WITH_RUNTIME)
 +
 +remove_definitions(-D_WIN32_WINNT=0x502)
 +add_definitions(-D_WIN32_WINNT=0x600)
 +
 +add_definitions(
 +    -D_SHELL32_
 +    -D_WINE)
 +
 +include_directories(
 +    ${REACTOS_SOURCE_DIR}/lib/recyclebin
 +    ${REACTOS_SOURCE_DIR}/lib/atl
 +    ${REACTOS_SOURCE_DIR})
 +
 +spec2def(shell32.dll shell32.spec ADD_IMPORTLIB)
 +
 +list(APPEND SOURCE
 +    #authors.cpp
 +    autocomplete.cpp
 +    brsfolder.cpp
 +    changenotify.cpp
 +    classes.cpp
 +    clipboard.cpp
 +    control.cpp
 +    CMenuBand.cpp
 +    CMenuDeskBar.cpp
 +    dataobject.cpp
 +    dde.cpp
 +    debughlp.cpp
 +    desktop.cpp
 +    dialogs.cpp
 +    dragdrophelper.cpp
 +    enumidlist.cpp
 +    extracticon.cpp
 +    folders.cpp
 +    iconcache.cpp
 +    pidl.cpp
 +    shell32_main.cpp
 +    shellitem.cpp
 +    shelllink.cpp
 +    shellole.cpp
 +    shellord.cpp
 +    shellpath.cpp
 +    shellreg.cpp
 +    shellstring.cpp
 +    folders/desktop.cpp
 +    folders/fs.cpp
 +    folders/mycomp.cpp
 +    folders/mydocuments.cpp
 +    folders/printers.cpp
 +    folders/admintools.cpp
 +    folders/netplaces.cpp
 +    folders/fonts.cpp
 +    folders/cpanel.cpp
 +    folders/recyclebin.cpp
 +    droptargets/CexeDropHandler.cpp
 +    shlexec.cpp
 +    shlfileop.cpp
 +    shlfolder.cpp
 +    shlfsbind.cpp
 +    shlmenu.cpp
 +    shlview.cpp
 +    shpolicy.cpp
 +    stubs.cpp
 +    systray.cpp
 +    fprop.cpp
 +    drive.cpp
 +    defcontextmenu.cpp
 +    openwithmenu.cpp
 +    newmenu.cpp
 +    startmenu.cpp
 +    folder_options.cpp
 +    filedefext.cpp
 +    drvdefext.cpp
 +    precomp.h)
 +
 +add_library(shell32 SHARED
 +    ${SOURCE}
++    vista.c
 +    shell32.rc
 +    ${CMAKE_CURRENT_BINARY_DIR}/shell32_stubs.c
 +    ${CMAKE_CURRENT_BINARY_DIR}/shell32.def)
 +
 +set_module_type(shell32 win32dll UNICODE HOTPATCHABLE)
 +
 +target_link_libraries(shell32
 +    atlnew
 +    wine
 +    uuid
 +    recyclebin)
 +
 +add_delay_importlibs(shell32 ole32 version fmifs)
 +
 +add_importlibs(shell32
 +    advapi32
 +    browseui
 +    gdi32
 +    user32
 +    comctl32
 +    comdlg32
 +    shdocvw
 +    shlwapi
 +    devmgr
 +    winspool
 +    winmm
 +    msvcrt
 +    kernel32
 +    ntdll)
 +
 +add_dependencies(shell32 shdocvw_v1)
 +add_pch(shell32 precomp.h SOURCE)
 +add_cd_file(TARGET shell32 DESTINATION reactos/system32 FOR all)
Simple merge
Simple merge
index fe0b7ab,0000000..e1e62cb
mode 100644,000000..100644
--- /dev/null
@@@ -1,2260 -1,0 +1,2262 @@@
-         dwCreationFlags |= CREATE_NEW_CONSOLE;    
 +/*
 + *          Shell Library Functions
 + *
 + * Copyright 1998 Marcus Meissner
 + * Copyright 2002 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 "precomp.h"
 +
 +WINE_DEFAULT_DEBUG_CHANNEL(exec);
 +
 +static const WCHAR wszOpen[] = L"open";
 +static const WCHAR wszExe[] = L".exe";
 +
 +#define SEE_MASK_CLASSALL (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)
 +
 +typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
 +                const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out);
 +
 +static void ParseNoTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
 +{
 +    bool firstCharQuote = false;
 +    bool quotes_opened = false;
 +    bool backslash_encountered = false;
 +
 +    for (int curArg = 0; curArg <= argNum && *args; ++curArg)
 +    {
 +        firstCharQuote = false;
 +        if (*args == '"')
 +        {
 +            quotes_opened = true;
 +            firstCharQuote = true;
 +            args++;
 +        }
 +
 +        while(*args)
 +        {
 +            if (*args == '\\')
 +            {
 +                // if we found a backslash then flip the variable
 +                backslash_encountered = !backslash_encountered;
 +            }
 +            else if (*args == '"')
 +            {
 +                if (quotes_opened)
 +                {
 +                    if (*(args + 1) != '"')
 +                    {
 +                        quotes_opened = false;
 +                        args++;
 +                        break;
 +                    }
 +                    else
 +                    {
 +                        args++;
 +                    }
 +                }
 +                else
 +                {
 +                    quotes_opened = true;
 +                }
 +
 +                backslash_encountered = false;
 +            }
 +            else
 +            {
 +                backslash_encountered = false;
 +                if (*args == ' ' && !firstCharQuote)
 +                    break;
 +            }
 +
 +            if (curArg == argNum)
 +            {
 +                used++;
 +                if (used < len)
 +                    *res++ = *args;
 +            }
 +
 +            args++;
 +        }
 +
 +        while(*args == ' ')
 +            ++args;
 +    }
 +}
 +
 +static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used, int argNum)
 +{
 +    bool quotes_opened = false;
 +    bool backslash_encountered = false;
 +
 +    for (int curArg = 0; curArg <= argNum && *args; ++curArg)
 +    {
 +        while(*args)
 +        {
 +            if (*args == '\\')
 +            {
 +                // if we found a backslash then flip the variable
 +                backslash_encountered = !backslash_encountered;
 +            }
 +            else if (*args == '"')
 +            {
 +                if (quotes_opened)
 +                {
 +                    if (*(args + 1) != '"')
 +                    {
 +                        quotes_opened = false;
 +                    }
 +                    else
 +                    {
 +                        args++;
 +                    }
 +                }
 +                else
 +                {
 +                    quotes_opened = true;
 +                }
 +
 +                backslash_encountered = false;
 +            }
 +            else
 +            {
 +                backslash_encountered = false;
 +                if (*args == ' ' && !quotes_opened && curArg != argNum)
 +                    break;
 +            }
 +
 +            if (curArg == argNum)
 +            {
 +                used++;
 +                if (used < len)
 +                    *res++ = *args;
 +            }
 +
 +            args++;
 +        }
 +    }
 +}
 +
 +/***********************************************************************
 + * SHELL_ArgifyW [Internal]
 + *
 + * this function is supposed to expand the escape sequences found in the registry
 + * some diving reported that the following were used:
 + * + %1, %2...  seem to report to parameter of index N in ShellExecute pmts
 + * %1 file
 + * %2 printer
 + * %3 driver
 + * %4 port
 + * %I address of a global item ID (explorer switch /idlist)
 + * %L seems to be %1 as long filename followed by the 8+3 variation
 + * %S ???
 + * %* all following parameters (see batfile)
 + *
 + * The way we parse the command line arguments was determined through extensive
 + * testing and can be summed up by the following rules"
 + *
 + * - %2
 + *     - if first letter is " break on first non literal " and include any white spaces
 + *     - if first letter is NOT " break on first " or white space
 + *     - if " is opened any pair of consecutive " results in ONE literal "
 + *
 + * - %~2
 + *     - use rules from here http://www.autohotkey.net/~deleyd/parameters/parameters.htm
 + */
 +
 +static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD* out_len)
 +{
 +    WCHAR   xlpFile[1024];
 +    BOOL    done = FALSE;
 +    BOOL    found_p1 = FALSE;
 +    PWSTR   res = out;
 +    PCWSTR  cmd;
 +    DWORD   used = 0;
 +    bool    tildeEffect = false;
 +
 +    TRACE("Before parsing: %p, %d, %s, %s, %p, %p\n", out, len, debugstr_w(fmt),
 +          debugstr_w(lpFile), pidl, args);
 +
 +    while (*fmt)
 +    {
 +        if (*fmt == '%')
 +        {
 +            switch (*++fmt)
 +            {
 +                case '\0':
 +                case '%':
 +                {
 +                    used++;
 +                    if (used < len)
 +                        *res++ = '%';
 +                };
 +                break;
 +
 +                case '*':
 +                {
 +                    if (args)
 +                    {
 +                        if (*fmt == '*')
 +                        {
 +                            used++;
 +                            while(*args)
 +                            {
 +                                used++;
 +                                if (used < len)
 +                                    *res++ = *args++;
 +                                else
 +                                    args++;
 +                            }
 +                            used++;
 +                            break;
 +                        }
 +                    }
 +                };
 +                break;
 +
 +                case '~':
 +
 +                case '2':
 +                case '3':
 +                case '4':
 +                case '5':
 +                case '6':
 +                case '7':
 +                case '8':
 +                case '9':
 +                    //case '0':
 +                {
 +                    if (*fmt == '~')
 +                    {
 +                        fmt++;
 +                        tildeEffect = true;
 +                    }
 +
 +                    if (args)
 +                    {
 +                        if (tildeEffect)
 +                        {
 +                            ParseTildeEffect(res, args, len, used, *fmt - '2');
 +                            tildeEffect = false;
 +                        }
 +                        else
 +                        {
 +                            ParseNoTildeEffect(res, args, len, used, *fmt - '2');
 +                        }
 +                    }
 +                };
 +                break;
 +
 +                case '1':
 +                    if (!done || (*fmt == '1'))
 +                    {
 +                        /*FIXME Is the call to SearchPathW() really needed? We already have separated out the parameter string in args. */
 +                        if (SearchPathW(NULL, lpFile, wszExe, sizeof(xlpFile) / sizeof(WCHAR), xlpFile, NULL))
 +                            cmd = xlpFile;
 +                        else
 +                            cmd = lpFile;
 +
 +                        used += wcslen(cmd);
 +                        if (used < len)
 +                        {
 +                            wcscpy(res, cmd);
 +                            res += wcslen(cmd);
 +                        }
 +                    }
 +                    found_p1 = TRUE;
 +                    break;
 +
 +                    /*
 +                     * IE uses this a lot for activating things such as windows media
 +                     * player. This is not verified to be fully correct but it appears
 +                     * to work just fine.
 +                     */
 +                case 'l':
 +                case 'L':
 +                    if (lpFile)
 +                    {
 +                        used += wcslen(lpFile);
 +                        if (used < len)
 +                        {
 +                            wcscpy(res, lpFile);
 +                            res += wcslen(lpFile);
 +                        }
 +                    }
 +                    found_p1 = TRUE;
 +                    break;
 +
 +                case 'i':
 +                case 'I':
 +                    if (pidl)
 +                    {
 +                        DWORD chars = 0;
 +                        /* %p should not exceed 8, maybe 16 when looking forward to 64bit.
 +                            * allowing a buffer of 100 should more than exceed all needs */
 +                        WCHAR buf[100];
 +                        LPVOID  pv;
 +                        HGLOBAL hmem = SHAllocShared(pidl, ILGetSize(pidl), 0);
 +                        pv = SHLockShared(hmem, 0);
 +                        chars = swprintf(buf, L":%p", pv);
 +
 +                        if (chars >= sizeof(buf) / sizeof(WCHAR))
 +                            ERR("pidl format buffer too small!\n");
 +
 +                        used += chars;
 +
 +                        if (used < len)
 +                        {
 +                            wcscpy(res, buf);
 +                            res += chars;
 +                        }
 +                        SHUnlockShared(pv);
 +                    }
 +                    found_p1 = TRUE;
 +                    break;
 +
 +                default:
 +                    /*
 +                     * Check if this is an env-variable here...
 +                     */
 +
 +                    /* Make sure that we have at least one more %.*/
 +                    if (strchrW(fmt, '%'))
 +                    {
 +                        WCHAR   tmpBuffer[1024];
 +                        PWSTR   tmpB = tmpBuffer;
 +                        WCHAR   tmpEnvBuff[MAX_PATH];
 +                        DWORD   envRet;
 +
 +                        while (*fmt != '%')
 +                            *tmpB++ = *fmt++;
 +                        *tmpB++ = 0;
 +
 +                        TRACE("Checking %s to be an env-var\n", debugstr_w(tmpBuffer));
 +
 +                        envRet = GetEnvironmentVariableW(tmpBuffer, tmpEnvBuff, MAX_PATH);
 +                        if (envRet == 0 || envRet > MAX_PATH)
 +                        {
 +                            used += wcslen(tmpBuffer);
 +                            if (used < len)
 +                            {
 +                                wcscpy( res, tmpBuffer );
 +                                res += wcslen(tmpBuffer);
 +                            }
 +                        }
 +                        else
 +                        {
 +                            used += wcslen(tmpEnvBuff);
 +                            if (used < len)
 +                            {
 +                                wcscpy( res, tmpEnvBuff );
 +                                res += wcslen(tmpEnvBuff);
 +                            }
 +                        }
 +                    }
 +                    done = TRUE;
 +                    break;
 +            }
 +            /* Don't skip past terminator (catch a single '%' at the end) */
 +            if (*fmt != '\0')
 +            {
 +                fmt++;
 +            }
 +        }
 +        else
 +        {
 +            used ++;
 +            if (used < len)
 +                *res++ = *fmt++;
 +            else
 +                fmt++;
 +        }
 +    }
 +
 +    used++;
 +    if (res - out < static_cast<int>(len))
 +        *res = '\0';
 +    else
 +        out[len-1] = '\0';
 +
 +    TRACE("used %i of %i space\n", used, len);
 +    if (out_len)
 +        *out_len = used;
 +
 +    TRACE("After parsing: %p, %d, %s, %s, %p, %p\n", out, len, debugstr_w(fmt),
 +          debugstr_w(lpFile), pidl, args);
 +
 +    return found_p1;
 +}
 +
 +static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
 +{
 +    STRRET strret;
 +    IShellFolder *desktop;
 +
 +    HRESULT hr = SHGetDesktopFolder(&desktop);
 +
 +    if (SUCCEEDED(hr))
 +    {
 +        hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
 +
 +        if (SUCCEEDED(hr))
 +            StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
 +
 +        desktop->Release();
 +    }
 +
 +    return hr;
 +}
 +
 +/*************************************************************************
 + *    SHELL_ExecuteW [Internal]
 + *
 + */
 +static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
 +                               const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
 +{
 +    STARTUPINFOW  startup;
 +    PROCESS_INFORMATION info;
 +    UINT_PTR retval = SE_ERR_NOASSOC;
 +    UINT gcdret = 0;
 +    WCHAR curdir[MAX_PATH];
 +    DWORD dwCreationFlags;
 +    const WCHAR *lpDirectory = NULL;
 +
 +    TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
 +
 +    /* make sure we don't fail the CreateProcess if the calling app passes in
 +     * a bad working directory */
 +    if (psei->lpDirectory && psei->lpDirectory[0])
 +    {
 +        DWORD attr = GetFileAttributesW(psei->lpDirectory);
 +        if (attr != INVALID_FILE_ATTRIBUTES && attr & FILE_ATTRIBUTE_DIRECTORY)
 +            lpDirectory = psei->lpDirectory;
 +    }
 +
 +    /* ShellExecute specifies the command from psei->lpDirectory
 +     * if present. Not from the current dir as CreateProcess does */
 +    if (lpDirectory)
 +        if ((gcdret = GetCurrentDirectoryW( MAX_PATH, curdir)))
 +            if (!SetCurrentDirectoryW( lpDirectory))
 +                ERR("cannot set directory %s\n", debugstr_w(lpDirectory));
 +
 +    ZeroMemory(&startup, sizeof(STARTUPINFOW));
 +    startup.cb = sizeof(STARTUPINFOW);
 +    startup.dwFlags = STARTF_USESHOWWINDOW;
 +    startup.wShowWindow = psei->nShow;
 +    dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
 +    if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
-     
++        dwCreationFlags |= CREATE_NEW_CONSOLE;
 +    startup.lpTitle = (LPWSTR)(psei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE) ? psei->lpClass : NULL);
 +
 +    if (psei->fMask & SEE_MASK_HASLINKNAME)
 +        startup.dwFlags |= STARTF_TITLEISLINKNAME;
 +
 +    if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
 +                       lpDirectory, &startup, &info))
 +    {
 +        /* Give 30 seconds to the app to come up, if desired. Probably only needed
 +           when starting app immediately before making a DDE connection. */
 +        if (shWait)
 +            if (WaitForInputIdle(info.hProcess, 30000) == WAIT_FAILED)
 +                WARN("WaitForInputIdle failed: Error %d\n", GetLastError() );
 +        retval = 33;
 +
 +        if (psei->fMask & SEE_MASK_NOCLOSEPROCESS)
 +            psei_out->hProcess = info.hProcess;
 +        else
 +            CloseHandle( info.hProcess );
 +        CloseHandle( info.hThread );
 +    }
 +    else if ((retval = GetLastError()) >= 32)
 +    {
 +        WARN("CreateProcess returned error %ld\n", retval);
 +        retval = ERROR_BAD_FORMAT;
 +    }
 +
 +    TRACE("returning %lu\n", retval);
 +
 +    psei_out->hInstApp = (HINSTANCE)retval;
 +
 +    if (gcdret)
 +        if (!SetCurrentDirectoryW(curdir))
 +            ERR("cannot return to directory %s\n", debugstr_w(curdir));
 +
 +    return retval;
 +}
 +
 +
 +/***********************************************************************
 + *           SHELL_BuildEnvW    [Internal]
 + *
 + * Build the environment for the new process, adding the specified
 + * path to the PATH variable. Returned pointer must be freed by caller.
 + */
 +static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
 +{
 +    static const WCHAR wPath[] = L"PATH=";
 +    WCHAR *strings, *new_env;
 +    WCHAR *p, *p2;
 +    int total = wcslen(path) + 1;
 +    BOOL got_path = FALSE;
 +
 +    if (!(strings = GetEnvironmentStringsW())) return NULL;
 +    p = strings;
 +    while (*p)
 +    {
 +        int len = wcslen(p) + 1;
 +        if (!_wcsnicmp( p, wPath, 5 )) got_path = TRUE;
 +        total += len;
 +        p += len;
 +    }
 +    if (!got_path) total += 5;  /* we need to create PATH */
 +    total++;  /* terminating null */
 +
 +    if (!(new_env = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, total * sizeof(WCHAR))))
 +    {
 +        FreeEnvironmentStringsW(strings);
 +        return NULL;
 +    }
 +    p = strings;
 +    p2 = new_env;
 +    while (*p)
 +    {
 +        int len = wcslen(p) + 1;
 +        memcpy(p2, p, len * sizeof(WCHAR));
 +        if (!_wcsnicmp( p, wPath, 5 ))
 +        {
 +            p2[len - 1] = ';';
 +            wcscpy( p2 + len, path );
 +            p2 += wcslen(path) + 1;
 +        }
 +        p += len;
 +        p2 += len;
 +    }
 +    if (!got_path)
 +    {
 +        wcscpy(p2, wPath);
 +        wcscat(p2, path);
 +        p2 += wcslen(p2) + 1;
 +    }
 +    *p2 = 0;
 +    FreeEnvironmentStringsW(strings);
 +    return new_env;
 +}
 +
 +
 +/***********************************************************************
 + *           SHELL_TryAppPathW    [Internal]
 + *
 + * Helper function for SHELL_FindExecutable
 + * @param lpResult - pointer to a buffer of size MAX_PATH
 + * On entry: szName is a filename (probably without path separators).
 + * On exit: if szName found in "App Path", place full path in lpResult, and return true
 + */
 +static BOOL SHELL_TryAppPathW( LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
 +{
 +    HKEY hkApp = 0;
 +    WCHAR buffer[1024];
 +    LONG len;
 +    LONG res;
 +    BOOL found = FALSE;
 +
 +    if (env) *env = NULL;
 +    wcscpy(buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
 +    wcscat(buffer, szName);
 +    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, buffer, 0, KEY_READ, &hkApp);
 +    if (res) goto end;
 +
 +    len = MAX_PATH * sizeof(WCHAR);
 +    res = RegQueryValueW(hkApp, NULL, lpResult, &len);
 +    if (res) goto end;
 +    found = TRUE;
 +
 +    if (env)
 +    {
 +        DWORD count = sizeof(buffer);
 +        if (!RegQueryValueExW(hkApp, L"Path", NULL, NULL, (LPBYTE)buffer, &count) && buffer[0])
 +            *env = SHELL_BuildEnvW(buffer);
 +    }
 +
 +end:
 +    if (hkApp) RegCloseKey(hkApp);
 +    return found;
 +}
 +
 +/*************************************************************************
 + *     SHELL_FindExecutableByVerb [Internal]
 + *
 + * called from SHELL_FindExecutable or SHELL_execute_class
 + * in/out:
 + *      classname a buffer, big enough, to get the key name to do actually the
 + *              command   "WordPad.Document.1\\shell\\open\\command"
 + *              passed as "WordPad.Document.1"
 + * in:
 + *      lpVerb the operation on it (open)
 + *      commandlen the size of command buffer (in bytes)
 + * out:
 + *      command a buffer, to store the command to do the
 + *              operation on the file
 + *      key a buffer, big enough, to get the key name to do actually the
 + *              command "WordPad.Document.1\\shell\\open\\command"
 + *              Can be NULL
 + */
 +static UINT SHELL_FindExecutableByVerb(LPCWSTR lpVerb, LPWSTR key, LPWSTR classname, LPWSTR command, LONG commandlen)
 +{
 +    static const WCHAR wCommand[] = L"\\command";
 +    HKEY hkeyClass;
 +    WCHAR verb[MAX_PATH];
 +
 +    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, classname, 0, 0x02000000, &hkeyClass))
 +        return SE_ERR_NOASSOC;
 +    if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, sizeof(verb) / sizeof(verb[0])))
 +        return SE_ERR_NOASSOC;
 +    RegCloseKey(hkeyClass);
 +
 +    /* Looking for ...buffer\shell\<verb>\command */
 +    wcscat(classname, L"\\shell\\");
 +    wcscat(classname, verb);
 +    wcscat(classname, wCommand);
 +
 +    if (RegQueryValueW(HKEY_CLASSES_ROOT, classname, command,
 +                       &commandlen) == ERROR_SUCCESS)
 +    {
 +        commandlen /= sizeof(WCHAR);
 +        if (key) wcscpy(key, classname);
 +#if 0
 +        LPWSTR tmp;
 +        WCHAR param[256];
 +        LONG paramlen = sizeof(param);
 +        static const WCHAR wSpace[] = {' ', 0};
 +
 +        /* FIXME: it seems all Windows version don't behave the same here.
 +         * the doc states that this ddeexec information can be found after
 +         * the exec names.
 +         * on Win98, it doesn't appear, but I think it does on Win2k
 +         */
 +        /* Get the parameters needed by the application
 +           from the associated ddeexec key */
 +        tmp = strstrW(classname, wCommand);
 +        tmp[0] = '\0';
 +        wcscat(classname, wDdeexec);
 +        if (RegQueryValueW(HKEY_CLASSES_ROOT, classname, param,
 +                           &paramlen) == ERROR_SUCCESS)
 +        {
 +            paramlen /= sizeof(WCHAR);
 +            wcscat(command, wSpace);
 +            wcscat(command, param);
 +            commandlen += paramlen;
 +        }
 +#endif
 +
 +        command[commandlen] = '\0';
 +
 +        return 33; /* FIXME see SHELL_FindExecutable() */
 +    }
 +
 +    return SE_ERR_NOASSOC;
 +}
 +
 +/*************************************************************************
 + *    SHELL_FindExecutable [Internal]
 + *
 + * Utility for code sharing between FindExecutable and ShellExecute
 + * in:
 + *      lpFile the name of a file
 + *      lpVerb the operation on it (open)
 + * out:
 + *      lpResult a buffer, big enough :-(, to store the command to do the
 + *              operation on the file
 + *      key a buffer, big enough, to get the key name to do actually the
 + *              command (it'll be used afterwards for more information
 + *              on the operation)
 + */
 +static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
 +                                 LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args)
 +{
 +    WCHAR *extension = NULL; /* pointer to file extension */
 +    WCHAR classname[256];     /* registry name for this file type */
 +    LONG  classnamelen = sizeof(classname); /* length of above */
 +    WCHAR command[1024];     /* command from registry */
 +    WCHAR wBuffer[256];      /* Used to GetProfileString */
 +    UINT  retval = SE_ERR_NOASSOC;
 +    WCHAR *tok;              /* token pointer */
 +    WCHAR xlpFile[256];      /* result of SearchPath */
 +    DWORD attribs;           /* file attributes */
 +
 +    TRACE("%s\n", debugstr_w(lpFile));
 +
 +    if (!lpResult)
 +        return ERROR_INVALID_PARAMETER;
 +
 +    xlpFile[0] = '\0';
 +    lpResult[0] = '\0'; /* Start off with an empty return string */
 +    if (key) *key = '\0';
 +
 +    /* trap NULL parameters on entry */
 +    if (!lpFile)
 +    {
 +        WARN("(lpFile=%s,lpResult=%s): NULL parameter\n",
 +             debugstr_w(lpFile), debugstr_w(lpResult));
 +        return ERROR_FILE_NOT_FOUND; /* File not found. Close enough, I guess. */
 +    }
 +
 +    if (SHELL_TryAppPathW( lpFile, lpResult, env ))
 +    {
 +        TRACE("found %s via App Paths\n", debugstr_w(lpResult));
 +        return 33;
 +    }
 +
 +    if (SearchPathW(lpPath, lpFile, wszExe, sizeof(xlpFile) / sizeof(WCHAR), xlpFile, NULL))
 +    {
 +        TRACE("SearchPathW returned non-zero\n");
 +        lpFile = xlpFile;
 +        /* The file was found in the application-supplied default directory (or the system search path) */
 +    }
 +    else if (lpPath && SearchPathW(NULL, lpFile, wszExe, sizeof(xlpFile)/sizeof(WCHAR), xlpFile, NULL))
 +    {
 +        TRACE("SearchPathW returned non-zero\n");
 +        lpFile = xlpFile;
 +        /* The file was found in one of the directories in the system-wide search path */
 +    }
-     
++
 +    attribs = GetFileAttributesW(lpFile);
 +    if (attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY))
 +    {
 +        wcscpy(classname, L"Folder");
 +    }
 +    else
 +    {
 +        /* Did we get something? Anything? */
 +        if (xlpFile[0] == 0)
 +        {
 +            TRACE("Returning SE_ERR_FNF\n");
 +            return SE_ERR_FNF;
 +        }
 +        /* First thing we need is the file's extension */
 +        extension = wcsrchr(xlpFile, '.'); /* Assume last "." is the one; */
 +        /* File->Run in progman uses */
 +        /* .\FILE.EXE :( */
 +        TRACE("xlpFile=%s,extension=%s\n", debugstr_w(xlpFile), debugstr_w(extension));
 +
 +        if (extension == NULL || extension[1] == 0)
 +        {
 +            WARN("Returning SE_ERR_NOASSOC\n");
 +            return SE_ERR_NOASSOC;
 +        }
 +
 +        /* Three places to check: */
 +        /* 1. win.ini, [windows], programs (NB no leading '.') */
 +        /* 2. Registry, HKEY_CLASS_ROOT\<classname>\shell\open\command */
 +        /* 3. win.ini, [extensions], extension (NB no leading '.' */
 +        /* All I know of the order is that registry is checked before */
 +        /* extensions; however, it'd make sense to check the programs */
 +        /* section first, so that's what happens here. */
 +
 +        /* See if it's a program - if GetProfileString fails, we skip this
 +         * section. Actually, if GetProfileString fails, we've probably
 +         * got a lot more to worry about than running a program... */
 +        if (GetProfileStringW(L"windows", L"programs", L"exe pif bat cmd com", wBuffer, sizeof(wBuffer) / sizeof(WCHAR)) > 0)
 +        {
 +            CharLowerW(wBuffer);
 +            tok = wBuffer;
 +            while (*tok)
 +            {
 +                WCHAR *p = tok;
 +                while (*p && *p != ' ' && *p != '\t') p++;
 +                if (*p)
 +                {
 +                    *p++ = 0;
 +                    while (*p == ' ' || *p == '\t') p++;
 +                }
 +
 +                if (wcsicmp(tok, &extension[1]) == 0) /* have to skip the leading "." */
 +                {
 +                    wcscpy(lpResult, xlpFile);
 +                    /* Need to perhaps check that the file has a path
 +                     * attached */
 +                    TRACE("found %s\n", debugstr_w(lpResult));
 +                    return 33;
 +                    /* Greater than 32 to indicate success */
 +                }
 +                tok = p;
 +            }
 +        }
 +
 +        /* Check registry */
 +        if (RegQueryValueW(HKEY_CLASSES_ROOT, extension, classname,
 +                           &classnamelen) == ERROR_SUCCESS)
 +        {
 +            classnamelen /= sizeof(WCHAR);
 +            if (classnamelen == sizeof(classname) / sizeof(WCHAR))
 +                classnamelen--;
 +
 +            classname[classnamelen] = '\0';
 +            TRACE("File type: %s\n", debugstr_w(classname));
 +        }
 +        else
 +        {
 +            *classname = '\0';
 +        }
 +    }
 +
 +    if (*classname)
 +    {
 +        /* pass the verb string to SHELL_FindExecutableByVerb() */
 +        retval = SHELL_FindExecutableByVerb(lpVerb, key, classname, command, sizeof(command));
 +
 +        if (retval > 32)
 +        {
 +            DWORD finishedLen;
 +            SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen);
 +            if (finishedLen > resultLen)
 +                ERR("Argify buffer not large enough.. truncated\n");
 +            /* Remove double quotation marks and command line arguments */
 +            if (*lpResult == '"')
 +            {
 +                WCHAR *p = lpResult;
 +                while (*(p + 1) != '"')
 +                {
 +                    *p = *(p + 1);
 +                    p++;
 +                }
 +                *p = '\0';
 +            }
 +            else
 +            {
 +                /* Truncate on first space */
 +                WCHAR *p = lpResult;
 +                while (*p != ' ' && *p != '\0')
 +                    p++;
 +                *p = '\0';
 +            }
 +        }
 +    }
 +    else /* Check win.ini */
 +    {
 +        /* Toss the leading dot */
 +        extension++;
 +        if (GetProfileStringW(L"extensions", extension, L"", command, sizeof(command) / sizeof(WCHAR)) > 0)
 +        {
 +            if (wcslen(command) != 0)
 +            {
 +                wcscpy(lpResult, command);
 +                tok = wcschr(lpResult, '^'); /* should be ^.extension? */
 +                if (tok != NULL)
 +                {
 +                    tok[0] = '\0';
 +                    wcscat(lpResult, xlpFile); /* what if no dir in xlpFile? */
 +                    tok = wcschr(command, '^'); /* see above */
 +                    if ((tok != NULL) && (wcslen(tok) > 5))
 +                    {
 +                        wcscat(lpResult, &tok[5]);
 +                    }
 +                }
 +                retval = 33; /* FIXME - see above */
 +            }
 +        }
 +    }
 +
 +    TRACE("returning %s\n", debugstr_w(lpResult));
 +    return retval;
 +}
 +
 +/******************************************************************
 + *        dde_cb
 + *
 + * callback for the DDE connection. not really useful
 + */
 +static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv,
 +                                HSZ hsz1, HSZ hsz2, HDDEDATA hData,
 +                                ULONG_PTR dwData1, ULONG_PTR dwData2)
 +{
 +    TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
 +          uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);
 +    return NULL;
 +}
 +
 +/******************************************************************
 + *        dde_connect
 + *
 + * ShellExecute helper. Used to do an operation with a DDE connection
 + *
 + * Handles both the direct connection (try #1), and if it fails,
 + * launching an application and trying (#2) to connect to it
 + *
 + */
 +static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec,
 +                            const WCHAR* lpFile, WCHAR *env,
 +                            LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc,
 +                            const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
 +{
 +    WCHAR       regkey[256];
 +    WCHAR *     endkey = regkey + wcslen(key);
 +    WCHAR       app[256], topic[256], ifexec[256], static_res[256];
 +    WCHAR *     dynamic_res=NULL;
 +    WCHAR *     res;
 +    LONG        applen, topiclen, ifexeclen;
 +    WCHAR *     exec;
 +    DWORD       ddeInst = 0;
 +    DWORD       tid;
 +    DWORD       resultLen, endkeyLen;
 +    HSZ         hszApp, hszTopic;
 +    HCONV       hConv;
 +    HDDEDATA    hDdeData;
 +    unsigned    ret = SE_ERR_NOASSOC;
 +    BOOL unicode = !(GetVersion() & 0x80000000);
 +
 +    if (strlenW(key) + 1 > sizeof(regkey) / sizeof(regkey[0]))
 +    {
 +        FIXME("input parameter %s larger than buffer\n", debugstr_w(key));
 +        return 2;
 +    }
 +    wcscpy(regkey, key);
 +    static const WCHAR wApplication[] = L"\\application";
 +    endkeyLen = sizeof(regkey) / sizeof(regkey[0]) - (endkey - regkey);
 +    if (strlenW(wApplication) + 1 > endkeyLen)
 +    {
 +        FIXME("endkey %s overruns buffer\n", debugstr_w(wApplication));
 +        return 2;
 +    }
 +    wcscpy(endkey, wApplication);
 +    applen = sizeof(app);
 +    if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, app, &applen) != ERROR_SUCCESS)
 +    {
 +        WCHAR command[1024], fullpath[MAX_PATH];
 +        static const WCHAR wSo[] = L".so";
 +        DWORD sizeSo = sizeof(wSo) / sizeof(WCHAR);
 +        LPWSTR ptr = NULL;
 +        DWORD ret = 0;
 +
 +        /* Get application command from start string and find filename of application */
 +        if (*start == '"')
 +        {
 +            if (strlenW(start + 1) + 1 > sizeof(command) / sizeof(command[0]))
 +            {
 +                FIXME("size of input parameter %s larger than buffer\n",
 +                      debugstr_w(start + 1));
 +                return 2;
 +            }
 +            wcscpy(command, start + 1);
 +            if ((ptr = wcschr(command, '"')))
 +                * ptr = 0;
 +            ret = SearchPathW(NULL, command, wszExe, sizeof(fullpath) / sizeof(WCHAR), fullpath, &ptr);
 +        }
 +        else
 +        {
 +            LPCWSTR p;
 +            LPWSTR space;
 +            for (p = start; (space = const_cast<LPWSTR>(strchrW(p, ' '))); p = space + 1)
 +            {
 +                int idx = space - start;
 +                memcpy(command, start, idx * sizeof(WCHAR));
 +                command[idx] = '\0';
 +                if ((ret = SearchPathW(NULL, command, wszExe, sizeof(fullpath) / sizeof(WCHAR), fullpath, &ptr)))
 +                    break;
 +            }
 +            if (!ret)
 +                ret = SearchPathW(NULL, start, wszExe, sizeof(fullpath) / sizeof(WCHAR), fullpath, &ptr);
 +        }
 +
 +        if (!ret)
 +        {
 +            ERR("Unable to find application path for command %s\n", debugstr_w(start));
 +            return ERROR_ACCESS_DENIED;
 +        }
 +        if (strlenW(ptr) + 1 > sizeof(app) / sizeof(app[0]))
 +        {
 +            FIXME("size of found path %s larger than buffer\n", debugstr_w(ptr));
 +            return 2;
 +        }
 +        wcscpy(app, ptr);
 +
 +        /* Remove extensions (including .so) */
 +        ptr = app + wcslen(app) - (sizeSo - 1);
 +        if (wcslen(app) >= sizeSo &&
 +                !wcscmp(ptr, wSo))
 +            *ptr = 0;
 +
 +        ptr = const_cast<LPWSTR>(strrchrW(app, '.'));
 +        assert(ptr);
 +        *ptr = 0;
 +    }
-     
++
 +    static const WCHAR wTopic[] = L"\\topic";
 +    if (strlenW(wTopic) + 1 > endkeyLen)
 +    {
 +        FIXME("endkey %s overruns buffer\n", debugstr_w(wTopic));
 +        return 2;
 +    }
 +    wcscpy(endkey, wTopic);
 +    topiclen = sizeof(topic);
 +    if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, topic, &topiclen) != ERROR_SUCCESS)
 +    {
 +        wcscpy(topic, L"System");
 +    }
 +
 +    if (unicode)
 +    {
 +        if (DdeInitializeW(&ddeInst, dde_cb, APPCMD_CLIENTONLY, 0L) != DMLERR_NO_ERROR)
 +            return 2;
 +    }
 +    else
 +    {
 +        if (DdeInitializeA(&ddeInst, dde_cb, APPCMD_CLIENTONLY, 0L) != DMLERR_NO_ERROR)
 +            return 2;
 +    }
 +
 +    hszApp = DdeCreateStringHandleW(ddeInst, app, CP_WINUNICODE);
 +    hszTopic = DdeCreateStringHandleW(ddeInst, topic, CP_WINUNICODE);
 +
 +    hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
 +    exec = ddeexec;
 +    if (!hConv)
 +    {
 +        TRACE("Launching %s\n", debugstr_w(start));
 +        ret = execfunc(start, env, TRUE, psei, psei_out);
 +        if (ret <= 32)
 +        {
 +            TRACE("Couldn't launch\n");
 +            goto error;
 +        }
 +        hConv = DdeConnect(ddeInst, hszApp, hszTopic, NULL);
 +        if (!hConv)
 +        {
 +            TRACE("Couldn't connect. ret=%d\n", ret);
 +            DdeUninitialize(ddeInst);
 +            SetLastError(ERROR_DDE_FAIL);
 +            return 30; /* whatever */
 +        }
 +        static const WCHAR wIfexec[] = L"\\ifexec";
 +        if (strlenW(wIfexec) + 1 > endkeyLen)
 +        {
 +            FIXME("endkey %s overruns buffer\n", debugstr_w(wIfexec));
 +            return 2;
 +        }
 +        strcpyW(endkey, wIfexec);
 +        ifexeclen = sizeof(ifexec);
 +        if (RegQueryValueW(HKEY_CLASSES_ROOT, regkey, ifexec, &ifexeclen) == ERROR_SUCCESS)
 +        {
 +            exec = ifexec;
 +        }
 +    }
 +
 +    SHELL_ArgifyW(static_res, sizeof(static_res)/sizeof(WCHAR), exec, lpFile, pidl, szCommandline, &resultLen);
 +    if (resultLen > sizeof(static_res)/sizeof(WCHAR))
 +    {
 +        res = dynamic_res = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, resultLen * sizeof(WCHAR)));
 +        SHELL_ArgifyW(dynamic_res, resultLen, exec, lpFile, pidl, szCommandline, NULL);
 +    }
 +    else
 +        res = static_res;
 +    TRACE("%s %s => %s\n", debugstr_w(exec), debugstr_w(lpFile), debugstr_w(res));
 +
 +    /* It's documented in the KB 330337 that IE has a bug and returns
 +     * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
 +     */
 +    if (unicode)
 +        hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
 +    else
 +    {
 +        DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
 +        char *resA = (LPSTR)HeapAlloc(GetProcessHeap(), 0, lenA);
 +        WideCharToMultiByte(CP_ACP, 0, res, -1, resA, lenA, NULL, NULL);
 +        hDdeData = DdeClientTransaction( (LPBYTE)resA, lenA, hConv, 0L, 0,
 +                                         XTYP_EXECUTE, 10000, &tid );
 +        HeapFree(GetProcessHeap(), 0, resA);
 +    }
 +    if (hDdeData)
 +        DdeFreeDataHandle(hDdeData);
 +    else
 +        WARN("DdeClientTransaction failed with error %04x\n", DdeGetLastError(ddeInst));
 +    ret = 33;
 +
 +    HeapFree(GetProcessHeap(), 0, dynamic_res);
 +
 +    DdeDisconnect(hConv);
 +
 +error:
 +    DdeUninitialize(ddeInst);
 +
 +    return ret;
 +}
 +
 +/*************************************************************************
 + *    execute_from_key [Internal]
 + */
 +static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env,
 +                                 LPCWSTR szCommandline, LPCWSTR executable_name,
 +                                 SHELL_ExecuteW32 execfunc,
 +                                 LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
 +{
 +    WCHAR cmd[256], param[1024], ddeexec[256];
 +    DWORD cmdlen = sizeof(cmd), ddeexeclen = sizeof(ddeexec);
 +    UINT_PTR retval = SE_ERR_NOASSOC;
 +    DWORD resultLen;
 +    LPWSTR tmp;
 +
 +    TRACE("%s %s %s %s %s\n", debugstr_w(key), debugstr_w(lpFile), debugstr_w(env),
 +          debugstr_w(szCommandline), debugstr_w(executable_name));
 +
 +    cmd[0] = '\0';
 +    param[0] = '\0';
 +
 +    /* Get the application from the registry */
 +    if (RegQueryValueW(HKEY_CLASSES_ROOT, key, cmd, (LONG *)&cmdlen) == ERROR_SUCCESS)
 +    {
 +        TRACE("got cmd: %s\n", debugstr_w(cmd));
 +
 +        /* Is there a replace() function anywhere? */
 +        cmdlen /= sizeof(WCHAR);
 +        if (cmdlen >= sizeof(cmd) / sizeof(WCHAR))
 +            cmdlen = sizeof(cmd) / sizeof(WCHAR) - 1;
 +        cmd[cmdlen] = '\0';
 +        SHELL_ArgifyW(param, sizeof(param) / sizeof(WCHAR), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen);
 +        if (resultLen > sizeof(param) / sizeof(WCHAR))
 +            ERR("Argify buffer not large enough, truncating\n");
 +    }
 +
 +    /* Get the parameters needed by the application
 +       from the associated ddeexec key */
 +    tmp = const_cast<LPWSTR>(strstrW(key, L"command"));
 +    assert(tmp);
 +    wcscpy(tmp, L"ddeexec");
 +
 +    if (RegQueryValueW(HKEY_CLASSES_ROOT, key, ddeexec, (LONG *)&ddeexeclen) == ERROR_SUCCESS)
 +    {
 +        TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(ddeexec));
 +        if (!param[0]) strcpyW(param, executable_name);
 +        retval = dde_connect(key, param, ddeexec, lpFile, env, szCommandline, (LPITEMIDLIST)psei->lpIDList, execfunc, psei, psei_out);
 +    }
 +    else if (param[0])
 +    {
 +        TRACE("executing: %s\n", debugstr_w(param));
 +        retval = execfunc(param, env, FALSE, psei, psei_out);
 +    }
 +    else
 +        WARN("Nothing appropriate found for %s\n", debugstr_w(key));
 +
 +    return retval;
 +}
 +
 +/*************************************************************************
 + * FindExecutableA            [SHELL32.@]
 + */
 +HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
 +{
 +    HINSTANCE retval;
 +    WCHAR *wFile = NULL, *wDirectory = NULL;
 +    WCHAR wResult[MAX_PATH];
 +
 +    if (lpFile) __SHCloneStrAtoW(&wFile, lpFile);
 +    if (lpDirectory) __SHCloneStrAtoW(&wDirectory, lpDirectory);
 +
 +    retval = FindExecutableW(wFile, wDirectory, wResult);
 +    WideCharToMultiByte(CP_ACP, 0, wResult, -1, lpResult, MAX_PATH, NULL, NULL);
 +    SHFree(wFile);
 +    SHFree(wDirectory);
 +
 +    TRACE("returning %s\n", lpResult);
 +    return retval;
 +}
 +
 +/*************************************************************************
 + * FindExecutableW            [SHELL32.@]
 + *
 + * This function returns the executable associated with the specified file
 + * for the default verb.
 + *
 + * PARAMS
 + *  lpFile   [I] The file to find the association for. This must refer to
 + *               an existing file otherwise FindExecutable fails and returns
 + *               SE_ERR_FNF.
 + *  lpResult [O] Points to a buffer into which the executable path is
 + *               copied. This parameter must not be NULL otherwise
 + *               FindExecutable() segfaults. The buffer must be of size at
 + *               least MAX_PATH characters.
 + *
 + * RETURNS
 + *  A value greater than 32 on success, less than or equal to 32 otherwise.
 + *  See the SE_ERR_* constants.
 + *
 + * NOTES
 + *  On Windows XP and 2003, FindExecutable() seems to first convert the
 + *  filename into 8.3 format, thus taking into account only the first three
 + *  characters of the extension, and expects to find an association for those.
 + *  However other Windows versions behave sanely.
 + */
 +HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult)
 +{
 +    UINT_PTR retval = SE_ERR_NOASSOC;
 +    WCHAR old_dir[1024];
 +
 +    TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory));
 +
 +    lpResult[0] = '\0'; /* Start off with an empty return string */
 +    if (lpFile == NULL)
 +        return (HINSTANCE)SE_ERR_FNF;
 +
 +    if (lpDirectory)
 +    {
 +        GetCurrentDirectoryW(sizeof(old_dir) / sizeof(WCHAR), old_dir);
 +        SetCurrentDirectoryW(lpDirectory);
 +    }
 +
 +    retval = SHELL_FindExecutable(lpDirectory, lpFile, wszOpen, lpResult, MAX_PATH, NULL, NULL, NULL, NULL);
 +
 +    TRACE("returning %s\n", debugstr_w(lpResult));
 +    if (lpDirectory)
 +        SetCurrentDirectoryW(old_dir);
 +    return (HINSTANCE)retval;
 +}
 +
 +/* FIXME: is this already implemented somewhere else? */
 +static HKEY ShellExecute_GetClassKey(const SHELLEXECUTEINFOW *sei)
 +{
 +    LPCWSTR ext = NULL, lpClass = NULL;
 +    LPWSTR cls = NULL;
 +    DWORD type = 0, sz = 0;
 +    HKEY hkey = 0;
 +    LONG r;
 +
 +    if (sei->fMask & SEE_MASK_CLASSALL)
 +        return sei->hkeyClass;
 +
 +    if (sei->fMask & SEE_MASK_CLASSNAME)
 +        lpClass = sei->lpClass;
 +    else
 +    {
 +        ext = PathFindExtensionW(sei->lpFile);
 +        TRACE("ext = %s\n", debugstr_w(ext));
 +        if (!ext)
 +            return hkey;
 +
 +        r = RegOpenKeyW(HKEY_CLASSES_ROOT, ext, &hkey);
 +        if (r != ERROR_SUCCESS)
 +            return hkey;
 +
 +        r = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &sz);
 +        if (r == ERROR_SUCCESS && type == REG_SZ)
 +        {
 +            sz += sizeof (WCHAR);
 +            cls = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sz);
 +            cls[0] = 0;
 +            RegQueryValueExW(hkey, NULL, 0, &type, (LPBYTE) cls, &sz);
 +        }
 +
 +        RegCloseKey( hkey );
 +        lpClass = cls;
 +    }
 +
 +    TRACE("class = %s\n", debugstr_w(lpClass));
 +
 +    hkey = 0;
 +    if (lpClass)
 +        RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey);
 +
 +    HeapFree(GetProcessHeap(), 0, cls);
 +
 +    return hkey;
 +}
 +
 +static IDataObject *shellex_get_dataobj( LPSHELLEXECUTEINFOW sei )
 +{
 +    LPCITEMIDLIST pidllast = NULL;
 +    IDataObject *dataobj = NULL;
 +    IShellFolder *shf = NULL;
 +    LPITEMIDLIST pidl = NULL;
 +    HRESULT r;
 +
 +    if (sei->fMask & SEE_MASK_CLASSALL)
 +        pidl = (LPITEMIDLIST)sei->lpIDList;
 +    else
 +    {
 +        WCHAR fullpath[MAX_PATH];
 +        BOOL ret;
 +
 +        fullpath[0] = 0;
 +        ret = GetFullPathNameW(sei->lpFile, MAX_PATH, fullpath, NULL);
 +        if (!ret)
 +            goto end;
 +
 +        pidl = ILCreateFromPathW(fullpath);
 +    }
 +
 +    r = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shf), &pidllast);
 +    if (FAILED(r))
 +        goto end;
 +
 +    shf->GetUIObjectOf(NULL, 1, &pidllast, IID_NULL_PPV_ARG(IDataObject, &dataobj));
 +
 +end:
 +    if (pidl != sei->lpIDList)
 +        ILFree(pidl);
 +    if (shf)
 +        shf->Release();
 +    return dataobj;
 +}
 +
 +static HRESULT shellex_run_context_menu_default(IShellExtInit *obj,
 +        LPSHELLEXECUTEINFOW sei)
 +{
 +    IContextMenu *cm = NULL;
 +    CMINVOKECOMMANDINFOEX ici;
 +    MENUITEMINFOW info;
 +    WCHAR string[0x80];
 +    INT i, n, def = -1;
 +    HMENU hmenu = 0;
 +    HRESULT r;
 +
 +    TRACE("%p %p\n", obj, sei);
 +
 +    r = obj->QueryInterface(IID_PPV_ARG(IContextMenu, &cm));
 +    if (FAILED(r))
 +        return r;
 +
 +    hmenu = CreateMenu();
 +    if (!hmenu)
 +        goto end;
 +
 +    /* the number of the last menu added is returned in r */
 +    r = cm->QueryContextMenu(hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
 +    if (FAILED(r))
 +        goto end;
 +
 +    n = GetMenuItemCount(hmenu);
 +    for (i = 0; i < n; i++)
 +    {
 +        memset(&info, 0, sizeof(info));
 +        info.cbSize = sizeof info;
 +        info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_DATA | MIIM_ID;
 +        info.dwTypeData = string;
 +        info.cch = sizeof string;
 +        string[0] = 0;
 +        GetMenuItemInfoW(hmenu, i, TRUE, &info);
 +
 +        TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
 +              info.fState, info.dwItemData, info.fType, info.wID);
 +        if ((!sei->lpVerb && (info.fState & MFS_DEFAULT)) ||
 +            (sei->lpVerb && !lstrcmpiW(sei->lpVerb, string)))
 +        {
 +            def = i;
 +            break;
 +        }
 +    }
 +
 +    r = E_FAIL;
 +    if (def == -1)
 +        goto end;
 +
 +    memset(&ici, 0, sizeof ici);
 +    ici.cbSize = sizeof ici;
 +    ici.fMask = CMIC_MASK_UNICODE | (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
 +    ici.nShow = sei->nShow;
 +    ici.lpVerb = MAKEINTRESOURCEA(def);
 +    ici.hwnd = sei->hwnd;
 +    ici.lpParametersW = sei->lpParameters;
 +
 +    r = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
 +
 +    TRACE("invoke command returned %08x\n", r);
 +
 +end:
 +    if (hmenu)
 +        DestroyMenu( hmenu );
 +    if (cm)
 +        cm->Release();
 +    return r;
 +}
 +
 +static HRESULT shellex_load_object_and_run(HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei)
 +{
 +    IDataObject *dataobj = NULL;
 +    IObjectWithSite *ows = NULL;
 +    IShellExtInit *obj = NULL;
 +    HRESULT r;
 +
 +    TRACE("%p %s %p\n", hkey, debugstr_guid(guid), sei);
 +
 +    r = CoInitialize(NULL);
 +    if (FAILED(r))
 +        goto end;
 +
 +    r = CoCreateInstance(*guid, NULL, CLSCTX_INPROC_SERVER,
 +                         IID_PPV_ARG(IShellExtInit, &obj));
 +    if (FAILED(r))
 +    {
 +        ERR("failed %08x\n", r);
 +        goto end;
 +    }
 +
 +    dataobj = shellex_get_dataobj(sei);
 +    if (!dataobj)
 +    {
 +        ERR("failed to get data object\n");
 +        goto end;
 +    }
 +
 +    r = obj->Initialize(NULL, dataobj, hkey);
 +    if (FAILED(r))
 +        goto end;
 +
 +    r = obj->QueryInterface(IID_PPV_ARG(IObjectWithSite, &ows));
 +    if (FAILED(r))
 +        goto end;
 +
 +    ows->SetSite(NULL);
 +
 +    r = shellex_run_context_menu_default(obj, sei);
 +
 +end:
 +    if (ows)
 +        ows->Release();
 +    if (dataobj)
 +        dataobj->Release();
 +    if (obj)
 +        obj->Release();
 +    CoUninitialize();
 +    return r;
 +}
 +
 +
 +/*************************************************************************
 + *    ShellExecute_FromContextMenu [Internal]
 + */
 +static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei )
 +{
 +    HKEY hkey, hkeycm = 0;
 +    WCHAR szguid[39];
 +    HRESULT hr;
 +    GUID guid;
 +    DWORD i;
 +    LONG r;
 +
 +    TRACE("%s\n", debugstr_w(sei->lpFile));
 +
 +    hkey = ShellExecute_GetClassKey(sei);
 +    if (!hkey)
 +        return ERROR_FUNCTION_FAILED;
 +
 +    r = RegOpenKeyW(hkey, L"shellex\\ContextMenuHandlers", &hkeycm);
 +    if (r == ERROR_SUCCESS)
 +    {
 +        i = 0;
 +        while (1)
 +        {
 +            r = RegEnumKeyW(hkeycm, i++, szguid, sizeof(szguid) / sizeof(szguid[0]));
 +            if (r != ERROR_SUCCESS)
 +                break;
 +
 +            hr = CLSIDFromString(szguid, &guid);
 +            if (SUCCEEDED(hr))
 +            {
 +                /* stop at the first one that succeeds in running */
 +                hr = shellex_load_object_and_run(hkey, &guid, sei);
 +                if (SUCCEEDED(hr))
 +                    break;
 +            }
 +        }
 +        RegCloseKey(hkeycm);
 +    }
 +
 +    if (hkey != sei->hkeyClass)
 +        RegCloseKey(hkey);
 +    return r;
 +}
 +
 +static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR lpstrProtocol, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc);
 +
 +static UINT_PTR SHELL_execute_class(LPCWSTR wszApplicationName, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 +{
 +    WCHAR execCmd[1024], classname[1024];
 +    /* launch a document by fileclass like 'WordPad.Document.1' */
 +    /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */
 +    /* FIXME: wcmd should not be of a fixed size. Fixed to 1024, MAX_PATH is way too short! */
 +    ULONG cmask = (psei->fMask & SEE_MASK_CLASSALL);
 +    DWORD resultLen;
 +    BOOL done;
 +    UINT_PTR rslt;
-     
++
 +    /* FIXME: remove following block when SHELL_quote_and_execute supports hkeyClass parameter */
 +    if (cmask != SEE_MASK_CLASSNAME)
 +    {
 +        WCHAR wcmd[1024];
 +        HCR_GetExecuteCommandW((cmask == SEE_MASK_CLASSKEY) ? psei->hkeyClass : NULL,
 +                               (cmask == SEE_MASK_CLASSNAME) ? psei->lpClass : NULL,
 +                               psei->lpVerb,
 +                               execCmd, sizeof(execCmd));
 +
 +        /* FIXME: get the extension of lpFile, check if it fits to the lpClass */
 +        TRACE("SEE_MASK_CLASSNAME->%s, doc->%s\n", debugstr_w(execCmd), debugstr_w(wszApplicationName));
 +
 +        wcmd[0] = '\0';
 +        done = SHELL_ArgifyW(wcmd, sizeof(wcmd) / sizeof(WCHAR), execCmd, wszApplicationName, (LPITEMIDLIST)psei->lpIDList, NULL, &resultLen);
 +        if (!done && wszApplicationName[0])
 +        {
 +            strcatW(wcmd, L" ");
 +            if (*wszApplicationName != '"')
 +            {
 +                strcatW(wcmd, L"\"");
 +                strcatW(wcmd, wszApplicationName);
 +                strcatW(wcmd, L"\"");
 +            }
 +            else
 +                strcatW(wcmd, wszApplicationName);
 +        }
 +        if (resultLen > sizeof(wcmd) / sizeof(WCHAR))
 +            ERR("Argify buffer not large enough... truncating\n");
 +        return execfunc(wcmd, NULL, FALSE, psei, psei_out);
 +    }
++
 +    strcpyW(classname, psei->lpClass);
 +    rslt = SHELL_FindExecutableByVerb(psei->lpVerb, NULL, classname, execCmd, sizeof(execCmd));
 +
 +    TRACE("SHELL_FindExecutableByVerb returned %u (%s, %s)\n", (unsigned int)rslt, debugstr_w(classname), debugstr_w(execCmd));
 +    if (33 > rslt)
 +        return rslt;
 +    rslt = SHELL_quote_and_execute( execCmd, L"", classname,
 +                                      wszApplicationName, NULL, psei,
 +                                      psei_out, execfunc );
 +    return rslt;
 +
 +}
 +
 +static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters, DWORD parametersLen, LPWSTR wszApplicationName, DWORD dwApplicationNameLen)
 +{
 +    static const WCHAR wExplorer[] = L"explorer.exe";
 +    WCHAR buffer[MAX_PATH];
 +    BOOL appKnownSingular = FALSE;
 +
 +    /* last chance to translate IDList: now also allow CLSID paths */
 +    if (SUCCEEDED(SHELL_GetPathFromIDListForExecuteW((LPCITEMIDLIST)sei->lpIDList, buffer, sizeof(buffer)/sizeof(WCHAR)))) {
 +        if (buffer[0] == ':' && buffer[1] == ':') {
 +            /* open shell folder for the specified class GUID */
 +            if (strlenW(buffer) + 1 > parametersLen)
 +                ERR("parameters len exceeds buffer size (%i > %i), truncating\n",
 +                    lstrlenW(buffer) + 1, parametersLen);
 +            lstrcpynW(wszParameters, buffer, parametersLen);
 +            if (strlenW(wExplorer) > dwApplicationNameLen)
 +                ERR("application len exceeds buffer size (%i > %i), truncating\n",
 +                    lstrlenW(wExplorer) + 1, dwApplicationNameLen);
 +            lstrcpynW(wszApplicationName, wExplorer, dwApplicationNameLen);
 +            appKnownSingular = TRUE;
 +
 +            sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
 +        } else {
 +            WCHAR target[MAX_PATH];
 +            DWORD attribs;
 +            DWORD resultLen;
 +            /* Check if we're executing a directory and if so use the
 +               handler for the Folder class */
 +            strcpyW(target, buffer);
 +            attribs = GetFileAttributesW(buffer);
 +            if (attribs != INVALID_FILE_ATTRIBUTES &&
 +                    (attribs & FILE_ATTRIBUTE_DIRECTORY) &&
 +                    HCR_GetExecuteCommandW(0, L"Folder",
 +                                           sei->lpVerb,
 +                                           buffer, sizeof(buffer))) {
 +                SHELL_ArgifyW(wszApplicationName, dwApplicationNameLen,
 +                              buffer, target, (LPITEMIDLIST)sei->lpIDList, NULL, &resultLen);
 +                if (resultLen > dwApplicationNameLen)
 +                    ERR("Argify buffer not large enough... truncating\n");
 +                appKnownSingular = FALSE;
 +            }
 +            sei->fMask &= ~SEE_MASK_INVOKEIDLIST;
 +        }
 +    }
 +    return appKnownSingular;
 +}
 +
 +static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR wszKeyname, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 +{
 +    UINT_PTR retval;
 +    DWORD len;
 +    WCHAR *wszQuotedCmd;
 +
 +    /* Length of quotes plus length of command plus NULL terminator */
 +    len = 2 + lstrlenW(wcmd) + 1;
 +    if (wszParameters[0])
 +    {
 +        /* Length of space plus length of parameters */
 +        len += 1 + lstrlenW(wszParameters);
 +    }
 +    wszQuotedCmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +    /* Must quote to handle case where cmd contains spaces,
 +     * else security hole if malicious user creates executable file "C:\\Program"
 +     */
 +    strcpyW(wszQuotedCmd, L"\"");
 +    strcatW(wszQuotedCmd, wcmd);
 +    strcatW(wszQuotedCmd, L"\"");
 +    if (wszParameters[0])
 +    {
 +        strcatW(wszQuotedCmd, L" ");
 +        strcatW(wszQuotedCmd, wszParameters);
 +    }
 +
 +    TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(psei->lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(wszKeyname));
 +
 +    if (*wszKeyname)
 +        retval = execute_from_key(wszKeyname, wszApplicationName, env, psei->lpParameters, wcmd, execfunc, psei, psei_out);
 +    else
 +        retval = execfunc(wszQuotedCmd, env, FALSE, psei, psei_out);
 +    HeapFree(GetProcessHeap(), 0, wszQuotedCmd);
 +    return retval;
 +}
 +
 +static UINT_PTR SHELL_execute_url(LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
 +{
 +    static const WCHAR wShell[] = L"\\shell\\";
 +    static const WCHAR wCommand[] = L"\\command";
 +    UINT_PTR retval;
 +    WCHAR *lpstrProtocol;
 +    LPCWSTR lpstrRes;
 +    INT iSize;
 +    DWORD len;
 +
 +    lpstrRes = strchrW(lpFile, ':');
 +    if (lpstrRes)
 +        iSize = lpstrRes - lpFile;
 +    else
 +        iSize = strlenW(lpFile);
 +
 +    TRACE("Got URL: %s\n", debugstr_w(lpFile));
 +    /* Looking for ...<protocol>\shell\<lpVerb>\command */
 +    len = iSize + lstrlenW(wShell) + lstrlenW(wCommand) + 1;
 +    if (psei->lpVerb && *psei->lpVerb)
 +        len += lstrlenW(psei->lpVerb);
 +    else
 +        len += lstrlenW(wszOpen);
 +    lpstrProtocol = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +    memcpy(lpstrProtocol, lpFile, iSize * sizeof(WCHAR));
 +    lpstrProtocol[iSize] = '\0';
 +    strcatW(lpstrProtocol, wShell);
 +    strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb : wszOpen);
 +    strcatW(lpstrProtocol, wCommand);
 +
 +    retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
 +                              wcmd, execfunc, psei, psei_out);
 +    HeapFree(GetProcessHeap(), 0, lpstrProtocol);
 +    return retval;
 +}
 +
 +static void do_error_dialog(UINT_PTR retval, HWND hwnd, WCHAR* filename)
 +{
 +    WCHAR msg[2048];
 +    DWORD_PTR msgArguments[3]  = { (DWORD_PTR)filename, 0, 0 };
 +    DWORD error_code;
 +
 +    error_code = GetLastError();
 +
 +    if (retval == SE_ERR_NOASSOC)
 +        LoadStringW(shell32_hInstance, IDS_SHLEXEC_NOASSOC, msg, sizeof(msg) / sizeof(WCHAR));
 +    else
 +        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
 +                       NULL,
 +                       error_code,
 +                       LANG_USER_DEFAULT,
 +                       msg,
 +                       sizeof(msg) / sizeof(WCHAR),
 +                       (va_list*)msgArguments);
 +
 +    MessageBoxW(hwnd, msg, NULL, MB_ICONERROR);
 +}
 +
 +/*************************************************************************
 + *    SHELL_execute [Internal]
 + */
 +static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
 +{
 +    static const DWORD unsupportedFlags =
 +        SEE_MASK_INVOKEIDLIST  | SEE_MASK_ICON         | SEE_MASK_HOTKEY |
 +        SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
 +        SEE_MASK_UNICODE       | SEE_MASK_ASYNCOK      | SEE_MASK_HMONITOR;
 +
 +    WCHAR parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024];
 +    WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd;
 +    DWORD dwApplicationNameLen = MAX_PATH + 2;
 +    DWORD parametersLen = sizeof(parametersBuffer) / sizeof(WCHAR);
 +    DWORD dirLen = sizeof(dirBuffer) / sizeof(WCHAR);
 +    DWORD wcmdLen = sizeof(wcmdBuffer) / sizeof(WCHAR);
 +    DWORD len;
 +    SHELLEXECUTEINFOW sei_tmp;    /* modifiable copy of SHELLEXECUTEINFO struct */
 +    WCHAR wfileName[MAX_PATH];
 +    WCHAR *env;
 +    WCHAR wszKeyname[256];
 +    LPCWSTR lpFile;
 +    UINT_PTR retval = SE_ERR_NOASSOC;
 +    BOOL appKnownSingular = FALSE;
 +
 +    /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
 +    sei_tmp = *sei;
 +
 +    TRACE("mask=0x%08x hwnd=%p verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s\n",
 +          sei_tmp.fMask, sei_tmp.hwnd, debugstr_w(sei_tmp.lpVerb),
 +          debugstr_w(sei_tmp.lpFile), debugstr_w(sei_tmp.lpParameters),
 +          debugstr_w(sei_tmp.lpDirectory), sei_tmp.nShow,
 +          ((sei_tmp.fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME) ?
 +          debugstr_w(sei_tmp.lpClass) : "not used");
 +
 +    sei->hProcess = NULL;
 +
 +    /* make copies of all path/command strings */
 +    if (!sei_tmp.lpFile)
 +    {
 +        wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
 +        *wszApplicationName = '\0';
 +    }
 +    else if (*sei_tmp.lpFile == '\"')
 +    {
 +        DWORD l = strlenW(sei_tmp.lpFile + 1);
 +        if(l >= dwApplicationNameLen)
 +            dwApplicationNameLen = l + 1;
 +
 +        wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
 +        memcpy(wszApplicationName, sei_tmp.lpFile + 1, (l + 1)*sizeof(WCHAR));
 +
 +        if (wszApplicationName[l-1] == L'\"')
 +            wszApplicationName[l-1] = L'\0';
 +        appKnownSingular = TRUE;
 +
 +        TRACE("wszApplicationName=%s\n", debugstr_w(wszApplicationName));
 +    }
 +    else
 +    {
 +        DWORD l = strlenW(sei_tmp.lpFile) + 1;
 +        if(l > dwApplicationNameLen) dwApplicationNameLen = l + 1;
 +        wszApplicationName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwApplicationNameLen * sizeof(WCHAR));
 +        memcpy(wszApplicationName, sei_tmp.lpFile, l * sizeof(WCHAR));
 +    }
 +
 +    wszParameters = parametersBuffer;
 +    if (sei_tmp.lpParameters)
 +    {
 +        len = lstrlenW(sei_tmp.lpParameters) + 1;
 +        if (len > parametersLen)
 +        {
 +            wszParameters = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +            parametersLen = len;
 +        }
 +        strcpyW(wszParameters, sei_tmp.lpParameters);
 +    }
 +    else
 +        *wszParameters = L'\0';
 +
 +    wszDir = dirBuffer;
 +    if (sei_tmp.lpDirectory)
 +    {
 +        len = lstrlenW(sei_tmp.lpDirectory) + 1;
 +        if (len > dirLen)
 +        {
 +            wszDir = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +            dirLen = len;
 +        }
 +        strcpyW(wszDir, sei_tmp.lpDirectory);
 +    }
 +    else
 +        *wszDir = L'\0';
 +
 +    /* adjust string pointers to point to the new buffers */
 +    sei_tmp.lpFile = wszApplicationName;
 +    sei_tmp.lpParameters = wszParameters;
 +    sei_tmp.lpDirectory = wszDir;
 +
 +    if (sei_tmp.fMask & unsupportedFlags)
 +    {
 +        FIXME("flags ignored: 0x%08x\n", sei_tmp.fMask & unsupportedFlags);
 +    }
 +
 +    /* process the IDList */
 +    if (sei_tmp.fMask & SEE_MASK_IDLIST)
 +    {
 +        IShellExecuteHookW* pSEH;
 +
 +        HRESULT hr = SHBindToParent((LPCITEMIDLIST)sei_tmp.lpIDList, IID_PPV_ARG(IShellExecuteHookW, &pSEH), NULL);
 +
 +        if (SUCCEEDED(hr))
 +        {
 +            hr = pSEH->Execute(&sei_tmp);
 +
 +            pSEH->Release();
 +
 +            if (hr == S_OK)
 +            {
 +                HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +                if (wszParameters != parametersBuffer)
 +                    HeapFree(GetProcessHeap(), 0, wszParameters);
 +                if (wszDir != dirBuffer)
 +                    HeapFree(GetProcessHeap(), 0, wszDir);
 +                return TRUE;
 +            }
 +        }
 +
 +        SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName);
 +        appKnownSingular = TRUE;
 +        TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
 +    }
 +
 +    if (ERROR_SUCCESS == ShellExecute_FromContextMenu(&sei_tmp))
 +    {
 +        sei->hInstApp = (HINSTANCE) 33;
 +        HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +        if (wszParameters != parametersBuffer)
 +            HeapFree(GetProcessHeap(), 0, wszParameters);
 +        if (wszDir != dirBuffer)
 +            HeapFree(GetProcessHeap(), 0, wszDir);
 +        return TRUE;
 +    }
 +
 +    if (sei_tmp.fMask & SEE_MASK_CLASSALL)
 +    {
 +        retval = SHELL_execute_class(wszApplicationName, &sei_tmp, sei, execfunc);
 +        if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
 +        {
 +            OPENASINFO Info;
 +
 +            //FIXME
 +            // need full path
 +
 +            Info.pcszFile = wszApplicationName;
 +            Info.pcszClass = NULL;
 +            Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
 +
 +            //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
++            DBG_UNREFERENCED_LOCAL_VARIABLE(Info);
 +            do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
 +        }
 +        HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +        if (wszParameters != parametersBuffer)
 +            HeapFree(GetProcessHeap(), 0, wszParameters);
 +        if (wszDir != dirBuffer)
 +            HeapFree(GetProcessHeap(), 0, wszDir);
 +        return retval > 32;
 +    }
 +
 +    /* Has the IDList not yet been translated? */
 +    if (sei_tmp.fMask & SEE_MASK_IDLIST)
 +    {
 +        appKnownSingular = SHELL_translate_idlist( &sei_tmp, wszParameters,
 +                           parametersLen,
 +                           wszApplicationName,
 +                           dwApplicationNameLen );
 +    }
 +
 +    /* convert file URLs */
 +    if (UrlIsFileUrlW(sei_tmp.lpFile))
 +    {
 +        LPWSTR buf;
 +        DWORD size;
 +
 +        size = MAX_PATH;
 +        buf = static_cast<LPWSTR>(HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)));
 +        if (!buf || FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
 +        {
 +            HeapFree(GetProcessHeap(), 0, buf);
 +            return SE_ERR_OOM;
 +        }
 +
 +        HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +        dwApplicationNameLen = lstrlenW(buf) + 1;
 +        wszApplicationName = buf;
 +        sei_tmp.lpFile = wszApplicationName;
 +    }
 +    else /* or expand environment strings (not both!) */
 +    {
 +        len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
 +        if (len > 0)
 +        {
 +            LPWSTR buf;
 +            buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
 +
 +            ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len + 1);
 +            HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +            dwApplicationNameLen = len + 1;
 +            wszApplicationName = buf;
 +            /* appKnownSingular unmodified */
 +
 +            sei_tmp.lpFile = wszApplicationName;
 +        }
 +    }
 +
 +    if (*sei_tmp.lpDirectory)
 +    {
 +        len = ExpandEnvironmentStringsW(sei_tmp.lpDirectory, NULL, 0);
 +        if (len > 0)
 +        {
 +            LPWSTR buf;
 +            len++;
 +            buf = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +            ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buf, len);
 +            if (wszDir != dirBuffer)
 +                HeapFree(GetProcessHeap(), 0, wszDir);
 +            wszDir = buf;
 +            sei_tmp.lpDirectory = wszDir;
 +        }
 +    }
 +
 +    /* Else, try to execute the filename */
 +    TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir));
 +
 +    /* separate out command line arguments from executable file name */
 +    if (!*sei_tmp.lpParameters && !appKnownSingular)
 +    {
 +        /* If the executable path is quoted, handle the rest of the command line as parameters. */
 +        if (sei_tmp.lpFile[0] == L'"')
 +        {
 +            LPWSTR src = wszApplicationName/*sei_tmp.lpFile*/ + 1;
 +            LPWSTR dst = wfileName;
 +            LPWSTR end;
 +
 +            /* copy the unquoted executable path to 'wfileName' */
 +            while(*src && *src != L'"')
 +                *dst++ = *src++;
 +
 +            *dst = L'\0';
 +
 +            if (*src == L'"')
 +            {
 +                end = ++src;
 +
 +                while(isspace(*src))
 +                    ++src;
 +            }
 +            else
 +                end = src;
 +
 +            /* copy the parameter string to 'wszParameters' */
 +            strcpyW(wszParameters, src);
 +
 +            /* terminate previous command string after the quote character */
 +            *end = L'\0';
 +            lpFile = wfileName;
 +        }
 +        else
 +        {
 +            /* If the executable name is not quoted, we have to use this search loop here,
 +               that in CreateProcess() is not sufficient because it does not handle shell links. */
 +            WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
 +            LPWSTR space, s;
 +
 +            LPWSTR beg = wszApplicationName/*sei_tmp.lpFile*/;
 +            for(s = beg; (space = const_cast<LPWSTR>(strchrW(s, L' '))); s = space + 1)
 +            {
 +                int idx = space - sei_tmp.lpFile;
 +                memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
 +                buffer[idx] = '\0';
 +
 +                /*FIXME This finds directory paths if the targeted file name contains spaces. */
 +                if (SearchPathW(*sei_tmp.lpDirectory ? sei_tmp.lpDirectory : NULL, buffer, wszExe, sizeof(xlpFile) / sizeof(xlpFile[0]), xlpFile, NULL))
 +                {
 +                    /* separate out command from parameter string */
 +                    LPCWSTR p = space + 1;
 +
 +                    while(isspaceW(*p))
 +                        ++p;
 +
 +                    strcpyW(wszParameters, p);
 +                    *space = L'\0';
 +
 +                    break;
 +                }
 +            }
 +
 +            lpFile = sei_tmp.lpFile;
 +        }
 +    }
 +    else
 +        lpFile = sei_tmp.lpFile;
 +
 +    wcmd = wcmdBuffer;
 +    len = lstrlenW(wszApplicationName) + 3;
 +    if (sei_tmp.lpParameters[0])
 +        len += 1 + lstrlenW(wszParameters);
 +    if (len > wcmdLen)
 +    {
 +        wcmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +        wcmdLen = len;
 +    }
 +    swprintf(wcmd, L"\"%s\"", wszApplicationName);
 +    if (sei_tmp.lpParameters[0])
 +    {
 +        strcatW(wcmd, L" ");
 +        strcatW(wcmd, wszParameters);
 +    }
 +
 +    retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei);
 +    if (retval > 32)
 +    {
 +        HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +        if (wszParameters != parametersBuffer)
 +            HeapFree(GetProcessHeap(), 0, wszParameters);
 +        if (wszDir != dirBuffer)
 +            HeapFree(GetProcessHeap(), 0, wszDir);
 +        if (wcmd != wcmdBuffer)
 +            HeapFree(GetProcessHeap(), 0, wcmd);
 +        return TRUE;
 +    }
 +
 +    /* Else, try to find the executable */
 +    wcmd[0] = L'\0';
 +    retval = SHELL_FindExecutable(sei_tmp.lpDirectory, lpFile, sei_tmp.lpVerb, wcmd, wcmdLen, wszKeyname, &env, (LPITEMIDLIST)sei_tmp.lpIDList, sei_tmp.lpParameters);
 +    if (retval > 32)  /* Found */
 +    {
 +        retval = SHELL_quote_and_execute(wcmd, wszParameters, wszKeyname,
 +                                         wszApplicationName, env, &sei_tmp,
 +                                         sei, execfunc);
 +        HeapFree(GetProcessHeap(), 0, env);
 +    }
 +    else if (PathIsDirectoryW(lpFile))
 +    {
 +        WCHAR wExec[MAX_PATH];
 +        WCHAR * lpQuotedFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (strlenW(lpFile) + 3));
 +
 +        if (lpQuotedFile)
 +        {
 +            retval = SHELL_FindExecutable(sei_tmp.lpDirectory, L"explorer",
 +                                          wszOpen, wExec, MAX_PATH,
 +                                          NULL, &env, NULL, NULL);
 +            if (retval > 32)
 +            {
 +                swprintf(lpQuotedFile, L"\"%s\"", lpFile);
 +                retval = SHELL_quote_and_execute(wExec, lpQuotedFile,
 +                                                 wszKeyname,
 +                                                 wszApplicationName, env,
 +                                                 &sei_tmp, sei, execfunc);
 +                HeapFree(GetProcessHeap(), 0, env);
 +            }
 +            HeapFree(GetProcessHeap(), 0, lpQuotedFile);
 +        }
 +        else
 +            retval = 0; /* Out of memory */
 +    }
 +    else if (PathIsURLW(lpFile))    /* File not found, check for URL */
 +    {
 +        retval = SHELL_execute_url(lpFile, wcmd, &sei_tmp, sei, execfunc );
 +    }
 +    /* Check if file specified is in the form www.??????.*** */
 +    else if (!strncmpiW(lpFile, L"www", 3))
 +    {
 +        /* if so, prefix lpFile with http:// and call ShellExecute */
 +        WCHAR lpstrTmpFile[256];
 +        strcpyW(lpstrTmpFile, L"http://");
 +        strcatW(lpstrTmpFile, lpFile);
 +        retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0);
 +    }
 +
 +    TRACE("retval %lu\n", retval);
 +
 +    if (retval <= 32 && !(sei_tmp.fMask & SEE_MASK_FLAG_NO_UI))
 +    {
 +        OPENASINFO Info;
 +
 +        //FIXME
 +        // need full path
 +
 +        Info.pcszFile = wszApplicationName;
 +        Info.pcszClass = NULL;
 +        Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
 +
 +        //if (SHOpenWithDialog(sei_tmp.hwnd, &Info) != S_OK)
++        DBG_UNREFERENCED_LOCAL_VARIABLE(Info);
 +        do_error_dialog(retval, sei_tmp.hwnd, wszApplicationName);
 +    }
 +
 +    HeapFree(GetProcessHeap(), 0, wszApplicationName);
 +    if (wszParameters != parametersBuffer)
 +        HeapFree(GetProcessHeap(), 0, wszParameters);
 +    if (wszDir != dirBuffer)
 +        HeapFree(GetProcessHeap(), 0, wszDir);
 +    if (wcmd != wcmdBuffer)
 +        HeapFree(GetProcessHeap(), 0, wcmd);
 +
 +    sei->hInstApp = (HINSTANCE)(retval > 32 ? 33 : retval);
 +
 +    return retval > 32;
 +}
 +
 +/*************************************************************************
 + * ShellExecuteA            [SHELL32.290]
 + */
 +HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile,
 +                               LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
 +{
 +    SHELLEXECUTEINFOA sei;
 +
 +    TRACE("%p,%s,%s,%s,%s,%d\n",
 +          hWnd, debugstr_a(lpVerb), debugstr_a(lpFile),
 +          debugstr_a(lpParameters), debugstr_a(lpDirectory), iShowCmd);
 +
 +    sei.cbSize = sizeof(sei);
 +    sei.fMask = SEE_MASK_FLAG_NO_UI;
 +    sei.hwnd = hWnd;
 +    sei.lpVerb = lpVerb;
 +    sei.lpFile = lpFile;
 +    sei.lpParameters = lpParameters;
 +    sei.lpDirectory = lpDirectory;
 +    sei.nShow = iShowCmd;
 +    sei.lpIDList = 0;
 +    sei.lpClass = 0;
 +    sei.hkeyClass = 0;
 +    sei.dwHotKey = 0;
 +    sei.hProcess = 0;
 +
 +    ShellExecuteExA(&sei);
 +    return sei.hInstApp;
 +}
 +
 +/*************************************************************************
 + * ShellExecuteExA                [SHELL32.292]
 + *
 + */
 +BOOL
 +WINAPI
 +DECLSPEC_HOTPATCH
 +ShellExecuteExA(LPSHELLEXECUTEINFOA sei)
 +{
 +    SHELLEXECUTEINFOW seiW;
 +    BOOL ret;
 +    WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL, *wClass = NULL;
 +
 +    TRACE("%p\n", sei);
 +
 +    memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
 +
 +    if (sei->lpVerb)
 +        seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
 +
 +    if (sei->lpFile)
 +        seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
 +
 +    if (sei->lpParameters)
 +        seiW.lpParameters = __SHCloneStrAtoW(&wParameters, sei->lpParameters);
 +
 +    if (sei->lpDirectory)
 +        seiW.lpDirectory = __SHCloneStrAtoW(&wDirectory, sei->lpDirectory);
 +
 +    if ((sei->fMask & SEE_MASK_CLASSALL) == SEE_MASK_CLASSNAME && sei->lpClass)
 +        seiW.lpClass = __SHCloneStrAtoW(&wClass, sei->lpClass);
 +    else
 +        seiW.lpClass = NULL;
 +
 +    ret = SHELL_execute(&seiW, SHELL_ExecuteW);
 +
 +    sei->hInstApp = seiW.hInstApp;
 +
 +    if (sei->fMask & SEE_MASK_NOCLOSEPROCESS)
 +        sei->hProcess = seiW.hProcess;
 +
 +    SHFree(wVerb);
 +    SHFree(wFile);
 +    SHFree(wParameters);
 +    SHFree(wDirectory);
 +    SHFree(wClass);
 +
 +    return ret;
 +}
 +
 +/*************************************************************************
 + * ShellExecuteExW                [SHELL32.293]
 + *
 + */
 +BOOL
 +WINAPI
 +DECLSPEC_HOTPATCH
 +ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
 +{
 +    return SHELL_execute(sei, SHELL_ExecuteW);
 +}
 +
 +/*************************************************************************
 + * ShellExecuteW            [SHELL32.294]
 + * from shellapi.h
 + * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpVerb,
 + * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
 + */
 +HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile,
 +                               LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
 +{
 +    SHELLEXECUTEINFOW sei;
 +
 +    TRACE("\n");
 +    sei.cbSize = sizeof(sei);
 +    sei.fMask = SEE_MASK_FLAG_NO_UI;
 +    sei.hwnd = hwnd;
 +    sei.lpVerb = lpVerb;
 +    sei.lpFile = lpFile;
 +    sei.lpParameters = lpParameters;
 +    sei.lpDirectory = lpDirectory;
 +    sei.nShow = nShowCmd;
 +    sei.lpIDList = 0;
 +    sei.lpClass = 0;
 +    sei.hkeyClass = 0;
 +    sei.dwHotKey = 0;
 +    sei.hProcess = 0;
 +
 +    SHELL_execute(&sei, SHELL_ExecuteW);
 +    return sei.hInstApp;
 +}
 +
 +/*************************************************************************
 + * WOWShellExecute            [SHELL32.@]
 + *
 + * FIXME: the callback function most likely doesn't work the same way on Windows.
 + */
 +EXTERN_C HINSTANCE WINAPI WOWShellExecute(HWND hWnd, LPCSTR lpVerb, LPCSTR lpFile,
 +        LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd, void *callback)
 +{
 +    SHELLEXECUTEINFOW seiW;
 +    WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
 +    HANDLE hProcess = 0;
 +
 +    seiW.lpVerb = lpVerb ? __SHCloneStrAtoW(&wVerb, lpVerb) : NULL;
 +    seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
 +    seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
 +    seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
 +
 +    seiW.cbSize = sizeof(seiW);
 +    seiW.fMask = 0;
 +    seiW.hwnd = hWnd;
 +    seiW.nShow = iShowCmd;
 +    seiW.lpIDList = 0;
 +    seiW.lpClass = 0;
 +    seiW.hkeyClass = 0;
 +    seiW.dwHotKey = 0;
 +    seiW.hProcess = hProcess;
 +
 +    SHELL_execute(&seiW, (SHELL_ExecuteW32)callback);
 +
 +    SHFree(wVerb);
 +    SHFree(wFile);
 +    SHFree(wParameters);
 +    SHFree(wDirectory);
 +    return seiW.hInstApp;
 +}
 +
 +/*************************************************************************
 + * OpenAs_RunDLLA          [SHELL32.@]
 + */
 +EXTERN_C void WINAPI OpenAs_RunDLLA(HWND hwnd, HINSTANCE hinst, LPCSTR cmdline, int cmdshow)
 +{
 +    FIXME("%p, %p, %s, %d\n", hwnd, hinst, debugstr_a(cmdline), cmdshow);
 +}
 +
 +/*************************************************************************
 + * OpenAs_RunDLLW          [SHELL32.@]
 + */
 +EXTERN_C void WINAPI OpenAs_RunDLLW(HWND hwnd, HINSTANCE hinst, LPCWSTR cmdline, int cmdshow)
 +{
 +    FIXME("%p, %p, %s, %d\n", hwnd, hinst, debugstr_w(cmdline), cmdshow);
 +}
index 0000000,93ec06c..93ec06c
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0b21b83,614c28e..614c28e
Binary files differ
index bff8acc,6f76a2c..6f76a2c
Binary files differ
index 0d6ba85,d009d53..d009d53
Binary files differ
index ee160f6,57e665b..57e665b
Binary files differ
index 8fe2e0b,afc54cc..afc54cc
Binary files differ
index 4415a11,d799760..d799760
Binary files differ
index 9bc33ce,e330dc8..e330dc8
Binary files differ
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 7851c0a,0000000..31a9f23
mode 100644,000000..100644
--- /dev/null
@@@ -1,1229 -1,0 +1,1285 @@@
 +/*
 + * COPYRIGHT:        See COPYING in the top level directory
 + * PROJECT:          ReactOS Win32k subsystem
 + * PURPOSE:          Focus functions
 + * FILE:             subsystems/win32/win32k/ntuser/focus.c
 + * PROGRAMER:        ReactOS Team
 + */
 +
 +#include <win32k.h>
 +DBG_DEFAULT_CHANNEL(UserFocus);
 +
 +PUSER_MESSAGE_QUEUE gpqForeground = NULL;
 +PUSER_MESSAGE_QUEUE gpqForegroundPrev = NULL;
 +PTHREADINFO gptiForeground = NULL;
 +PPROCESSINFO gppiLockSFW = NULL;
 +ULONG guSFWLockCount = 0; // Rule #8, No menus are active. So should be zero.
 +PTHREADINFO ptiLastInput = NULL;
 +
 +/*
 +  Check locking of a process or one or more menus are active.
 +*/
 +BOOL FASTCALL
 +IsFGLocked(VOID)
 +{
 +   return (gppiLockSFW || guSFWLockCount);
 +}
 +
 +HWND FASTCALL
 +IntGetCaptureWindow(VOID)
 +{
 +   PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
 +   return ( ForegroundQueue ? (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : 0) : 0);
 +}
 +
 +HWND FASTCALL
 +IntGetThreadFocusWindow(VOID)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   if (!ThreadQueue)
 +     return NULL;
 +   return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 +}
 +
 +BOOL FASTCALL
 +co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
 +{
 +   USER_REFERENCE_ENTRY RefPrev;
 +   PWND WndPrev;
 +   BOOL Ret = TRUE;
 +
 +   if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
 +   {
 +      UserRefObjectCo(WndPrev, &RefPrev);
 +
 +      if (co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0)) //(LPARAM)hWnd))
 +      {
 +         co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
 +                    MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
 +                    (LPARAM)hWnd);
 +
 +         if (WndPrev)
 +            WndPrev->state &= ~WNDS_ACTIVEFRAME;
 +      }
 +      else
 +      {
 +         ERR("Application is keeping itself Active to prevent the change!\n");
 +         Ret = FALSE;
 +      }
 +
 +      UserDerefObjectCo(WndPrev);
 +   }
 +   return Ret;
 +}
 +
 +BOOL FASTCALL
 +co_IntMakeWindowActive(PWND Window)
 +{
 +  PWND spwndOwner;
 +  if (VerifyWnd(Window))
 +  {  // Set last active for window and it's owner.
 +     spwndOwner = Window;
 +     while (spwndOwner->spwndOwner)
 +     {
 +       spwndOwner = spwndOwner->spwndOwner;
 +     }
 +     spwndOwner->spwndLastActive = Window;
 +     return TRUE;
 +   }
 +   ERR("MakeWindowActive Failed!\n");
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
 +{
 +   USER_REFERENCE_ENTRY Ref, RefPrev;
 +   HANDLE OldTID, NewTID;
 +   PTHREADINFO pti, ptiOld, ptiNew;
 +   BOOL InAAPM = FALSE;
++
++   //ERR("SendActivateMessages\n");
++
 +   pti = PsGetCurrentThreadWin32Thread();
 +
 +   if (Window)
 +   {
-       ////
 +      UserRefObjectCo(Window, &Ref);
 +
 +      if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
 +
 +      /* Send palette messages */
 +      if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
 +          //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
 +          co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
 +      {
 +         UserSendNotifyMessage( HWND_BROADCAST,
 +                                WM_PALETTEISCHANGING,
 +                               (WPARAM)UserHMGetHandle(Window),
 +                                0);
 +      }
 +      //// Fixes CORE-6434.
 +      if (!(Window->style & WS_CHILD))
 +      {
 +         PWND pwndTemp = co_GetDesktopWindow(Window)->spwndChild;
 +
 +         while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
 +
 +         if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
 +         {
 +            if (!Async || pti->MessageQueue == gpqForeground)
 +            {
 +               UINT flags = SWP_NOSIZE | SWP_NOMOVE;
 +               if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
 +               //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
 +               co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags);
 +            }
 +         }
 +      }
 +      ////
 +      //// CORE-1161 and CORE-6651
 +      if (Window->spwndPrev)
 +      {
 +         HWND *phwndTopLevel, *phwndCurrent;
 +         PWND pwndCurrent, pwndDesktop;
 +
 +         pwndDesktop = UserGetDesktopWindow();
 +         if (Window->spwndParent == pwndDesktop )
 +         {
 +            phwndTopLevel = IntWinListChildren(pwndDesktop);
 +            phwndCurrent = phwndTopLevel;
 +            while(*phwndCurrent)
 +            {
 +                pwndCurrent = UserGetWindowObject(*phwndCurrent);
 +
 +                if (pwndCurrent && pwndCurrent->spwndOwner == Window )
 +                {
 +                    co_WinPosSetWindowPos(pwndCurrent, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
 +                }
 +                phwndCurrent++;
 +            }
 +            ExFreePool(phwndTopLevel);
 +          }
 +      }
-        OwnerWnd = Child->spwndOwner;
++   }
++   ////
++   OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
++   NewTID = Window ? IntGetWndThreadId(Window) : NULL;
++   ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
++   ptiNew = Window ? Window->head.pti : NULL;
++
++   //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
++
++   if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
++        (!WindowPrev || OldTID != NewTID) )
++   {
++      PWND cWindow;
++      HWND *List, *phWnd;
++
++      List = IntWinListChildren(UserGetDesktopWindow());
++      if ( List )
++      {
++         if ( OldTID )
++         {
++            ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
++            // Note: Do not set pci flags, this does crash!
++            for (phWnd = List; *phWnd; ++phWnd)
++            {
++               cWindow = ValidateHwndNoErr(*phWnd);
++               if (cWindow && cWindow->head.pti == ptiOld)
++               { // FALSE if the window is being deactivated,
++                 // ThreadId that owns the window being activated.
++                 //ERR("SendActivateMessage Old\n");
++                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
++               }
++            }
++            ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
++         }
++         if ( NewTID )
++         {  //// Prevents a resource crash due to reentrance!
++            InAAPM = TRUE;
++            pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
++            ////
++            for (phWnd = List; *phWnd; ++phWnd)
++            {
++               cWindow = ValidateHwndNoErr(*phWnd);
++               if (cWindow && cWindow->head.pti == ptiNew)
++               { // TRUE if the window is being activated,
++                 // ThreadId that owns the window being deactivated.
++                 //ERR("SendActivateMessage New\n");
++                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
++               }
++            }
++         }
++         ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
++      }
++   }
 +
++   if (Window)
++   {
 +      if (WindowPrev)
 +         UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
 +
 +      if (Window->state & WNDS_ACTIVEFRAME)
 +      {  // If already active frame do not allow NCPaint.
 +         //ERR("SendActivateMessage Is Active Frame!\n");
 +         Window->state |= WNDS_NONCPAINT;
 +      }
 +
 +      if (Window->style & WS_MINIMIZE)
 +      {
 +         TRACE("Widow was minimized\n");
 +      }
 +
 +      co_IntMakeWindowActive(Window);
 +
 +      co_IntSendMessageNoWait( UserHMGetHandle(Window),
 +                               WM_NCACTIVATE,
 +                              (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)),
 +                               0); //(LPARAM)hWndPrev);
 +
 +      co_IntSendMessageNoWait( UserHMGetHandle(Window),
 +                               WM_ACTIVATE,
 +                               MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE),
 +                              (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
 +
 +      if (Window->spwndParent == UserGetDesktopWindow() &&
 +          Window->spwndOwner == NULL &&
 +          (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
 +           (Window->ExStyle & WS_EX_APPWINDOW)))
 +      {
 +         // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
 +         co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
 +      }
 +      else
 +      {
 +          co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE);
 +      }
 +
 +      Window->state &= ~WNDS_NONCPAINT;
 +
 +      UserDerefObjectCo(Window);
 +   }
 +
 +   OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
 +   NewTID = Window ? IntGetWndThreadId(Window) : NULL;
 +   ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
 +   ptiNew = Window ? Window->head.pti : NULL;
 +
 +   //ERR("SendActivateMessage WindowPrev -> %x, Old -> %x, New -> %x\n", WindowPrev, OldTID, NewTID);
 +
 +   if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
 +        (OldTID != NewTID) )
 +   {
 +      PWND cWindow;
 +      HWND *List, *phWnd;
 +
 +      List = IntWinListChildren(UserGetDesktopWindow());
 +      if ( List )
 +      {
 +         if ( OldTID )
 +         {
 +            ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
 +            // Note: Do not set pci flags, this does crash!
 +            for (phWnd = List; *phWnd; ++phWnd)
 +            {
 +               cWindow = ValidateHwndNoErr(*phWnd);
 +               if (cWindow && cWindow->head.pti == ptiOld)
 +               {  // FALSE if the window is being deactivated,
 +                  // ThreadId that owns the window being activated.
 +                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
 +               }
 +            }
 +            ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
 +         }
 +         if ( NewTID )
 +         {  //// Prevents a resource crash due to reentrance!
 +            InAAPM = TRUE;
 +            pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
 +            ////
 +            for (phWnd = List; *phWnd; ++phWnd)
 +            {
 +               cWindow = ValidateHwndNoErr(*phWnd);
 +               if (cWindow && cWindow->head.pti == ptiNew)
 +               { // TRUE if the window is being activated,
 +                 // ThreadId that owns the window being deactivated.
 +                 co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
 +               }
 +            }
 +         }
 +         ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
 +      }
 +   }
 +   return InAAPM;
 +}
 +
 +VOID FASTCALL
 +IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
 +{
 +   PWND pWndPrev;
 +   PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
 +
 +   ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
 +   if (!pWnd && ThreadQueue->spwndActive)
 +   {
 +      ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
 +   }
 +
 +   pWndPrev = ThreadQueue->spwndFocus;
 +
 +   /* check if the specified window can be set in the input data of a given queue */
 +   if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
 +      /* set the current thread focus window */
 +      ThreadQueue->spwndFocus = pWnd;
 +
 +   if (pWnd)
 +   {
 +      if (pWndPrev)
 +      {
 +         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
 +         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
 +      }
 +      if (ThreadQueue->spwndFocus == pWnd)
 +      {
 +         IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
 +         //co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
 +         co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
 +      }
 +   }
 +   else
 +   {
 +      if (pWndPrev)
 +      {
 +         IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
 +         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
 +         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
 +      }
 +   }
 +}
 +
 +VOID FASTCALL
 +FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
 +{
 +   PTHREADINFO pti;
 +   PUSER_SENT_MESSAGE Message;
 +   PLIST_ENTRY Entry;
 +
 +   if (!Wnd) return;
 +
 +   pti = Wnd->head.pti;
 +
 +   if (!IsListEmpty(&pti->SentMessagesListHead))
 +   {
 +      // Scan sent queue messages to see if we received async messages.
 +      Entry = pti->SentMessagesListHead.Flink;
 +      Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
 +      do
 +      {
 +         if (IsListEmpty(Entry)) return;
 +         if (!Message) return;
 +         Entry = Message->ListEntry.Flink;
 +
 +         if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
 +             Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
 +             Message->Msg.wParam == wParam )
 +         {
 +             ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam);
 +             RemoveEntryList(&Message->ListEntry); // Purge the entry.
 +             ExFreePoolWithTag(Message, TAG_USRMSG);
 +         }
 +         Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
 +      }
 +      while (Entry != &pti->SentMessagesListHead);
 +   }
 +}
 +
 +BOOL FASTCALL
 +ToggleFGActivate(PTHREADINFO pti)
 +{
 +   BOOL Ret;
 +   PPROCESSINFO ppi = pti->ppi;
 +
 +   Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
 +   if (Ret)
 +   {
 +      pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
 +   }
 +   else
 +      Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
 +
 +   if (Ret)
 +      ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
 +   //ERR("ToggleFGActivate is %d\n",Ret);
 +   return Ret;
 +}
 +
 +BOOL FASTCALL
 +IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
 +{
 +   // Not allowed if one or more,,
 +   if (!ToggleFGActivate(pti) ||              // bits not set,
 +        pti->rpdesk != gpdeskInputDesktop ||  // not current Desktop,
 +        pti->MessageQueue == gpqForeground || // if already the queue foreground,
 +        IsFGLocked() ||                       // foreground is locked,
 +        Wnd->ExStyle & WS_EX_NOACTIVATE )     // or,,, does not become the foreground window when the user clicks it.
 +   {
 +      return FALSE;
 +   }
 +   //ERR("IsAllowedFGActive is TRUE\n");
 +   return TRUE;
 +}
 +
 +/*
 +   Can the system force foreground from one or more conditions.
 + */
 +BOOL FASTCALL
 +CanForceFG(PPROCESSINFO ppi)
 +{
 +   if (!ptiLastInput ||
 +        ptiLastInput->ppi == ppi ||
 +       !gptiForeground ||
 +        gptiForeground->ppi == ppi ||
 +        ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_SETFOREGROUNDALLOWED) ||
 +        gppiInputProvider == ppi ||
 +       !gpqForeground
 +      ) return TRUE;
 +   //ERR("CanForceFG is FALSE\n");
 +   return FALSE;
 +}
 +
 +/*
 +   MSDN:
 +   The system restricts which processes can set the foreground window. A process
 +   can set the foreground window only if one of the following conditions is true:
 +
 +    * The process is the foreground process.
 +    * The process was started by the foreground process.
 +    * The process received the last input event.
 +    * There is no foreground process.
 +    * The foreground process is being debugged.
 +    * The foreground is not locked (see LockSetForegroundWindow).
 +    * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
 +    * No menus are active.
 +*/
 +static
 +BOOL FASTCALL
 +co_IntSetForegroundAndFocusWindow(
 +    _In_ PWND Wnd,
 +    _In_ BOOL MouseActivate)
 +{
 +   HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
 +   HWND hWndPrev = NULL;
 +   PWND pWndPrev = NULL;
 +   PUSER_MESSAGE_QUEUE PrevForegroundQueue;
 +   PTHREADINFO pti;
 +   BOOL fgRet = FALSE, Ret = FALSE;
 +
 +   if (Wnd) ASSERT_REFS_CO(Wnd);
 +
 +   //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
 +
 +   PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
 +   pti = PsGetCurrentThreadWin32Thread();
 +
 +   if (PrevForegroundQueue)
 +   {  // Same Window Q as foreground just do active.
 +      if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue)
 +      {
 +         //ERR("Same Window Q as foreground just do active.\n");
 +         if (pti->MessageQueue == PrevForegroundQueue)
 +         { // Same WQ and TQ go active.
 +            //ERR("Same WQ and TQ go active.\n");
 +            Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
 +         }
 +         else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
 +         { // Same WQ and it is active.
 +            //ERR("Same WQ and it is active.\n");
 +            Ret = TRUE;
 +         }
 +         else
 +         { // Same WQ as FG but not the same TQ send active.
 +            //ERR("Same WQ as FG but not the same TQ send active.\n");
 +            co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
 +            Ret = TRUE;
 +         }
 +         return Ret;
 +      }
 +
 +      hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0;
 +      pWndPrev = PrevForegroundQueue->spwndActive;
 +   }
 +
 +   if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
 +         ( CanForceFG(pti->ppi) || pti->TIF_flags & (TIF_SYSTEMTHREAD|TIF_CSRSSTHREAD|TIF_ALLOWFOREGROUNDACTIVATE) )) ||
 +        pti->ppi == ppiScrnSaver
 +      )
 +   {
 +
 +      //ToggleFGActivate(pti); // win.c line 2662 fail
 +      if (Wnd)
 +      {
 +         IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
 +         gptiForeground = Wnd->head.pti;
 +         //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h);
 +      }
 +      else
 +      {
 +         IntSetFocusMessageQueue(NULL);
 +         gptiForeground = NULL;
 +         //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
 +      }
 +/*
 +     Henri Verbeet,
 +     What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
 +     other thread after we already changed the foreground window back to our own
 +     window.
 + */
 +      //ERR("SFAFW: 1\n");
 +      FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos!
 +
 +      fgRet = TRUE;
 +   }
 +
 +   //  Fix FG Bounce with regedit.
 +   if (hWndPrev != hWnd )
 +   {
 +      if (PrevForegroundQueue &&
 +          fgRet &&
 +          PrevForegroundQueue->spwndActive)
 +      {
 +         //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev);
 +         if (pti->MessageQueue == PrevForegroundQueue)
 +         {
 +            //ERR("SFGW: TI same as Prev TI\n");
 +            co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE);
 +         }
 +         else if (pWndPrev)
 +         {
 +            //ERR("SFGW Deactivate: TI not same as Prev TI\n");
 +            // No real reason to wait here.
 +            co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
 +         }
 +      }
 +   }
 +
 +   if (!Wnd) return FALSE; // Always return false.
 +
 +   if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
 +   {
 +       //ERR("Same PQ and WQ go active.\n");
 +       Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
 +   }
 +   else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
 +   {
 +       //ERR("Same Active and Wnd.\n");
 +       Ret = TRUE;
 +   }
 +   else
 +   {
 +       //ERR("Activate Not same PQ and WQ and Wnd.\n");
 +       co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
 +       Ret = TRUE;
 +   }
 +   return Ret && fgRet;
 +}
 +
 +/*
 +  Revision 7888, activate modal dialog when clicking on a disabled window.
 +*/
 +HWND FASTCALL
 +IntFindChildWindowToOwner(PWND Root, PWND Owner)
 +{
 +   HWND Ret;
 +   PWND Child, OwnerWnd;
 +
 +   for(Child = Root->spwndChild; Child; Child = Child->spwndNext)
 +   {
++      OwnerWnd = Child->spwndOwner;
 +      if(!OwnerWnd)
 +         continue;
 +
 +      if(OwnerWnd == Owner)
 +      {
 +         Ret = Child->head.h;
 +         return Ret;
 +      }
 +   }
 +   return NULL;
 +}
 +
 +BOOL FASTCALL
 +co_IntMouseActivateWindow(PWND Wnd)
 +{
 +   HWND Top;
 +   USER_REFERENCE_ENTRY Ref;
 +   ASSERT_REFS_CO(Wnd);
 +
 +   if (Wnd->style & WS_DISABLED)
 +   {
 +      BOOL Ret;
 +      PWND TopWnd;
 +      PWND DesktopWindow = UserGetDesktopWindow();
 +      if (DesktopWindow)
 +      {
 +         ERR("Window Diabled\n");
 +         Top = IntFindChildWindowToOwner(DesktopWindow, Wnd);
 +         if ((TopWnd = ValidateHwndNoErr(Top)))
 +         {
 +            UserRefObjectCo(TopWnd, &Ref);
 +            Ret = co_IntMouseActivateWindow(TopWnd);
 +            UserDerefObjectCo(TopWnd);
 +
 +            return Ret;
 +         }
 +      }
 +      return FALSE;
 +   }
 +   ERR("Mouse Active\n");
 +   co_IntSetForegroundAndFocusWindow(Wnd, TRUE);
 +   return TRUE;
 +}
 +
 +BOOL FASTCALL
 +co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +   PWND pWndChg, WndPrev; // State changes.
 +   HWND hWndPrev;
 +   HWND hWnd = 0;
 +   BOOL InAAPM;
 +   CBTACTIVATESTRUCT cbt;
 +   //ERR("co_IntSetActiveWindow 1\n");
 +   if (Wnd)
 +   {
 +      ASSERT_REFS_CO(Wnd);
 +      hWnd = UserHMGetHandle(Wnd);
 +      if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
 +      if (Wnd == UserGetDesktopWindow()) return FALSE;
 +      //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd);
 +   }
 +
 +   //ERR("co_IntSetActiveWindow 2\n");
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   ASSERT(ThreadQueue != 0);
 +
 +   hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
 +
 +   pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
 +
 +   while (Wnd)
 +   {
 +      BOOL Ret, DoFG, AllowFG;
 +
 +      if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE;
 +
 +      if (ThreadQueue == Wnd->head.pti->MessageQueue)
 +      {
 +         if (IsAllowedFGActive(pti, Wnd))
 +         {
 +             DoFG = TRUE;
 +         }
 +         else
 +         {
 +             //ERR("co_IntSetActiveWindow 3 Go Out!\n");
 +             break;
 +         }
 +         AllowFG = !pti->cVisWindows; // Nothing is visable.
 +         //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
 +      }
 +      else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
 +      {
 +         //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
 +         // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
 +         //if (!ForegroundQueue || ForegroundQueue == ThreadQueue)
 +         if (!gpqForeground || gpqForeground == ThreadQueue)
 +         {
 +            DoFG = TRUE;
 +         }
 +         else
 +            DoFG = FALSE;
 +         if (DoFG)
 +         {
 +            if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows)
 +               AllowFG = TRUE;
 +            else
 +               AllowFG = FALSE;
 +         }
 +         else
 +            AllowFG = FALSE;
 +         //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
 +      }
 +      Ret = FALSE;
 +      if (DoFG)
 +      {
 +         pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
 +         //ERR("co_IntSetActiveWindow 3c FG set\n");
 +         Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
 +         if (AllowFG)
 +         {
 +            pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
 +         }
 +         else
 +         {
 +            pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
 +         }
 +      }
 +      return Ret;
 +   }
 +
 +   /* Call CBT hook chain */
 +   cbt.fMouse     = bMouse;
 +   cbt.hWndActive = hWndPrev;
 +   if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
 +   {
 +      ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
 +      return FALSE;
 +   }
 +
 +   if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
 +      ThreadQueue->spwndActive = NULL;
 +   else
 +      ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
 +
 +   WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
 +
 +   if (WndPrev)
 +   {
 +      if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
 +      if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE;
 +   }
 +
 +   WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
 +
 +   // While in calling message proc or hook:
 +   // Fail if a preemptive switch was made, current active not made previous,
 +   // focus window is dead or no longer the same thread queue.
 +   if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
 +        pWndChg != WndPrev ||
 +        (Wnd && !VerifyWnd(Wnd)) ||
 +        ThreadQueue != pti->MessageQueue )
 +   {
 +      ERR("SetActiveWindow: Summery ERROR, active state changed!\n");
 +      return FALSE;
 +   }
 +
 +   if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
 +
 +   if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED;
 +
 +   IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 +   //// Breaks Atl-Esc/Tab via User32.
 +   ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages.
 +
 +   /* check if the specified window can be set in the input data of a given queue */
 +   if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue)
 +   {
 +      /* set the current thread active window */
 +      ThreadQueue->spwndActive = Wnd;
 +   }
 +
 +   WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
 +
 +   InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
 +
 +   /* now change focus if necessary */
 +   //// Fixes CORE-6452 allows setting focus on window.
 +   if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
 +   {
 +      /* Do not change focus if the window is no longer active */
 +      if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
 +      {
 +         PWND pWndSend = pti->MessageQueue->spwndActive;
 +         // Clear focus if the active window is minimized.
 +         if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL;
 +         // Send focus messages and if so, set the focus.
 +         IntSendFocusMessages( pti, pWndSend);
 +      }
 +   }
 +   ////
 +   if (InAAPM)
 +   {
 +      pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
 +   }
 +
 +   // FIXME: Used in the menu loop!!!
 +   //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
 +
 +   //ERR("co_IntSetActiveWindow Exit\n");
 +   if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
 +   return (ThreadQueue->spwndActive == Wnd);
 +}
 +
 +BOOL FASTCALL
 +UserSetActiveWindow(PWND Wnd)
 +{
 +  if (Wnd) // Must have a window!
 +  {
 +     if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
 +
 +     return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
 +  }
 +  /*
 +     Yes your eye are not deceiving you~!
 +  
 +     First part of wines Win.c test_SetActiveWindow:
 +
 +     flush_events( TRUE );
 +     ShowWindow(hwnd, SW_HIDE);
 +     SetFocus(0);
 +     SetActiveWindow(0);
 +     check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
 +
 +  */
 +  return FALSE;
 +}
 +
 +HWND FASTCALL
 +co_UserSetFocus(PWND Window)
 +{
 +   HWND hWndPrev = 0;
 +   PWND pwndTop;
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +
 +   if (Window)
 +      ASSERT_REFS_CO(Window);
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +   ASSERT(ThreadQueue != 0);
 +
 +   TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
 +
 +   hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 +
 +   if (Window != 0)
 +   {
 +      if (hWndPrev == UserHMGetHandle(Window))
 +      {
 +         return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
 +      }
 +
 +      if (Window->head.pti->MessageQueue != ThreadQueue)
 +      {
 +         ERR("SetFocus Must have the same Q!\n");
 +         return 0;
 +      }
 +
 +      /* Check if we can set the focus to this window */
 +      //// Fixes wine win test_SetParent both "todo" line 3710 and 3720...
 +      for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
 +      {
 +         if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
 +         if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
 +      }
 +      ////
 +      if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
 +      {
 +         ERR("SetFocus 1 WH_CBT Call Hook return!\n");
 +         return 0;
 +      }
 +
 +      /* Activate pwndTop if needed. */
 +      if (pwndTop != ThreadQueue->spwndActive)
 +      {
 +         PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
 +         if (ThreadQueue != ForegroundQueue &&am