* Sync to trunk r63845.
authorDavid Quintana <gigaherz@gmail.com>
Sat, 9 Aug 2014 14:15:16 +0000 (14:15 +0000)
committerDavid Quintana <gigaherz@gmail.com>
Sat, 9 Aug 2014 14:15:16 +0000 (14:15 +0000)
svn path=/branches/shell-experiments/; revision=63846

214 files changed:
1  2 
CMakeLists.txt
base/applications/calc/lang/tr-TR.rc
base/applications/charmap/about.c
base/applications/charmap/charmap.c
base/applications/charmap/lrgcell.c
base/applications/charmap/map.c
base/applications/charmap/settings.c
base/applications/games/spider/spider.cpp
base/applications/games/spider/spider.h
base/applications/games/spider/spigame.cpp
base/applications/mplay32/lang/tr-TR.rc
base/applications/mscutils/servman/lang/tr-TR.rc
base/applications/mspaint/lang/tr-TR.rc
base/applications/notepad/lang/tr-TR.rc
base/applications/rapps/lang/tr-TR.rc
base/applications/rapps/rapps/ghostscript.txt
base/applications/rapps/rapps/ghostview.txt
base/applications/rapps/rapps/miktex.txt
base/applications/rapps/rapps/net20.txt
base/applications/rapps/rapps/nirlauncher.txt
base/applications/rapps/rapps/qmmp.txt
base/applications/rapps/rapps/smplayer.txt
base/applications/regedit/lang/tr-TR.rc
base/applications/screensavers/logon/lang/tr-TR.rc
base/applications/sndrec32/lang/tr-TR.rc
base/applications/taskmgr/lang/tr-TR.rc
base/applications/winhlp32/lang/Tr.rc
base/applications/wordpad/lang/Tr.rc
base/setup/usetup/lang/tr-TR.h
base/shell/explorer/CMakeLists.txt
boot/bootdata/CMakeLists.txt
boot/bootdata/packages/CMakeLists.txt
cmake/CMakeMacros.cmake
dll/cpl/access/lang/tr-TR.rc
dll/cpl/console/console.c
dll/cpl/console/layout.c
dll/cpl/desk/lang/tr-TR.rc
dll/cpl/input/lang/tr-TR.rc
dll/cpl/main/lang/tr-TR.rc
dll/cpl/mmsys/lang/tr-TR.rc
dll/cpl/powercfg/lang/tr-TR.rc
dll/cpl/sysdm/lang/tr-TR.rc
dll/cpl/wined3dcfg/lang/cs-CZ.rc
dll/cpl/wined3dcfg/lang/de-DE.rc
dll/cpl/wined3dcfg/lang/en-US.rc
dll/cpl/wined3dcfg/lang/he-IL.rc
dll/cpl/wined3dcfg/lang/pl-PL.rc
dll/cpl/wined3dcfg/lang/ro-RO.rc
dll/cpl/wined3dcfg/lang/sq-AL.rc
dll/cpl/wined3dcfg/lang/tr-TR.rc
dll/ntdll/csr/capture.c
dll/win32/avifil32/lang/avifile_Tr.rc
dll/win32/browseui/CMakeLists.txt
dll/win32/browseui/precomp.h
dll/win32/browseui/shellbrowser.cpp
dll/win32/cards/COPYING
dll/win32/cards/res/bavarian/Ruecken1.bmp
dll/win32/cards/res/bavarian/Ruecken11.bmp
dll/win32/cards/res/bavarian/Ruecken12.bmp
dll/win32/cards/res/bavarian/Ruecken3.bmp
dll/win32/cards/res/bavarian/Ruecken4.bmp
dll/win32/cards/res/bavarian/Ruecken6.bmp
dll/win32/cards/res/bavarian/Ruecken8.bmp
dll/win32/cards/res/default/Background_6.bmp
dll/win32/cards/res/default/Clubs_Ace.bmp
dll/win32/cards/res/default/Clubs_Eight.bmp
dll/win32/cards/res/default/Clubs_Five.bmp
dll/win32/cards/res/default/Clubs_Four.bmp
dll/win32/cards/res/default/Clubs_Jack.bmp
dll/win32/cards/res/default/Clubs_King.bmp
dll/win32/cards/res/default/Clubs_Nine.bmp
dll/win32/cards/res/default/Clubs_Queen.bmp
dll/win32/cards/res/default/Clubs_Seven.bmp
dll/win32/cards/res/default/Clubs_Six.bmp
dll/win32/cards/res/default/Clubs_Ten.bmp
dll/win32/cards/res/default/Clubs_Three.bmp
dll/win32/cards/res/default/Clubs_Two.bmp
dll/win32/cards/res/default/Diamonds_Ace.bmp
dll/win32/cards/res/default/Diamonds_Eight.bmp
dll/win32/cards/res/default/Diamonds_Five.bmp
dll/win32/cards/res/default/Diamonds_Four.bmp
dll/win32/cards/res/default/Diamonds_Jack.bmp
dll/win32/cards/res/default/Diamonds_King.bmp
dll/win32/cards/res/default/Diamonds_Nine.bmp
dll/win32/cards/res/default/Diamonds_Queen.bmp
dll/win32/cards/res/default/Diamonds_Seven.bmp
dll/win32/cards/res/default/Diamonds_Six.bmp
dll/win32/cards/res/default/Diamonds_Ten.bmp
dll/win32/cards/res/default/Diamonds_Three.bmp
dll/win32/cards/res/default/Diamonds_Two.bmp
dll/win32/cards/res/default/Hearts_Ace.bmp
dll/win32/cards/res/default/Hearts_Eight.bmp
dll/win32/cards/res/default/Hearts_Five.bmp
dll/win32/cards/res/default/Hearts_Four.bmp
dll/win32/cards/res/default/Hearts_Jack.bmp
dll/win32/cards/res/default/Hearts_King.bmp
dll/win32/cards/res/default/Hearts_Nine.bmp
dll/win32/cards/res/default/Hearts_Queen.bmp
dll/win32/cards/res/default/Hearts_Seven.bmp
dll/win32/cards/res/default/Hearts_Six.bmp
dll/win32/cards/res/default/Hearts_Ten.bmp
dll/win32/cards/res/default/Hearts_Three.bmp
dll/win32/cards/res/default/Hearts_Two.bmp
dll/win32/cards/res/default/Spades_Ace.bmp
dll/win32/cards/res/default/Spades_Eight.bmp
dll/win32/cards/res/default/Spades_Five.bmp
dll/win32/cards/res/default/Spades_Four.bmp
dll/win32/cards/res/default/Spades_Jack.bmp
dll/win32/cards/res/default/Spades_King.bmp
dll/win32/cards/res/default/Spades_Nine.bmp
dll/win32/cards/res/default/Spades_Queen.bmp
dll/win32/cards/res/default/Spades_Seven.bmp
dll/win32/cards/res/default/Spades_Six.bmp
dll/win32/cards/res/default/Spades_Ten.bmp
dll/win32/cards/res/default/Spades_Three.bmp
dll/win32/cards/res/default/Spades_Two.bmp
dll/win32/comctl32/lang/comctl_Tr.rc
dll/win32/comctl32/rsrc.rc
dll/win32/comdlg32/lang/cdlg_Tr.rc
dll/win32/comdlg32/rsrc.rc
dll/win32/credui/lang/credui_Tr.rc
dll/win32/crypt32/lang/crypt32_Tr.rc
dll/win32/cryptdlg/lang/cryptdlg_Tr.rc
dll/win32/cryptui/lang/cryptui_Tr.rc
dll/win32/devmgr/lang/tr-TR.rc
dll/win32/getuname/getuname.rc
dll/win32/jscript/lang/jscript_Tr.rc
dll/win32/kernel32/client/console/alias.c
dll/win32/kernel32/client/console/console.c
dll/win32/kernel32/client/console/history.c
dll/win32/kernel32/client/console/readwrite.c
dll/win32/kernel32/client/handle.c
dll/win32/kernel32/include/console.h
dll/win32/kernel32/winnls/lang/tr-TR.rc
dll/win32/localui/lang/ui_Tr.rc
dll/win32/msgina/lang/tr-TR.rc
dll/win32/msvfw32/lang/msvfw32_Tr.rc
dll/win32/oledlg/lang/oledlg_Tr.rc
dll/win32/shell32/folders.cpp
dll/win32/shell32/iconcache.cpp
dll/win32/shell32/shfldr.h
dll/win32/shell32/shlfolder.cpp
drivers/filesystems/npfs/datasup.c
drivers/filesystems/npfs/readsup.c
drivers/filesystems/npfs/waitsup.c
include/ndk/mmtypes.h
include/reactos/libs/pseh/pseh3.h
include/reactos/subsys/csr/csr.h
include/reactos/subsys/win/conmsg.h
lib/pseh/i386/pseh3.c
ntoskrnl/CMakeLists.txt
ntoskrnl/config/i386/cmhardwr.c
ntoskrnl/include/internal/i386/ke.h
ntoskrnl/include/internal/mm.h
ntoskrnl/io/iomgr/iofunc.c
ntoskrnl/mm/ARM3/miarm.h
ntoskrnl/mm/ARM3/pagfault.c
ntoskrnl/mm/ARM3/pfnlist.c
ntoskrnl/mm/ARM3/section.c
ntoskrnl/mm/ARM3/virtual.c
ntoskrnl/mm/balance.c
ntoskrnl/mm/pagefile.c
ntoskrnl/mm/section.c
ntoskrnl/ntkrnlmp/CMakeLists.txt
ntoskrnl/ob/oblife.c
subsystems/ntvdm/CMakeLists.txt
subsystems/ntvdm/hardware/mouse.c
subsystems/ntvdm/hardware/mouse.h
subsystems/ntvdm/hardware/ps2.c
subsystems/ntvdm/hardware/ps2.h
subsystems/ntvdm/hardware/vga.c
win32ss/gdi/ntgdi/cliprgn.c
win32ss/user/ntuser/clipboard.c
win32ss/user/ntuser/cursoricon.c
win32ss/user/ntuser/cursoricon_new.c
win32ss/user/ntuser/menu.c
win32ss/user/user32/misc/stubs.c
win32ss/user/winsrv/consrv.cmake
win32ss/user/winsrv/consrv/alias.c
win32ss/user/winsrv/consrv/condrv/coninput.c
win32ss/user/winsrv/consrv/condrv/conoutput.c
win32ss/user/winsrv/consrv/condrv/console.c
win32ss/user/winsrv/consrv/condrv/dummyterm.c
win32ss/user/winsrv/consrv/condrv/graphics.c
win32ss/user/winsrv/consrv/condrv/text.c
win32ss/user/winsrv/consrv/coninput.c
win32ss/user/winsrv/consrv/coninput.h
win32ss/user/winsrv/consrv/conoutput.c
win32ss/user/winsrv/consrv/conoutput.h
win32ss/user/winsrv/consrv/console.c
win32ss/user/winsrv/consrv/console.h
win32ss/user/winsrv/consrv/consrv.h
win32ss/user/winsrv/consrv/frontendctl.c
win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
win32ss/user/winsrv/consrv/frontends/gui/guisettings.c
win32ss/user/winsrv/consrv/frontends/gui/guisettings.h
win32ss/user/winsrv/consrv/frontends/gui/guiterm.c
win32ss/user/winsrv/consrv/frontends/gui/guiterm.h
win32ss/user/winsrv/consrv/frontends/input.c
win32ss/user/winsrv/consrv/frontends/terminal.c
win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
win32ss/user/winsrv/consrv/frontends/tui/tuiterm.h
win32ss/user/winsrv/consrv/handle.c
win32ss/user/winsrv/consrv/handle.h
win32ss/user/winsrv/consrv/include/conio.h
win32ss/user/winsrv/consrv/include/conio_winsrv.h
win32ss/user/winsrv/consrv/include/console.h
win32ss/user/winsrv/consrv/include/rect.h
win32ss/user/winsrv/consrv/include/settings.h
win32ss/user/winsrv/consrv/include/term.h
win32ss/user/winsrv/consrv/init.c
win32ss/user/winsrv/consrv/lineinput.c
win32ss/user/winsrv/consrv/lineinput.h
win32ss/user/winsrv/consrv/procinit.h

diff --cc CMakeLists.txt
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index f212782,0000000..5b2a339
mode 100644,000000..100644
--- /dev/null
@@@ -1,66 -1,0 +1,71 @@@
 +
 +add_subdirectory(notifyhook)
 +
 +set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL)
 +
 +add_definitions(
 +    -DWIN32
 +    -D__WINDRES__)
 +
 +include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 +
 +list(APPEND SOURCE
 +    shell/mainframe.cpp
 +    shell/unixfs.cpp
 +    shell/ntobjfs.cpp
 +    shell/filechild.cpp
 +    shell/shellfs.cpp
 +    shell/fatfs.cpp
 +    shell/pane.cpp
 +    shell/regfs.cpp
 +    shell/webchild.cpp
 +    shell/entries.cpp
 +    shell/shellbrowser.cpp
 +    shell/winfs.cpp
 +    dialogs/searchprogram.cpp
 +    dialogs/settings.cpp
 +    taskbar/taskbar.cpp
 +    taskbar/favorites.cpp
 +    taskbar/quicklaunch.cpp
 +    taskbar/desktopbar.cpp
 +    taskbar/startmenu.cpp
 +    taskbar/traynotify.cpp
 +    services/shellservices.cpp
 +    desktop/desktop.cpp
 +    explorer.cpp
 +    utility/xs-native.cpp
 +    utility/shellclasses.cpp
 +    utility/dragdropimpl.cpp
 +    utility/utility.cpp
 +    utility/xmlstorage.cpp
 +    utility/window.cpp
 +    utility/shellbrowserimpl.cpp
 +    precomp.h) #    utility/shelltests.cpp
 +
 +if(ARCH STREQUAL "i386")
 +    list(APPEND I386_SOURCE i386-stub-win32.c)
 +endif()
 +
 +add_executable(explorer_old
 +    ${SOURCE}
 +    ${I386_SOURCE}
 +    services/startup.c
 +    explorer.rc)
 +
 +target_link_libraries(explorer_old comsupp wine uuid)
 +set_module_type(explorer_old win32gui UNICODE)
 +
 +add_importlibs(explorer_old advapi32 gdi32 user32 ws2_32 msimg32 comctl32 ole32 oleaut32 shell32 shlwapi notifyhook msvcrt kernel32 ntdll)
 +add_pch(explorer_old precomp.h SOURCE)
 +add_dependencies(explorer_old psdk)
 +add_cd_file(TARGET explorer_old DESTINATION reactos FOR all)
 +add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/explorer-cfg-template.xml DESTINATION reactos FOR all)
 +
 +if(NOT MSVC)
 +    add_compile_flags("-Wno-error=narrowing")
++
++    # GCC bug #59472
++    if(LTCG)
++        add_target_link_flags(explorer "-Wno-error")
++    endif()
 +endif()
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 808dcfb,0000000..73272ff
mode 100644,000000..100644
--- /dev/null
@@@ -1,77 -1,0 +1,82 @@@
 +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")
++
++    # Binutils linker bug
++    if(LTCG)
++        add_target_link_flags(browseui "-Wl,--allow-multiple-definition")
++    endif()
 +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")
index 323deb6,0000000..21ce5e3
mode 100644,000000..100644
--- /dev/null
@@@ -1,159 -1,0 +1,200 @@@
 +#ifndef _BROWSEUI_PCH_
 +#define _BROWSEUI_PCH_
 +
 +#include <stdarg.h>
 +
 +#define WIN32_NO_STATUS
 +#define _INC_WINDOWS
 +#define COM_NO_WINDOWS_H
 +
 +#include <windef.h>
 +#include <winbase.h>
 +#include <wincon.h>
 +#include <shlobj.h>
 +#include <tlogstg.h>
 +#include <shlobj_undoc.h>
 +#include <shlguid_undoc.h>
 +#include <shdeprecated.h>
 +#include <tchar.h>
 +#include <atlbase.h>
 +#include <atlcom.h>
 +#include <atlwin.h>
 +#include <perhist.h>
 +#include <exdispid.h>
 +#include <shlwapi.h>
 +#include <shlwapi_undoc.h>
 +#include <wine/debug.h>
 +
 +#include "resource.h"
 +
 +#include "aclmulti.h"
 +#include "addressband.h"
 +#include "addresseditbox.h"
 +#include "bandproxy.h"
 +#include "bandsite.h"
 +#include "bandsitemenu.h"
 +#include "brandband.h"
 +#include "internettoolbar.h"
 +#include "commonbrowser.h"
 +#include "globalfoldersettings.h"
 +#include "regtreeoptions.h"
 +#include <stdio.h>
 +
 +static __inline ULONG
 +Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...)
 +{
 +    char szMsg[512];
 +    char *szMsgStart;
 +    const char *fname;
 +    va_list vl;
 +    ULONG uRet;
 +
 +    fname = strrchr(filename, '\\');
 +    if (fname == NULL)
 +    {
 +        fname = strrchr(filename, '/');
 +        if (fname != NULL)
 +            fname++;
 +    }
 +    else
 +        fname++;
 +
 +    if (fname == NULL)
 +        fname = filename;
 +
 +    szMsgStart = szMsg + sprintf(szMsg, "%s:%d: ", fname, line);
 +
 +    va_start(vl, lpFormat);
 +    uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl);
 +    va_end(vl);
 +
 +    OutputDebugStringA(szMsg);
 +
 +    return uRet;
 +}
 +
 +#define DbgPrint(fmt, ...) \
 +    Win32DbgPrint(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
 +
++static void DbgDumpMenuInternal(HMENU hmenu, char* padding, int padlevel)
++{
++    WCHAR label[128];
++
++    padding[padlevel] = '.';
++    padding[padlevel + 1] = '.';
++    padding[padlevel + 2] = 0;
++
++    int count = GetMenuItemCount(hmenu);
++    for (int i = 0; i < count; i++)
++    {
++        MENUITEMINFOW mii = { 0 };
++
++        mii.cbSize = sizeof(mii);
++        mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU | MIIM_STATE | MIIM_ID;
++        mii.dwTypeData = label;
++        mii.cch = _countof(label);
++
++        GetMenuItemInfo(hmenu, i, TRUE, &mii);
++
++        if (mii.fType & MFT_BITMAP)
++            DbgPrint("%s%2d - %08x: BITMAP %08p (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.hbmpItem, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
++        else if (mii.fType & MFT_SEPARATOR)
++            DbgPrint("%s%2d - %08x ---SEPARATOR---\n", padding, i, mii.wID);
++        else
++            DbgPrint("%s%2d - %08x: %S (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.dwTypeData, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
++
++        if (mii.hSubMenu)
++            DbgDumpMenuInternal(mii.hSubMenu, padding, padlevel + 2);
++
++    }
++
++    padding[padlevel] = 0;
++}
++
++static __inline void DbgDumpMenu(HMENU hmenu)
++{
++    char padding[128];
++    DbgDumpMenuInternal(hmenu, padding, 0);
++}
++
 +#if 1
 +#define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (DbgPrint("Unexpected failure %08x.\n", hr), TRUE))
 +#else
 +#define FAILED_UNEXPECTEDLY(hr) FAILED(hr)
 +#endif
 +
 +
 +template <class Base>
 +class CComDebugObject : public Base
 +{
 +public:
 +    CComDebugObject(void * = NULL)
 +    {
 +        _pAtlModule->Lock();
 +    }
 +
 +    virtual ~CComDebugObject()
 +    {
 +        this->FinalRelease();
 +        _pAtlModule->Unlock();
 +    }
 +
 +    STDMETHOD_(ULONG, AddRef)()
 +    {
 +        int rc = this->InternalAddRef();
 +        DbgPrint("RefCount is now %d(++)!\n", rc);
 +        return rc;
 +    }
 +
 +    STDMETHOD_(ULONG, Release)()
 +    {
 +        ULONG                                                         newRefCount;
 +
 +        newRefCount = this->InternalRelease();
 +        DbgPrint("RefCount is now %d(--)!\n", newRefCount);
 +        if (newRefCount == 0)
 +            delete this;
 +        return newRefCount;
 +    }
 +
 +    STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject)
 +    {
 +        return this->_InternalQueryInterface(iid, ppvObject);
 +    }
 +
 +    static HRESULT WINAPI CreateInstance(CComDebugObject<Base> **pp)
 +    {
 +        CComDebugObject<Base>                         *newInstance;
 +        HRESULT                                                               hResult;
 +
 +        ATLASSERT(pp != NULL);
 +        if (pp == NULL)
 +            return E_POINTER;
 +
 +        hResult = E_OUTOFMEMORY;
 +        newInstance = NULL;
 +        ATLTRY(newInstance = new CComDebugObject<Base>())
 +            if (newInstance != NULL)
 +            {
 +            newInstance->SetVoid(NULL);
 +            newInstance->InternalFinalConstructAddRef();
 +            hResult = newInstance->_AtlInitialConstruct();
 +            if (SUCCEEDED(hResult))
 +                hResult = newInstance->FinalConstruct();
 +            if (SUCCEEDED(hResult))
 +                hResult = newInstance->_AtlFinalConstruct();
 +            newInstance->InternalFinalConstructRelease();
 +            if (hResult != S_OK)
 +            {
 +                delete newInstance;
 +                newInstance = NULL;
 +            }
 +            }
 +        *pp = newInstance;
 +        return hResult;
 +    }
 +};
 +
 +WINE_DEFAULT_DEBUG_CHANNEL(browseui);
 +
 +#endif /* _BROWSEUI_PCH_ */
index 89a9959,0000000..5de7aaf
mode 100644,000000..100644
--- /dev/null
@@@ -1,3530 -1,0 +1,3490 @@@
- static void DbgDumpMenuInternal(HMENU hmenu, char* padding, int padlevel)
- {
-     WCHAR label[128];
-     padding[padlevel] = '.';
-     padding[padlevel + 1] = '.';
-     padding[padlevel + 2] = 0;
-     int count = GetMenuItemCount(hmenu);
-     for (int i = 0; i < count; i++)
-     {
-         MENUITEMINFOW mii = { 0 };
-         mii.cbSize = sizeof(mii);
-         mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU | MIIM_STATE | MIIM_ID;
-         mii.dwTypeData = label;
-         mii.cch = _countof(label);
-         GetMenuItemInfo(hmenu, i, TRUE, &mii);
-         if (mii.fType & MFT_BITMAP)
-             DbgPrint("%s%2d - %08x: BITMAP %08p (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.hbmpItem, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
-         else if (mii.fType & MFT_SEPARATOR)
-             DbgPrint("%s%2d - %08x ---SEPARATOR---\n", padding, i, mii.wID);
-         else
-             DbgPrint("%s%2d - %08x: %S (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.dwTypeData, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
-         if (mii.hSubMenu)
-             DbgDumpMenuInternal(mii.hSubMenu, padding, padlevel + 2);
-     }
-     padding[padlevel] = 0;
- }
- static void DbgDumpMenu(HMENU hmenu)
- {
-     char padding[128];
-     DbgDumpMenuInternal(hmenu, padding, 0);
- }
 +/*
 + * ReactOS Explorer
 + *
 + * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
 + *
 + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
 +#include "precomp.h"
 +
 +#include <shellapi.h>
 +#include <htiframe.h>
 +
 +extern "C"
 +BOOL WINAPI Shell_GetImageLists(
 +    _Out_  HIMAGELIST *phiml,
 +    _Out_  HIMAGELIST *phimlSmall
 +    );
 +
 +extern HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow);
 +
 +#include "newatlinterfaces.h"
 +
 +
 +/*
 +TODO:
 +  **Provide implementation of new and delete that use LocalAlloc
 +  **Persist history for shell view isn't working correctly, possibly because of the mismatch between traveling and updating the travel log. The
 +        view doesn't restore the selection correctly.
 +  **Build explorer.exe, browseui.dll, comctl32.dll, shdocvw.dll, shell32.dll, shlwapi.dll into a directory and run them for testing...
 +  **Add brand band bitmaps to shell32.dll
 +  **If Go button on address bar is clicked, each time a new duplicate entry is added to travel log
 +****The current entry is updated in travel log before doing the travel, which means when traveling back the update of the
 +        current state overwrites the wrong entry's contents. This needs to be changed.
 +****Fix close of browser window to release all objects
 +****Given only a GUID in ShowBrowserBar, what is the correct way to determine if the bar is vertical or horizontal?
 +  **When a new bar is added to base bar site, how is base bar told so it can resize?
 +  **Does the base bar site have a classid?
 +  **What should refresh command send to views to make them refresh?
 +  **When new bar is created, what status notifications need to be fired?
 +  **How does keyboard filtering dispatch?
 +  **For deferred persist history load, how does the view connect up and get the state?
 +    How does context menu send open, cut, rename commands to its site (the shell view)?
 +  **Fix browser to implement IProfferService and hold onto brand band correctly - this will allow animations.
 +
 +  **Route View->Toolbars commands to internet toolbar
 +  **Handle travel log items in View->Go
 +  **Fix ShowBrowserBar to pass correct size on when bar is shown
 +****Fix SetBorderSpaceDW to cascade resize to subsequent bars
 +****Make ShowToolbar check if bar is already created before creating it again
 +****Shell should fill in the list of explorer bars in the View submenus
 +  **Add folder menu in the file menu
 +  **Fix CShellBrowser::GetBorderDW to compute available size correctly
 +  **When a new bar is shown, re-fire the navigate event. This makes the explorer band select the correct folder
 +  **Implement support for refresh. Forward refresh to explorer bar (refresh on toolbar and in menu is dispatched different)
 +    Make folders toolbar item update state appropriately
 +    Read list of bands from registry on launch
 +    Read list of bars from registry on launch
 +    If the folders or search bars don't exist, disable the toolbar buttons
 +    If the favorites or history bars don't exist, disable the toolbar butons
 +    Fix Apply to all Folders in Folder Options
 +    Implement close command
 +    Add explorer band context menu to file menu
 +    Add code to allow restore of internet toolbar from registry
 +    Fix code that calls FireNavigateComplete to pass the correct new path
 +
 +    What are the other command ids for QueryStatus/FireCommandStateChange?
 +
 +    Add handler for cabinet settings change
 +    Add handler for system metrics change (renegotiate border space?)
 +    Add handler for theme change and forward to contained windows
 +
 +    When folders are shown, the status bar text should change
 +    Add code to save/restore shell view settings
 +    Implement tabbing between frames
 +    Fix handling of focus everywhere
 +    Most keyboard shortcuts don't work, such as F2 for rename, F5 for refresh (see list in "explorer keyboard shortcuts")
 +
 +    The status bar doesn't show help text for items owned by frame during menu tracking
 +    Stub out frame command handlers
 +    "Arrange icons by" group is not checked properly
 +
 +    When folders are hidden, icon is the same as the current shell object being displayed. When folders are shown,
 +        the icon is always an open folder with magnifying glass
 +    Fix bars to calculate height correctly
 +    Hookup policies for everything...
 +    Investigate toolbar message WM_USER+93
 +    Investigate toolbar message WM_USER+100 (Adds extra padding between parts of buttons with BTNS_DROPDOWN | BTNS_SHOWTEXT style
 +
 +    Vertical Explorer Bar             CATID_InfoBand
 +    Horizontal Explorer Bar           CATID_CommBand
 +    Desk Band                                 CATID_DeskBand
 +
 +    cache of bars
 +    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021493-0000-0000-C000-000000000046}\Enum
 +    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021494-0000-0000-C000-000000000046}\Enum
 +
 +    create key here with CLSID of bar to register tool band
 +    HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Toolbar
 +
 +*/
 +
 +#ifndef __GNUC__
 +#pragma comment(linker, \
 +    "\"/manifestdependency:type='Win32' "\
 +    "name='Microsoft.Windows.Common-Controls' "\
 +    "version='6.0.0.0' "\
 +    "processorArchitecture='*' "\
 +    "publicKeyToken='6595b64144ccf1df' "\
 +    "language='*'\"")
 +#endif // __GNUC__
 +
 +struct categoryCacheHeader
 +{
 +    long                dwSize;         // size of header only
 +    long                version;        // currently 1
 +    SYSTEMTIME          writeTime;      // time we were written to registry
 +    long                classCount;     // number of classes following
 +};
 +
 +static const unsigned int                   folderOptionsPageCountMax = 20;
 +static const long                           BTP_UPDATE_CUR_HISTORY = 1;
 +static const long                           BTP_UPDATE_NEXT_HISTORY = 2;
 +
 +BOOL                                        createNewStuff = false;
 +
 +
 +// this class is private to browseui.dll and is not registered externally?
 +//DEFINE_GUID(CLSID_ShellFldSetExt, 0x6D5313C0, 0x8C62, 0x11D1, 0xB2, 0xCD, 0x00, 0x60, 0x97, 0xDF, 0x8C, 0x11);
 +
 +
 +extern HRESULT CreateTravelLog(REFIID riid, void **ppv);
 +extern HRESULT CreateBaseBar(REFIID riid, void **ppv);
 +extern HRESULT CreateBaseBarSite(REFIID riid, void **ppv);
 +
 +// temporary
 +extern HRESULT CreateInternetToolbar(REFIID riid, void **ppv);
 +
 +
 +HMENU SHGetMenuFromID(HMENU topMenu, int theID)
 +{
 +    MENUITEMINFO                            menuItemInfo;
 +
 +    menuItemInfo.cbSize = sizeof(menuItemInfo);
 +    menuItemInfo.fMask = MIIM_SUBMENU;
 +    if (!GetMenuItemInfo(topMenu, theID, FALSE, &menuItemInfo))
 +        return NULL;
 +    return menuItemInfo.hSubMenu;
 +}
 +
 +void SHCheckMenuItem(HMENU theMenu, int theID, BOOL checked)
 +{
 +    MENUITEMINFO                            menuItemInfo;
 +
 +    menuItemInfo.cbSize = sizeof(menuItemInfo);
 +    menuItemInfo.fMask = MIIM_STATE;
 +    if (GetMenuItemInfo(theMenu, theID, FALSE, &menuItemInfo))
 +    {
 +        if (checked)
 +            menuItemInfo.fState |= MF_CHECKED;
 +        else
 +            menuItemInfo.fState &= ~MF_CHECKED;
 +        SetMenuItemInfo(theMenu, theID, FALSE, &menuItemInfo);
 +    }
 +}
 +
 +void DeleteMenuItems(HMENU theMenu, unsigned int firstIDToDelete, unsigned int lastIDToDelete)
 +{
 +    MENUITEMINFO                            menuItemInfo;
 +    int                                     menuItemCount;
 +    int                                     curIndex;
 +
 +    menuItemCount = GetMenuItemCount(theMenu);
 +    curIndex = 0;
 +    while (curIndex < menuItemCount)
 +    {
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_ID;
 +        if (GetMenuItemInfo(theMenu, curIndex, TRUE, &menuItemInfo) &&
 +            menuItemInfo.wID >= firstIDToDelete && menuItemInfo.wID <= lastIDToDelete)
 +        {
 +            DeleteMenu(theMenu, curIndex, MF_BYPOSITION);
 +            menuItemCount--;
 +        }
 +        else
 +            curIndex++;
 +    }
 +}
 +
 +HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder)
 +{
 +    CComPtr<IShellFolder>                   desktop;
 +
 +    HRESULT hr = ::SHGetDesktopFolder(&desktop);
 +    if (FAILED_UNEXPECTEDLY(hr))
 +        return E_FAIL;
 +    if (path == NULL || path->mkid.cb == 0)
 +    {
 +        *newFolder = desktop;
 +        desktop.p->AddRef ();
 +        return S_OK;
 +    }
 +    return desktop->BindToObject (path, NULL, IID_PPV_ARG(IShellFolder, newFolder));
 +}
 +
 +static const TCHAR szCabinetWndClass[] = TEXT("CabinetWClassX");
 +static const TCHAR szExploreWndClass[] = TEXT("ExploreWClassX");
 +
 +class CDockManager;
 +class CShellBrowser;
 +
 +class CToolbarProxy :
 +    public CWindowImpl<CToolbarProxy, CWindow, CControlWinTraits>
 +{
 +private:
 +    CComPtr<IExplorerToolbar>               fExplorerToolbar;
 +public:
 +    void Initialize(HWND parent, IUnknown *explorerToolbar);
 +
 +private:
 +
 +    // message handlers
 +    LRESULT OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +
 +    BEGIN_MSG_MAP(CToolbarProxy)
 +        MESSAGE_HANDLER(TB_ADDBITMAP, OnAddBitmap)
 +        MESSAGE_RANGE_HANDLER(WM_USER, 0x7fff, OnForwardMessage)
 +    END_MSG_MAP()
 +};
 +
 +void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar)
 +{
 +    HWND                                    myWindow;
 +    HRESULT                                 hResult;
 +
 +    myWindow = SHCreateWorkerWindowW(0, parent, 0, WS_CHILD, NULL, 0);
 +    if (myWindow != NULL)
 +    {
 +        SubclassWindow(myWindow);
 +        SetWindowPos(NULL, -32000, -32000, 0, 0, SWP_NOOWNERZORDER | SWP_NOZORDER);
 +        hResult = explorerToolbar->QueryInterface(
 +            IID_PPV_ARG(IExplorerToolbar, &fExplorerToolbar));
 +    }
 +}
 +
 +LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    long int                                result;
 +    HRESULT                                 hResult;
 +
 +    result = 0;
 +    if (fExplorerToolbar.p != NULL)
 +    {
 +        hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 1, (long)wParam,
 +            reinterpret_cast<TBADDBITMAP *>(lParam), &result, RGB(192, 192, 192));
 +        hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 2, (long)wParam,
 +            reinterpret_cast<TBADDBITMAP *>(lParam), &result, RGB(192, 192, 192));
 +    }
 +    return result;
 +}
 +
 +LRESULT CToolbarProxy::OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    LRESULT                                 result;
 +    HRESULT                                 hResult;
 +
 +    result = 0;
 +    if (fExplorerToolbar.p != NULL)
 +        hResult = fExplorerToolbar->SendToolbarMsg(&CGID_ShellBrowser, uMsg, wParam, lParam, &result);
 +    return result;
 +}
 +
 +/*
 +Switch to a new bar when it receives an Exec(CGID_IDeskBand, 1, 1, vaIn, NULL);
 +    where vaIn will be a VT_UNKNOWN with the new bar. It also sends a RB_SHOWBAND to the
 +    rebar
 +*/
 +
 +class CShellBrowser :
 +    public CWindowImpl<CShellBrowser, CWindow, CFrameWinTraits>,
 +    public CComObjectRootEx<CComMultiThreadModelNoCS>,
 +    public IShellBrowser,
 +    public IDropTarget,
 +    public IServiceProvider,
 +    public IProfferServiceImpl<CShellBrowser>,
 +    public IShellBrowserService,
 +    public IWebBrowser2,
 +    public ITravelLogClient,
 +    public IPersistHistory,
 +    public IDockingWindowSite,
 +    public IOleCommandTarget,
 +    public IBrowserService2,
 +    public IConnectionPointContainerImpl<CShellBrowser>,
 +    public MyIConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents2>,
 +    public MyIConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents>
 +{
 +private:
 +    class barInfo
 +    {
 +    public:
 +        RECT                                borderSpace;
 +        CComPtr<IUnknown>                   clientBar;
 +        HWND                                hwnd;
 +    };
 +    static const int                        BIInternetToolbar = 0;
 +    static const int                        BIVerticalBaseBar = 1;
 +    static const int                        BIHorizontalBaseBar = 2;
 +
 +    HWND                                    fCurrentShellViewWindow;    // our currently hosted shell view window
 +    CComPtr<IShellFolder>                   fCurrentShellFolder;        //
 +    CComPtr<IShellView>                     fCurrentShellView;          //
 +    LPITEMIDLIST                            fCurrentDirectoryPIDL;      //
 +    HWND                                    fStatusBar;
 +    bool                                    fStatusBarVisible;
 +    CToolbarProxy                           fToolbarProxy;
 +    barInfo                                 fClientBars[3];
 +    CComPtr<ITravelLog>                     fTravelLog;
 +    HMENU                                   fCurrentMenuBar;
 +    CABINETSTATE                            fCabinetState;
 +    // The next three fields support persisted history for shell views.
 +    // They do not need to be reference counted.
 +    IOleObject                              *fHistoryObject;
 +    IStream                                 *fHistoryStream;
 +    IBindCtx                                *fHistoryBindContext;
 +    HACCEL m_hAccel;
 +public:
 +#if 0
 +    ULONG InternalAddRef()
 +    {
 +        OutputDebugString(_T("AddRef\n"));
 +        return CComObjectRootEx<CComMultiThreadModelNoCS>::InternalAddRef();
 +    }
 +    ULONG InternalRelease()
 +    {
 +        OutputDebugString(_T("Release\n"));
 +        return CComObjectRootEx<CComMultiThreadModelNoCS>::InternalRelease();
 +    }
 +#endif
 +
 +    CShellBrowser();
 +    ~CShellBrowser();
 +    HRESULT Initialize(LPITEMIDLIST pidl, long b, long c, long d);
 +public:
 +    HRESULT BrowseToPIDL(LPCITEMIDLIST pidl, long flags);
 +    HRESULT BrowseToPath(IShellFolder *newShellFolder, LPCITEMIDLIST absolutePIDL,
 +        FOLDERSETTINGS *folderSettings, long flags);
 +    HRESULT GetMenuBand(REFIID riid, void **shellMenu);
 +    HRESULT GetBaseBar(bool vertical, IUnknown **theBaseBar);
 +    HRESULT ShowBand(const CLSID &classID, bool vertical);
 +    HRESULT NavigateToParent();
 +    HRESULT DoFolderOptions();
 +    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    void RepositionBars();
 +    virtual WNDPROC GetWindowProc()
 +    {
 +        return WindowProc;
 +    }
 +    HRESULT FireEvent(DISPID dispIdMember, int argCount, VARIANT *arguments);
 +    HRESULT FireNavigateComplete(const wchar_t *newDirectory);
 +    HRESULT FireCommandStateChange(bool newState, int commandID);
 +    HRESULT FireCommandStateChangeAll();
 +    HRESULT UpdateForwardBackState();
 +    void UpdateGotoMenu(HMENU theMenu);
 +    void UpdateViewMenu(HMENU theMenu);
 +
 +/*    // *** IDockingWindowFrame methods ***
 +    virtual HRESULT STDMETHODCALLTYPE AddToolbar(IUnknown *punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags);
 +    virtual HRESULT STDMETHODCALLTYPE RemoveToolbar(IUnknown *punkSrc, DWORD dwRemoveFlags);
 +    virtual HRESULT STDMETHODCALLTYPE FindToolbar(LPCWSTR pwszItem, REFIID riid, void **ppv);
 +    */
 +
 +    // *** IDockingWindowSite methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetBorderDW(IUnknown* punkObj, LPRECT prcBorder);
 +    virtual HRESULT STDMETHODCALLTYPE RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
 +    virtual HRESULT STDMETHODCALLTYPE SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
 +
 +    // *** IOleCommandTarget methods ***
 +    virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
 +        OLECMD prgCmds[  ], OLECMDTEXT *pCmdText);
 +    virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
 +        DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
 +
 +    // *** IOleWindow methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
 +    virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
 +
 +    // *** IShellBrowser methods ***
 +    virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
 +    virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject);
 +    virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared);
 +    virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCOLESTR pszStatusText);
 +    virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable);
 +    virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID);
 +    virtual HRESULT STDMETHODCALLTYPE BrowseObject(LPCITEMIDLIST pidl, UINT wFlags);
 +    virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode, IStream **ppStrm);
 +    virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND *lphwnd);
 +    virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret);
 +    virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(IShellView **ppshv);
 +    virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(IShellView *ppshv);
 +    virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags);
 +
 +    // *** IDropTarget methods ***
 +    virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
 +    virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
 +    virtual HRESULT STDMETHODCALLTYPE DragLeave();
 +    virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
 +
 +    // *** IServiceProvider methods ***
 +    virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
 +
 +    // *** IShellBowserService methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetPropertyBag(long flags, REFIID riid, void **ppvObject);
 +
 +    // *** IDispatch methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
 +    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
 +    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
 +        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
 +    virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
 +        DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
 +
 +    // *** IBrowserService methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetParentSite(IOleInPlaceSite **ppipsite);
 +    virtual HRESULT STDMETHODCALLTYPE SetTitle(IShellView *psv, LPCWSTR pszName);
 +    virtual HRESULT STDMETHODCALLTYPE GetTitle(IShellView *psv, LPWSTR pszName, DWORD cchName);
 +    virtual HRESULT STDMETHODCALLTYPE GetOleObject(IOleObject **ppobjv);
 +    virtual HRESULT STDMETHODCALLTYPE GetTravelLog(ITravelLog **pptl);
 +    virtual HRESULT STDMETHODCALLTYPE ShowControlWindow(UINT id, BOOL fShow);
 +    virtual HRESULT STDMETHODCALLTYPE IsControlWindowShown(UINT id, BOOL *pfShown);
 +    virtual HRESULT STDMETHODCALLTYPE IEGetDisplayName(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags);
 +    virtual HRESULT STDMETHODCALLTYPE IEParseDisplayName(UINT uiCP, LPCWSTR pwszPath, LPITEMIDLIST *ppidlOut);
 +    virtual HRESULT STDMETHODCALLTYPE DisplayParseError(HRESULT hres, LPCWSTR pwszPath);
 +    virtual HRESULT STDMETHODCALLTYPE NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF);
 +    virtual HRESULT STDMETHODCALLTYPE SetNavigateState(BNSTATE bnstate);
 +    virtual HRESULT STDMETHODCALLTYPE GetNavigateState(BNSTATE *pbnstate);
 +    virtual HRESULT STDMETHODCALLTYPE NotifyRedirect(IShellView *psv, LPCITEMIDLIST pidl, BOOL *pfDidBrowse);
 +    virtual HRESULT STDMETHODCALLTYPE UpdateWindowList();
 +    virtual HRESULT STDMETHODCALLTYPE UpdateBackForwardState();
 +    virtual HRESULT STDMETHODCALLTYPE SetFlags(DWORD dwFlags, DWORD dwFlagMask);
 +    virtual HRESULT STDMETHODCALLTYPE GetFlags(DWORD *pdwFlags);
 +    virtual HRESULT STDMETHODCALLTYPE CanNavigateNow( void);
 +    virtual HRESULT STDMETHODCALLTYPE GetPidl(LPITEMIDLIST *ppidl);
 +    virtual HRESULT STDMETHODCALLTYPE SetReferrer(LPCITEMIDLIST pidl);
 +    virtual DWORD STDMETHODCALLTYPE GetBrowserIndex();
 +    virtual HRESULT STDMETHODCALLTYPE GetBrowserByIndex(DWORD dwID, IUnknown **ppunk);
 +    virtual HRESULT STDMETHODCALLTYPE GetHistoryObject(IOleObject **ppole, IStream **pstm, IBindCtx **ppbc);
 +    virtual HRESULT STDMETHODCALLTYPE SetHistoryObject(IOleObject *pole, BOOL fIsLocalAnchor);
 +    virtual HRESULT STDMETHODCALLTYPE CacheOLEServer(IOleObject *pole);
 +    virtual HRESULT STDMETHODCALLTYPE GetSetCodePage(VARIANT *pvarIn, VARIANT *pvarOut);
 +    virtual HRESULT STDMETHODCALLTYPE OnHttpEquiv(IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut);
 +    virtual HRESULT STDMETHODCALLTYPE GetPalette(HPALETTE *hpal);
 +    virtual HRESULT STDMETHODCALLTYPE RegisterWindow(BOOL fForceRegister, int swc);
 +
 +    // *** IBrowserService2 methods ***
 +    virtual LRESULT STDMETHODCALLTYPE WndProcBS(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE SetAsDefFolderSettings();
 +    virtual HRESULT STDMETHODCALLTYPE GetViewRect(RECT *prc);
 +    virtual HRESULT STDMETHODCALLTYPE OnSize(WPARAM wParam);
 +    virtual HRESULT STDMETHODCALLTYPE OnCreate(struct tagCREATESTRUCTW *pcs);
 +    virtual LRESULT STDMETHODCALLTYPE OnCommand(WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE OnDestroy();
 +    virtual LRESULT STDMETHODCALLTYPE OnNotify(struct tagNMHDR *pnm);
 +    virtual HRESULT STDMETHODCALLTYPE OnSetFocus();
 +    virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivateBS(BOOL fActive);
 +    virtual HRESULT STDMETHODCALLTYPE ReleaseShellView();
 +    virtual HRESULT STDMETHODCALLTYPE ActivatePendingView();
 +    virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvNew, IShellView *psvOld, LPRECT prcView, HWND *phwnd);
 +    virtual HRESULT STDMETHODCALLTYPE CreateBrowserPropSheetExt(REFIID riid, void **ppv);
 +    virtual HRESULT STDMETHODCALLTYPE GetViewWindow(HWND *phwndView);
 +    virtual HRESULT STDMETHODCALLTYPE GetBaseBrowserData(LPCBASEBROWSERDATA *pbbd);
 +    virtual LPBASEBROWSERDATA STDMETHODCALLTYPE PutBaseBrowserData( void);
 +    virtual HRESULT STDMETHODCALLTYPE InitializeTravelLog(ITravelLog *ptl, DWORD dw);
 +    virtual HRESULT STDMETHODCALLTYPE SetTopBrowser();
 +    virtual HRESULT STDMETHODCALLTYPE Offline(int iCmd);
 +    virtual HRESULT STDMETHODCALLTYPE AllowViewResize(BOOL f);
 +    virtual HRESULT STDMETHODCALLTYPE SetActivateState(UINT u);
 +    virtual HRESULT STDMETHODCALLTYPE UpdateSecureLockIcon(int eSecureLock);
 +    virtual HRESULT STDMETHODCALLTYPE InitializeDownloadManager();
 +    virtual HRESULT STDMETHODCALLTYPE InitializeTransitionSite();
 +    virtual HRESULT STDMETHODCALLTYPE _Initialize(HWND hwnd, IUnknown *pauto);
 +    virtual HRESULT STDMETHODCALLTYPE _CancelPendingNavigationAsync( void);
 +    virtual HRESULT STDMETHODCALLTYPE _CancelPendingView();
 +    virtual HRESULT STDMETHODCALLTYPE _MaySaveChanges();
 +    virtual HRESULT STDMETHODCALLTYPE _PauseOrResumeView(BOOL fPaused);
 +    virtual HRESULT STDMETHODCALLTYPE _DisableModeless();
 +    virtual HRESULT STDMETHODCALLTYPE _NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF, DWORD dwFlags);
 +    virtual HRESULT STDMETHODCALLTYPE _TryShell2Rename(IShellView *psv, LPCITEMIDLIST pidlNew);
 +    virtual HRESULT STDMETHODCALLTYPE _SwitchActivationNow();
 +    virtual HRESULT STDMETHODCALLTYPE _ExecChildren(IUnknown *punkBar, BOOL fBroadcast, const GUID *pguidCmdGroup,
 +        DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
 +    virtual HRESULT STDMETHODCALLTYPE _SendChildren(
 +        HWND hwndBar, BOOL fBroadcast, UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE GetFolderSetData(struct tagFolderSetData *pfsd);
 +    virtual HRESULT STDMETHODCALLTYPE _OnFocusChange(UINT itb);
 +    virtual HRESULT STDMETHODCALLTYPE v_ShowHideChildWindows(BOOL fChildOnly);
 +    virtual UINT STDMETHODCALLTYPE _get_itbLastFocus();
 +    virtual HRESULT STDMETHODCALLTYPE _put_itbLastFocus(UINT itbLastFocus);
 +    virtual HRESULT STDMETHODCALLTYPE _UIActivateView(UINT uState);
 +    virtual HRESULT STDMETHODCALLTYPE _GetViewBorderRect(RECT *prc);
 +    virtual HRESULT STDMETHODCALLTYPE _UpdateViewRectSize();
 +    virtual HRESULT STDMETHODCALLTYPE _ResizeNextBorder(UINT itb);
 +    virtual HRESULT STDMETHODCALLTYPE _ResizeView();
 +    virtual HRESULT STDMETHODCALLTYPE _GetEffectiveClientArea(LPRECT lprectBorder, HMONITOR hmon);
 +    virtual IStream *STDMETHODCALLTYPE v_GetViewStream(LPCITEMIDLIST pidl, DWORD grfMode, LPCWSTR pwszName);
 +    virtual LRESULT STDMETHODCALLTYPE ForwardViewMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
 +    virtual HRESULT STDMETHODCALLTYPE SetAcceleratorMenu(HACCEL hacc);
 +    virtual int STDMETHODCALLTYPE _GetToolbarCount();
 +    virtual LPTOOLBARITEM STDMETHODCALLTYPE _GetToolbarItem(int itb);
 +    virtual HRESULT STDMETHODCALLTYPE _SaveToolbars(IStream *pstm);
 +    virtual HRESULT STDMETHODCALLTYPE _LoadToolbars(IStream *pstm);
 +    virtual HRESULT STDMETHODCALLTYPE _CloseAndReleaseToolbars(BOOL fClose);
 +    virtual HRESULT STDMETHODCALLTYPE v_MayGetNextToolbarFocus(LPMSG lpMsg, UINT itbNext,
 +        int citb, LPTOOLBARITEM *pptbi, HWND *phwnd);
 +    virtual HRESULT STDMETHODCALLTYPE _ResizeNextBorderHelper(UINT itb, BOOL bUseHmonitor);
 +    virtual UINT STDMETHODCALLTYPE _FindTBar(IUnknown *punkSrc);
 +    virtual HRESULT STDMETHODCALLTYPE _SetFocus(LPTOOLBARITEM ptbi, HWND hwnd, LPMSG lpMsg);
 +    virtual HRESULT STDMETHODCALLTYPE v_MayTranslateAccelerator(MSG *pmsg);
 +    virtual HRESULT STDMETHODCALLTYPE _GetBorderDWHelper(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor);
 +    virtual HRESULT STDMETHODCALLTYPE v_CheckZoneCrossing(LPCITEMIDLIST pidl);
 +
 +    // *** IWebBrowser methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GoBack();
 +    virtual HRESULT STDMETHODCALLTYPE GoForward();
 +    virtual HRESULT STDMETHODCALLTYPE GoHome();
 +    virtual HRESULT STDMETHODCALLTYPE GoSearch();
 +    virtual HRESULT STDMETHODCALLTYPE Navigate(BSTR URL, VARIANT *Flags, VARIANT *TargetFrameName,
 +        VARIANT *PostData, VARIANT *Headers);
 +    virtual HRESULT STDMETHODCALLTYPE Refresh();
 +    virtual HRESULT STDMETHODCALLTYPE Refresh2(VARIANT *Level);
 +    virtual HRESULT STDMETHODCALLTYPE Stop();
 +    virtual HRESULT STDMETHODCALLTYPE get_Application(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_Parent(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_Container(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_Document(IDispatch **ppDisp);
 +    virtual HRESULT STDMETHODCALLTYPE get_TopLevelContainer(VARIANT_BOOL *pBool);
 +    virtual HRESULT STDMETHODCALLTYPE get_Type(BSTR *Type);
 +    virtual HRESULT STDMETHODCALLTYPE get_Left(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Left(long Left);
 +    virtual HRESULT STDMETHODCALLTYPE get_Top(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Top(long Top);
 +    virtual HRESULT STDMETHODCALLTYPE get_Width(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Width(long Width);
 +    virtual HRESULT STDMETHODCALLTYPE get_Height(long *pl);
 +    virtual HRESULT STDMETHODCALLTYPE put_Height(long Height);
 +    virtual HRESULT STDMETHODCALLTYPE get_LocationName(BSTR *LocationName);
 +    virtual HRESULT STDMETHODCALLTYPE get_LocationURL(BSTR *LocationURL);
 +    virtual HRESULT STDMETHODCALLTYPE get_Busy(VARIANT_BOOL *pBool);
 +
 +    // *** IWebBrowserApp methods ***
 +    virtual HRESULT STDMETHODCALLTYPE Quit();
 +    virtual HRESULT STDMETHODCALLTYPE ClientToWindow(int *pcx, int *pcy);
 +    virtual HRESULT STDMETHODCALLTYPE PutProperty(BSTR Property, VARIANT vtValue);
 +    virtual HRESULT STDMETHODCALLTYPE GetProperty(BSTR Property, VARIANT *pvtValue);
 +    virtual HRESULT STDMETHODCALLTYPE get_Name(BSTR *Name);
 +    virtual HRESULT STDMETHODCALLTYPE get_HWND(SHANDLE_PTR *pHWND);
 +    virtual HRESULT STDMETHODCALLTYPE get_FullName(BSTR *FullName);
 +    virtual HRESULT STDMETHODCALLTYPE get_Path(BSTR *Path);
 +    virtual HRESULT STDMETHODCALLTYPE get_Visible(VARIANT_BOOL *pBool);
 +    virtual HRESULT STDMETHODCALLTYPE put_Visible(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_StatusBar(VARIANT_BOOL *pBool);
 +    virtual HRESULT STDMETHODCALLTYPE put_StatusBar(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_StatusText(BSTR *StatusText);
 +    virtual HRESULT STDMETHODCALLTYPE put_StatusText(BSTR StatusText);
 +    virtual HRESULT STDMETHODCALLTYPE get_ToolBar(int *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_ToolBar(int Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_MenuBar(VARIANT_BOOL *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_MenuBar(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_FullScreen(VARIANT_BOOL *pbFullScreen);
 +    virtual HRESULT STDMETHODCALLTYPE put_FullScreen(VARIANT_BOOL bFullScreen);
 +
 +    // *** IWebBrowser2 methods ***
 +    virtual HRESULT STDMETHODCALLTYPE Navigate2(VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName,
 +        VARIANT *PostData, VARIANT *Headers);
 +    virtual HRESULT STDMETHODCALLTYPE QueryStatusWB(OLECMDID cmdID, OLECMDF *pcmdf);
 +    virtual HRESULT STDMETHODCALLTYPE ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt,
 +        VARIANT *pvaIn, VARIANT *pvaOut);
 +    virtual HRESULT STDMETHODCALLTYPE ShowBrowserBar(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize);
 +    virtual HRESULT STDMETHODCALLTYPE get_ReadyState(READYSTATE *plReadyState);
 +    virtual HRESULT STDMETHODCALLTYPE get_Offline(VARIANT_BOOL *pbOffline);
 +    virtual HRESULT STDMETHODCALLTYPE put_Offline(VARIANT_BOOL bOffline);
 +    virtual HRESULT STDMETHODCALLTYPE get_Silent(VARIANT_BOOL *pbSilent);
 +    virtual HRESULT STDMETHODCALLTYPE put_Silent(VARIANT_BOOL bSilent);
 +    virtual HRESULT STDMETHODCALLTYPE get_RegisterAsBrowser(VARIANT_BOOL *pbRegister);
 +    virtual HRESULT STDMETHODCALLTYPE put_RegisterAsBrowser(VARIANT_BOOL bRegister);
 +    virtual HRESULT STDMETHODCALLTYPE get_RegisterAsDropTarget(VARIANT_BOOL *pbRegister);
 +    virtual HRESULT STDMETHODCALLTYPE put_RegisterAsDropTarget(VARIANT_BOOL bRegister);
 +    virtual HRESULT STDMETHODCALLTYPE get_TheaterMode(VARIANT_BOOL *pbRegister);
 +    virtual HRESULT STDMETHODCALLTYPE put_TheaterMode(VARIANT_BOOL bRegister);
 +    virtual HRESULT STDMETHODCALLTYPE get_AddressBar(VARIANT_BOOL *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_AddressBar(VARIANT_BOOL Value);
 +    virtual HRESULT STDMETHODCALLTYPE get_Resizable(VARIANT_BOOL *Value);
 +    virtual HRESULT STDMETHODCALLTYPE put_Resizable(VARIANT_BOOL Value);
 +
 +    // *** ITravelLogClient methods ***
 +    virtual HRESULT STDMETHODCALLTYPE FindWindowByIndex(DWORD dwID, IUnknown **ppunk);
 +    virtual HRESULT STDMETHODCALLTYPE GetWindowData(IStream *pStream, LPWINDOWDATA pWinData);
 +    virtual HRESULT STDMETHODCALLTYPE LoadHistoryPosition(LPWSTR pszUrlLocation, DWORD dwPosition);
 +
 +    // *** IPersist methods ***
 +    virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
 +
 +    // *** IPersistHistory methods ***
 +    virtual HRESULT STDMETHODCALLTYPE LoadHistory(IStream *pStream, IBindCtx *pbc);
 +    virtual HRESULT STDMETHODCALLTYPE SaveHistory(IStream *pStream);
 +    virtual HRESULT STDMETHODCALLTYPE SetPositionCookie(DWORD dwPositioncookie);
 +    virtual HRESULT STDMETHODCALLTYPE GetPositionCookie(DWORD *pdwPositioncookie);
 +
 +    // message handlers
 +    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +    LRESULT OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnDisconnectNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnAboutReactOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnIsThisLegal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT OnGoTravel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
 +    LRESULT RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 +
 +    static ATL::CWndClassInfo& GetWndClassInfo()
 +    {
 +        static ATL::CWndClassInfo wc =
 +        {
 +            { sizeof(WNDCLASSEX), CS_DBLCLKS, StartWindowProc,
 +              0, 0, NULL, LoadIcon(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDI_CABINET)),
 +              LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, szCabinetWndClass, NULL },
 +            NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
 +        };
 +        return wc;
 +    }
 +
 +    BEGIN_MSG_MAP(CShellBrowser)
 +        MESSAGE_HANDLER(WM_CREATE, OnCreate)
 +        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
 +        MESSAGE_HANDLER(WM_SIZE, OnSize)
 +        MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
 +        MESSAGE_HANDLER(WM_MEASUREITEM, RelayMsgToShellView)
 +        MESSAGE_HANDLER(WM_DRAWITEM, RelayMsgToShellView)
 +        MESSAGE_HANDLER(WM_MENUSELECT, RelayMsgToShellView)
 +        COMMAND_ID_HANDLER(IDM_FILE_CLOSE, OnClose)
 +        COMMAND_ID_HANDLER(IDM_TOOLS_FOLDEROPTIONS, OnFolderOptions)
 +        COMMAND_ID_HANDLER(IDM_TOOLS_MAPNETWORKDRIVE, OnMapNetworkDrive)
 +        COMMAND_ID_HANDLER(IDM_TOOLS_DISCONNECTNETWORKDRIVE, OnDisconnectNetworkDrive)
 +        COMMAND_ID_HANDLER(IDM_HELP_ABOUT, OnAboutReactOS)
 +        COMMAND_ID_HANDLER(IDM_GOTO_BACK, OnGoBack)
 +        COMMAND_ID_HANDLER(IDM_GOTO_FORWARD, OnGoForward)
 +        COMMAND_ID_HANDLER(IDM_GOTO_UPONELEVEL, OnGoUpLevel)
 +        COMMAND_ID_HANDLER(IDM_GOTO_HOMEPAGE, OnGoHome)
 +        COMMAND_ID_HANDLER(IDM_HELP_ISTHISCOPYLEGAL, OnIsThisLegal)
 +        COMMAND_ID_HANDLER(IDM_VIEW_STATUSBAR, OnToggleStatusBarVisible)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_LOCKTOOLBARS, OnToggleToolbarLock)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_STANDARDBUTTONS, OnToggleToolbarBandVisible)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_ADDRESSBAR, OnToggleAddressBandVisible)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_LINKSBAR, OnToggleLinksBandVisible)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_TEXTLABELS, OnToggleTextLabels)
 +        COMMAND_ID_HANDLER(IDM_TOOLBARS_CUSTOMIZE, OnToolbarCustomize)
 +        COMMAND_ID_HANDLER(IDM_BACKSPACE, OnBackspace)
 +        COMMAND_RANGE_HANDLER(IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, OnGoTravel)
 +        MESSAGE_HANDLER(WM_COMMAND, RelayCommands)
 +    END_MSG_MAP()
 +
 +    BEGIN_CONNECTION_POINT_MAP(CShellBrowser)
 +        CONNECTION_POINT_ENTRY(DIID_DWebBrowserEvents2)
 +        CONNECTION_POINT_ENTRY(DIID_DWebBrowserEvents)
 +    END_CONNECTION_POINT_MAP()
 +
 +    BEGIN_COM_MAP(CShellBrowser)
 +        COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
 +        COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
 +        COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDockingWindowSite)
 +        COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
 +        COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
 +        COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
 +        COM_INTERFACE_ENTRY_IID(IID_IProfferService, IProfferService)
 +        COM_INTERFACE_ENTRY_IID(IID_IShellBrowserService, IShellBrowserService)
 +        COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch)
 +        COM_INTERFACE_ENTRY_IID(IID_IConnectionPointContainer, IConnectionPointContainer)
 +        COM_INTERFACE_ENTRY_IID(IID_IWebBrowser, IWebBrowser)
 +        COM_INTERFACE_ENTRY_IID(IID_IWebBrowserApp, IWebBrowserApp)
 +        COM_INTERFACE_ENTRY_IID(IID_IWebBrowser2, IWebBrowser2)
 +        COM_INTERFACE_ENTRY_IID(IID_ITravelLogClient, ITravelLogClient)
 +        COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
 +        COM_INTERFACE_ENTRY_IID(IID_IPersistHistory, IPersistHistory)
 +        COM_INTERFACE_ENTRY_IID(IID_IBrowserService, IBrowserService)
 +        COM_INTERFACE_ENTRY_IID(IID_IBrowserService2, IBrowserService2)
 +    END_COM_MAP()
 +};
 +
 +extern HRESULT CreateProgressDialog(REFIID riid, void **ppv);
 +
 +CShellBrowser::CShellBrowser()
 +{
 +    fCurrentShellViewWindow = NULL;
 +    fCurrentDirectoryPIDL = NULL;
 +    fStatusBar = NULL;
 +    fStatusBarVisible = true;
 +    memset(fClientBars, 0, sizeof(fClientBars));
 +    fCurrentMenuBar = NULL;
 +    fHistoryObject = NULL;
 +    fHistoryStream = NULL;
 +    fHistoryBindContext = NULL;
 +}
 +
 +CShellBrowser::~CShellBrowser()
 +{
 +}
 +
 +HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
 +{
 +    CComPtr<IPersistStreamInit>             persistStreamInit;
 +    HRESULT                                 hResult;
 +    CComPtr<IUnknown> clientBar;
 +
 +    _AtlInitialConstruct();
 +
 +    fCabinetState.cLength = sizeof(fCabinetState);
 +    if (ReadCabinetState(&fCabinetState, sizeof(fCabinetState)) == FALSE)
 +    {
 +    }
 +
 +    // create window
 +    Create(HWND_DESKTOP);
 +    if (m_hWnd == NULL)
 +        return E_FAIL;
 +
 +#if 0
 +    hResult = CoCreateInstance(CLSID_InternetToolbar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &fClientBars[BIInternetToolbar].clientBar));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +#else
 +    hResult = CreateInternetToolbar(IID_PPV_ARG(IUnknown, &clientBar));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +#endif
 +
 +    fClientBars[BIInternetToolbar].clientBar = clientBar;
 +
 +    // create interfaces
 +    hResult = clientBar->QueryInterface(IID_PPV_ARG(IPersistStreamInit, &persistStreamInit));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    hResult = IUnknown_SetSite(clientBar, static_cast<IShellBrowser *>(this));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    hResult = IUnknown_Exec(clientBar, CGID_PrivCITCommands, 1, 1 /* or 0 */, NULL, NULL);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    // TODO: create settingsStream from registry entry
 +    //if (settingsStream.p)
 +    //{
 +    //    hResult = persistStreamInit->Load(settingsStream);
 +    //    if (FAILED_UNEXPECTEDLY(hResult))
 +    //        return hResult;
 +    //}
 +    //else
 +    {
 +        hResult = persistStreamInit->InitNew();
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +    }
 +
 +    hResult = IUnknown_ShowDW(clientBar, TRUE);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    fToolbarProxy.Initialize(m_hWnd, clientBar);
 +
 +
 +    // create status bar
 +    fStatusBar = CreateWindow(STATUSCLASSNAMEW, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
 +                    SBT_NOBORDERS | SBT_TOOLTIPS, 0, 0, 500, 20, m_hWnd, (HMENU)0xa001,
 +                    _AtlBaseModule.GetModuleInstance(), 0);
 +    fStatusBarVisible = true;
 +
 +
 +    // browse 
 +    hResult = BrowseToPIDL(pidl, BTP_UPDATE_NEXT_HISTORY);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    ShowWindow(SW_SHOWNORMAL);
 +
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags)
 +{
 +    CComPtr<IShellFolder>                   newFolder;
 +    FOLDERSETTINGS                          newFolderSettings;
 +    HRESULT                                 hResult;
 +
 +    // called by shell view to browse to new folder
 +    // also called by explorer band to navigate to new folder
 +    hResult = SHBindToFolder(pidl, &newFolder);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    newFolderSettings.ViewMode = FVM_ICON;
 +    newFolderSettings.fFlags = 0;
 +    hResult = BrowseToPath(newFolder, pidl, &newFolderSettings, flags);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
 +{
 +    return (pidl == NULL || pidl->mkid.cb == 0);
 +}
 +
 +BOOL WINAPI _ILIsPidlSimple(LPCITEMIDLIST pidl)
 +{
 +    LPCITEMIDLIST                           pidlnext;
 +    WORD                                    length;
 +    BOOL                                    ret;
 +
 +    ret = TRUE;
 +    if (! _ILIsDesktop(pidl))
 +    {
 +        length = pidl->mkid.cb;
 +        pidlnext =
 +            reinterpret_cast<LPCITEMIDLIST>(
 +                reinterpret_cast<const BYTE *>(pidl) + length);
 +        if (pidlnext->mkid.cb != 0)
 +            ret = FALSE;
 +    }
 +    return ret;
 +}
 +
 +HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *unused, LPCITEMIDLIST pidl,
 +    const IID *riid, LPVOID *ppv, LPITEMIDLIST *ppidlLast)
 +{
 +    CComPtr<IShellFolder>                   psf;
 +    LPITEMIDLIST                            pidlChild;
 +    LPITEMIDLIST                            pidlParent;
 +    HRESULT                                 hResult;
 +
 +    hResult = E_FAIL;
 +    if (ppv == NULL)
 +        return E_POINTER;
 +    *ppv = NULL;
 +    if (ppidlLast != NULL)
 +        *ppidlLast = NULL;
 +    if (_ILIsPidlSimple(pidl))
 +    {
 +        if (ppidlLast != NULL)
 +            *ppidlLast = ILClone(pidl);
 +        hResult = SHGetDesktopFolder((IShellFolder **)ppv);
 +    }
 +    else
 +    {
 +        pidlChild = ILClone(ILFindLastID(pidl));
 +        pidlParent = ILClone(pidl);
 +        ILRemoveLastID(pidlParent);
 +        hResult = SHGetDesktopFolder(&psf);
 +        if (SUCCEEDED(hResult))
 +            hResult = psf->BindToObject(pidlParent, NULL, *riid, ppv);
 +        if (SUCCEEDED(hResult) && ppidlLast != NULL)
 +            *ppidlLast = pidlChild;
 +        else
 +            ILFree(pidlChild);
 +        ILFree(pidlParent);
 +    }
 +    return hResult;
 +}
 +
 +HRESULT IEGetNameAndFlagsEx(LPITEMIDLIST pidl, SHGDNF uFlags, long param10,
 +    LPWSTR pszBuf, UINT cchBuf, SFGAOF *rgfInOut)
 +{
 +    CComPtr<IShellFolder>                   parentFolder;
 +    LPITEMIDLIST                            childPIDL;
 +    STRRET                                  L108;
 +    HRESULT                                 hResult;
 +
 +    hResult = SHBindToFolderIDListParent(NULL, pidl, &IID_PPV_ARG(IShellFolder, &parentFolder), &childPIDL);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    hResult = parentFolder->GetDisplayNameOf(childPIDL, uFlags, &L108);
 +    if (FAILED(hResult))
 +        return hResult;
 +
 +    StrRetToBufW(&L108, childPIDL, pszBuf, cchBuf);
 +    if (rgfInOut)
 +    {
 +        hResult = parentFolder->GetAttributesOf(1, const_cast<LPCITEMIDLIST *>(&childPIDL), rgfInOut);
 +        if (FAILED(hResult))
 +            return hResult;
 +    }
 +
 +    ILFree(childPIDL);
 +    return S_OK;
 +}
 +
 +long IEGetNameAndFlags(LPITEMIDLIST pidl, SHGDNF uFlags, LPWSTR pszBuf, UINT cchBuf, SFGAOF *rgfInOut)
 +{
 +    return IEGetNameAndFlagsEx(pidl, uFlags, 0, pszBuf, cchBuf, rgfInOut);
 +}
 +
 +HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
 +    LPCITEMIDLIST absolutePIDL, FOLDERSETTINGS *folderSettings, long flags)
 +{
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    CComPtr<IShellFolder>                   saveCurrentShellFolder;
 +    CComPtr<IShellView>                     saveCurrentShellView;
 +    CComPtr<IShellView>                     newShellView;
 +    CComPtr<ITravelLog>                     travelLog;
 +    HWND                                    newShellViewWindow;
 +    BOOL                                    windowUpdateIsLocked;
 +    RECT                                    shellViewWindowBounds;
 +    HWND                                    previousView;
 +    HCURSOR                                 saveCursor;
 +    wchar_t                                 newTitle[MAX_PATH];
 +    SHGDNF                                  nameFlags;
 +    HRESULT                                 hResult;
 +
 +    if (newShellFolder == NULL)
 +        return E_INVALIDARG;
 +
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    // update history
 +    if (flags & BTP_UPDATE_CUR_HISTORY)
 +    {
 +        if (travelLog->CountEntries(static_cast<IDropTarget *>(this)) > 0)
 +            hResult = travelLog->UpdateEntry(static_cast<IDropTarget *>(this), FALSE);
 +        // what to do with error? Do we want to halt browse because state save failed?
 +    }
 +
 +    if (fCurrentShellView)
 +    {
 +        fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
 +    }
 +
 +    // create view object
 +    hResult = newShellFolder->CreateViewObject(m_hWnd, IID_PPV_ARG(IShellView, &newShellView));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    previousView = fCurrentShellViewWindow;
 +
 +    // enter updating section
 +    saveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
 +    windowUpdateIsLocked = LockWindowUpdate(TRUE);
 +    if (fCurrentShellView != NULL)
 +        ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 0, 0);
 +
 +    // set site
 +    hResult = newShellView->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +    if (SUCCEEDED(hResult) && objectWithSite.p != NULL)
 +        hResult = objectWithSite->SetSite(static_cast<IDropTarget *>(this));
 +
 +    // update folder and view
 +    saveCurrentShellFolder = fCurrentShellFolder;
 +    saveCurrentShellView = fCurrentShellView;
 +    fCurrentShellFolder = newShellFolder;
 +    fCurrentShellView = newShellView;
 +
 +    // get boundary
 +    if (previousView != NULL)
 +        ::GetWindowRect(previousView, &shellViewWindowBounds);
 +    else
 +        ZeroMemory(&shellViewWindowBounds, sizeof(shellViewWindowBounds));
 +    ::MapWindowPoints(0, m_hWnd, reinterpret_cast<POINT *>(&shellViewWindowBounds), 2);
 +
 +    // create view window
 +    hResult = newShellView->CreateViewWindow(saveCurrentShellView, folderSettings,
 +        this, &shellViewWindowBounds, &newShellViewWindow);
 +    if (FAILED_UNEXPECTEDLY(hResult) || newShellViewWindow == NULL)
 +    {
 +        fCurrentShellView = saveCurrentShellView;
 +        fCurrentShellFolder = saveCurrentShellFolder;
 +        ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 1, 0);
 +        if (windowUpdateIsLocked)
 +            LockWindowUpdate(FALSE);
 +        SetCursor(saveCursor);
 +        return hResult;
 +    }
 +
 +    if (objectWithSite.p != NULL)
 +        hResult = objectWithSite->SetSite(NULL);
 +
 +    // update current pidl
 +    ILFree(fCurrentDirectoryPIDL);
 +    fCurrentDirectoryPIDL = ILClone(absolutePIDL);
 +
 +    // update view window
 +    if (saveCurrentShellView != NULL)
 +        saveCurrentShellView->DestroyViewWindow();
 +    fCurrentShellViewWindow = newShellViewWindow;
 +
 +    // no use
 +    saveCurrentShellView.Release();
 +    saveCurrentShellFolder.Release();
 +
 +    hResult = newShellView->UIActivate(SVUIA_ACTIVATE_FOCUS);
 +
 +    // leave updating section
 +    if (windowUpdateIsLocked)
 +        LockWindowUpdate(FALSE);
 +    SetCursor(saveCursor);
 +
 +    // update history
 +    if (flags & BTP_UPDATE_NEXT_HISTORY)
 +    {
 +        hResult = travelLog->AddEntry(static_cast<IDropTarget *>(this), FALSE);
 +        hResult = travelLog->UpdateEntry(static_cast<IDropTarget *>(this), FALSE);
 +    }
 +
 +    // completed
 +    nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
 +    hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
 +        sizeof(newTitle) / sizeof(wchar_t), NULL);
 +    if (SUCCEEDED(hResult))
 +    {
 +        FireNavigateComplete(newTitle);
 +    }
 +    else
 +    {
 +        FireNavigateComplete(L"ERROR");
 +    }
 +
 +    if (fCabinetState.fFullPathTitle)
 +        nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
 +    else
 +        nameFlags = SHGDN_FORADDRESSBAR;
 +    hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
 +        sizeof(newTitle) / sizeof(wchar_t), NULL);
 +    if (SUCCEEDED(hResult))
 +    {
 +        SetWindowText(newTitle);
 +
 +        LPCITEMIDLIST pidlChild;
 +        INT index, indexOpen;
 +        HIMAGELIST himlSmall, himlLarge;
 +
 +        CComPtr<IShellFolder> sf;
 +        SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
 +
 +        index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
 +
 +        Shell_GetImageLists(&himlLarge, &himlSmall);
 +
 +        HICON icSmall = ImageList_GetIcon(himlSmall, indexOpen, 0);
 +        HICON icLarge = ImageList_GetIcon(himlLarge, indexOpen, 0);
 +
 +        SendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icSmall));
 +        SendMessage(WM_SETICON, ICON_BIG,   reinterpret_cast<LPARAM>(icLarge));
 +    }
 +
 +    // TODO: Update the window icon
 +
 +    FireCommandStateChangeAll();
 +    hResult = UpdateForwardBackState();
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::GetMenuBand(REFIID riid, void **shellMenu)
 +{
 +    CComPtr<IServiceProvider>               serviceProvider;
 +    CComPtr<IBandSite>                      bandSite;
 +    CComPtr<IDeskBand>                      deskBand;
 +    HRESULT                                 hResult;
 +
 +    if (!fClientBars[BIInternetToolbar].clientBar)
 +        return E_FAIL;
 +
 +    hResult = IUnknown_QueryService(fClientBars[BIInternetToolbar].clientBar, SID_IBandSite, IID_PPV_ARG(IBandSite, &bandSite));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    hResult = bandSite->QueryBand(1, &deskBand, NULL, NULL, 0);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +
 +    return deskBand->QueryInterface(riid, shellMenu);
 +}
 +
 +HRESULT CShellBrowser::GetBaseBar(bool vertical, IUnknown **theBaseBar)
 +{
 +    CComPtr<IUnknown>                       newBaseBar;
 +    CComPtr<IDeskBar>                       deskBar;
 +    CComPtr<IUnknown>                       newBaseBarSite;
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    CComPtr<IDeskBarClient>                 deskBarClient;
 +    IUnknown                                **cache;
 +    HRESULT                                 hResult;
 +
 +    if (vertical)
 +        cache = &fClientBars[BIVerticalBaseBar].clientBar.p;
 +    else
 +        cache = &fClientBars[BIHorizontalBaseBar].clientBar.p;
 +    if (*cache == NULL)
 +    {
 +        hResult = CreateBaseBar(IID_PPV_ARG(IUnknown, &newBaseBar));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +        hResult = CreateBaseBarSite(IID_PPV_ARG(IUnknown, &newBaseBarSite));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +
 +        // tell the new base bar about the shell browser
 +        hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +        hResult = objectWithSite->SetSite(static_cast<IDropTarget *>(this));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +
 +        // tell the new base bar about the new base bar site
 +        hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +        hResult = deskBar->SetClient(newBaseBarSite);
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +
 +        // tell the new base bar site about the new base bar
 +        hResult = newBaseBarSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &deskBarClient));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +        hResult = deskBarClient->SetDeskBarSite(newBaseBar);
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +
 +        *cache = newBaseBar.Detach();
 +    }
 +    return (*cache)->QueryInterface(IID_PPV_ARG(IUnknown, theBaseBar));
 +}
 +
 +HRESULT CShellBrowser::ShowBand(const CLSID &classID, bool vertical)
 +{
 +    CComPtr<IDockingWindow>                 dockingWindow;
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    CComPtr<IUnknown>                       baseBarSite;
 +    CComPtr<IUnknown>                       newBand;
 +    CComPtr<IUnknown>                       theBaseBar;
 +    CComPtr<IDeskBar>                       deskBar;
 +    VARIANT                                 vaIn;
 +    HRESULT                                 hResult;
 +
 +    __debugbreak();
 +
 +    hResult = GetBaseBar(vertical, (IUnknown **)&theBaseBar);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = CoCreateInstance(classID, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &newBand));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = theBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = deskBar->GetClient(&baseBarSite);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = theBaseBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = baseBarSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    V_VT(&vaIn) = VT_UNKNOWN;
 +    V_UNKNOWN(&vaIn) = newBand.p;
 +    hResult = oleCommandTarget->Exec(&CGID_IDeskBand, 1, 1, &vaIn, NULL);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = dockingWindow->ShowDW(TRUE);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::NavigateToParent()
 +{
 +    LPITEMIDLIST                            newDirectory;
 +    HRESULT                                 hResult;
 +
 +    newDirectory = ILClone(fCurrentDirectoryPIDL);
 +    if (newDirectory == NULL)
 +        return E_OUTOFMEMORY;
 +    ILRemoveLastID(newDirectory);
 +    hResult = BrowseToPIDL(newDirectory, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
 +    ILFree(newDirectory);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +BOOL CALLBACK AddFolderOptionsPage(HPROPSHEETPAGE thePage, LPARAM lParam)
 +{
 +    PROPSHEETHEADER                         *sheetInfo;
 +
 +    sheetInfo = (PROPSHEETHEADER *)lParam;
 +    if (sheetInfo->nPages >= folderOptionsPageCountMax)
 +        return FALSE;
 +    sheetInfo->phpage[sheetInfo->nPages] = thePage;
 +    sheetInfo->nPages++;
 +    return TRUE;
 +}
 +
 +HRESULT CShellBrowser::DoFolderOptions()
 +{
 +    CComPtr<IShellPropSheetExt>             folderOptionsSheet;
 +    CComPtr<IObjectWithSite>                objectWithSite;
 +    PROPSHEETHEADER                         m_PropSheet;
 +    HPROPSHEETPAGE                          m_psp[folderOptionsPageCountMax];
 +//    CComPtr<IGlobalFolderSettings>          globalSettings;
 +//    SHELLSTATE2                             shellState;
 +    HRESULT                                 hResult;
 +
 +    memset(m_psp, 0, sizeof(m_psp));
 +    memset(&m_PropSheet, 0, sizeof(m_PropSheet));
 +
 +    // create sheet object
 +    hResult = CoCreateInstance(CLSID_ShellFldSetExt, NULL, CLSCTX_INPROC_SERVER,
 +        IID_PPV_ARG(IShellPropSheetExt, &folderOptionsSheet));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return E_FAIL;
 +
 +    // must set site in order for Apply to all Folders on Advanced page to be enabled
 +    hResult = folderOptionsSheet->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
 +    if (SUCCEEDED(hResult) && objectWithSite.p != NULL)
 +        hResult = objectWithSite->SetSite(static_cast<IDispatch *>(this));
 +    m_PropSheet.phpage = m_psp;
 +
 +#if 0
 +    hResult = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IGlobalFolderSettings, &globalSettings));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return E_FAIL;
 +    hResult = globalSettings->Get(&shellState, sizeof(shellState));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return E_FAIL;
 +#endif
 +
 +    // add pages
 +    hResult = folderOptionsSheet->AddPages(AddFolderOptionsPage, reinterpret_cast<LPARAM>(&m_PropSheet));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return E_FAIL;
 +
 +    if (fCurrentShellView != NULL)
 +    {
 +        hResult = fCurrentShellView->AddPropertySheetPages(
 +            0, AddFolderOptionsPage, reinterpret_cast<LPARAM>(&m_PropSheet));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return E_FAIL;
 +    }
 +
 +    // show sheet
 +    m_PropSheet.dwSize = sizeof(PROPSHEETHEADER);
 +    m_PropSheet.dwFlags = 0;
 +    m_PropSheet.hwndParent = m_hWnd;
 +    m_PropSheet.hInstance = _AtlBaseModule.GetResourceInstance();
 +    m_PropSheet.pszCaption = _T("Folder Options");
 +    m_PropSheet.nStartPage = 0;
 +    PropertySheet(&m_PropSheet);
 +    return S_OK;
 +}
 +
 +LRESULT CALLBACK CShellBrowser::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    CShellBrowser                           *pThis = reinterpret_cast<CShellBrowser *>(hWnd);
 +    _ATL_MSG                                msg(pThis->m_hWnd, uMsg, wParam, lParam);
 +    LRESULT                                 lResult;
 +    const _ATL_MSG                          *previousMessage;
 +    BOOL                                    handled;
 +    WNDPROC                                 saveWindowProc;
 +    HRESULT                                 hResult;
 +
 +    hWnd = pThis->m_hWnd;
 +    previousMessage = pThis->m_pCurrentMsg;
 +    pThis->m_pCurrentMsg = &msg;
 +
 +    CComPtr<IMenuBand> menuBand;
 +    hResult = pThis->GetMenuBand(IID_PPV_ARG(IMenuBand, &menuBand));
 +    if (SUCCEEDED(hResult) && menuBand.p != NULL)
 +    {
 +        hResult = menuBand->TranslateMenuMessage(&msg, &lResult);
 +        if (hResult == S_OK)
 +            return lResult;
 +        uMsg = msg.message;
 +        wParam = msg.wParam;
 +        lParam = msg.lParam;
 +    }
 +    menuBand.Release();
 +
 +    handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
 +    ATLASSERT(pThis->m_pCurrentMsg == &msg);
 +    if (handled == FALSE)
 +    {
 +        if (uMsg == WM_NCDESTROY)
 +        {
 +            saveWindowProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWL_WNDPROC));
 +            lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
 +            if (saveWindowProc == reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWL_WNDPROC)))
 +                SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
 +            pThis->m_dwState |= WINSTATE_DESTROYED;
 +        }
 +        else
 +            lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
 +    }
 +    pThis->m_pCurrentMsg = previousMessage;
 +    if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
 +    {
 +        pThis->m_dwState &= ~WINSTATE_DESTROYED;
 +        pThis->m_hWnd = NULL;
 +        pThis->OnFinalMessage(hWnd);
 +    }
 +    return lResult;
 +}
 +
 +void CShellBrowser::RepositionBars()
 +{
 +    RECT                                    clientRect;
 +    RECT                                    statusRect;
 +    int                                     x;
 +
 +    GetClientRect(&clientRect);
 +
 +    if (fStatusBarVisible && fStatusBar)
 +    {
 +        ::GetWindowRect(fStatusBar, &statusRect);
 +        ::SetWindowPos(fStatusBar, NULL, clientRect.left, clientRect.bottom - (statusRect.bottom - statusRect.top),
 +                            clientRect.right - clientRect.left,
 +                            statusRect.bottom - statusRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
 +        clientRect.bottom -= statusRect.bottom - statusRect.top;
 +    }
 +
 +    for (x = 0; x < 3; x++)
 +    {
 +        HWND hwnd = fClientBars[x].hwnd;
 +        RECT borderSpace = fClientBars[x].borderSpace;
 +        if (hwnd == NULL && fClientBars[x].clientBar != NULL)
 +        {
 +            IUnknown_GetWindow(fClientBars[x].clientBar, &hwnd);
 +            fClientBars[x].hwnd = hwnd;
 +        }
 +        if (hwnd != NULL)
 +        {
 +            RECT toolbarRect = clientRect;
 +            if (borderSpace.top != 0)
 +            {
 +                toolbarRect.bottom = toolbarRect.top + borderSpace.top;
 +            }
 +            else if (borderSpace.bottom != 0)
 +            {
 +                toolbarRect.top = toolbarRect.bottom - borderSpace.bottom;
 +            }
 +            else if (borderSpace.left != 0)
 +            {
 +                toolbarRect.right = toolbarRect.left + borderSpace.left;
 +            }
 +            else if (borderSpace.right != 0)
 +            {
 +                toolbarRect.left = toolbarRect.right - borderSpace.right;
 +            }
 +
 +            ::SetWindowPos(hwnd, NULL,
 +                toolbarRect.left,
 +                toolbarRect.top,
 +                toolbarRect.right - toolbarRect.left,
 +                toolbarRect.bottom - toolbarRect.top,
 +                SWP_NOOWNERZORDER | SWP_NOZORDER);
 +
 +            if (borderSpace.top != 0)
 +            {
 +                clientRect.top = toolbarRect.bottom;
 +            }
 +            else if (borderSpace.bottom != 0)
 +            {
 +                clientRect.bottom = toolbarRect.top;
 +            }
 +            else if (borderSpace.left != 0)
 +            {
 +                clientRect.left = toolbarRect.right;
 +            }
 +            else if (borderSpace.right != 0)
 +            {
 +                clientRect.right = toolbarRect.left;
 +            }
 +        }
 +    }
 +    ::SetWindowPos(fCurrentShellViewWindow, NULL, clientRect.left, clientRect.top,
 +                        clientRect.right - clientRect.left,
 +                        clientRect.bottom - clientRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
 +}
 +
 +HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arguments)
 +{
 +    DISPPARAMS                          params;
 +    CComDynamicUnkArray                 &vec = IConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents2>::m_vec;
 +    CComDynamicUnkArray                 &vec2 = IConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents>::m_vec;
 +    HRESULT                             hResult;
 +
 +    params.rgvarg = arguments;
 +    params.rgdispidNamedArgs = NULL;
 +    params.cArgs = argCount;
 +    params.cNamedArgs = 0;
 +    IUnknown** pp = vec.begin();
 +    while (pp < vec.end())
 +    {
 +        if (*pp != NULL)
 +        {
 +            CComPtr<IDispatch>          theDispatch;
 +
 +            hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
 +            hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
 +        }
 +        pp++;
 +    }
 +    pp = vec2.begin();
 +    while (pp < vec2.end())
 +    {
 +        if (*pp != NULL)
 +        {
 +            CComPtr<IDispatch>          theDispatch;
 +
 +            hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
 +            hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
 +        }
 +        pp++;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT CShellBrowser::FireNavigateComplete(const wchar_t *newDirectory)
 +{
 +    // these two variants intentionally to do use CComVariant because it would double free/release
 +    // or does not need to dispose at all
 +    VARIANT                             varArg[2];
 +    VARIANT                             varArgs;
 +    CComBSTR                            tempString(newDirectory);
 +
 +    V_VT(&varArgs) = VT_BSTR;
 +    V_BSTR(&varArgs) = tempString.m_str;
 +
 +    V_VT(&varArg[0]) = VT_VARIANT | VT_BYREF;
 +    V_VARIANTREF(&varArg[0]) = &varArgs;
 +    V_VT(&varArg[1]) = VT_DISPATCH;
 +    V_DISPATCH(&varArg[1]) = (IDispatch *)this;
 +
 +    return FireEvent(DISPID_NAVIGATECOMPLETE2, 2, varArg);
 +}
 +
 +HRESULT CShellBrowser::FireCommandStateChange(bool newState, int commandID)
 +{
 +    VARIANT                             varArg[2];
 +
 +    V_VT(&varArg[0]) = VT_BOOL;
 +    V_BOOL(&varArg[0]) = newState ? VARIANT_TRUE : VARIANT_FALSE;
 +    V_VT(&varArg[1]) = VT_I4;
 +    V_I4(&varArg[1]) = commandID;
 +
 +    return FireEvent(DISPID_COMMANDSTATECHANGE, 2, varArg);
 +}
 +
 +HRESULT CShellBrowser::FireCommandStateChangeAll()
 +{
 +    return FireCommandStateChange(false, -1);
 +}
 +
 +HRESULT CShellBrowser::UpdateForwardBackState()
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    CComPtr<ITravelEntry>                   unusedEntry;
 +    bool                                    canGoBack;
 +    bool                                    canGoForward;
 +    HRESULT                                 hResult;
 +
 +    canGoBack = false;
 +    canGoForward = false;
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this), TLOG_BACK, &unusedEntry);
 +    if (SUCCEEDED(hResult))
 +    {
 +        canGoBack = true;
 +        unusedEntry.Release();
 +    }
 +    hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this), TLOG_FORE, &unusedEntry);
 +    if (SUCCEEDED(hResult))
 +    {
 +        canGoForward = true;
 +        unusedEntry.Release();
 +    }
 +    hResult = FireCommandStateChange(canGoBack, 2);
 +    hResult = FireCommandStateChange(canGoForward, 1);
 +    return S_OK;
 +}
 +
 +void CShellBrowser::UpdateGotoMenu(HMENU theMenu)
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    int                                     position;
 +    MENUITEMINFO                            menuItemInfo;
 +    HRESULT                                 hResult;
 +
 +    DeleteMenuItems(theMenu, IDM_GOTO_TRAVEL_FIRST, IDM_GOTO_TRAVEL_LAST);
 +
 +    position = GetMenuItemCount(theMenu);
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return;
 +    hResult = travelLog->InsertMenuEntries(static_cast<IDropTarget *>(this), theMenu, position,
 +        IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, TLMENUF_BACKANDFORTH | TLMENUF_CHECKCURRENT);
 +    if (SUCCEEDED(hResult))
 +    {
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_TYPE | MIIM_ID;
 +        menuItemInfo.fType = MF_SEPARATOR;
 +        menuItemInfo.wID = IDM_GOTO_TRAVEL_SEP;
 +        InsertMenuItem(theMenu, position, TRUE, &menuItemInfo);
 +    }
 +}
 +
 +void CShellBrowser::UpdateViewMenu(HMENU theMenu)
 +{
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    CComPtr<ITravelLog>                     travelLog;
 +    HMENU                                   gotoMenu;
 +    OLECMD                                  commandList[5];
 +    HMENU                                   toolbarMenuBar;
 +    HMENU                                   toolbarMenu;
 +    MENUITEMINFO                            menuItemInfo;
 +    HRESULT                                 hResult;
 +
 +    gotoMenu = SHGetMenuFromID(theMenu, FCIDM_MENU_EXPLORE);
 +    if (gotoMenu != NULL)
 +        UpdateGotoMenu(gotoMenu);
 +
 +    commandList[0].cmdID = ITID_TOOLBARBANDSHOWN;
 +    commandList[1].cmdID = ITID_ADDRESSBANDSHOWN;
 +    commandList[2].cmdID = ITID_LINKSBANDSHOWN;
 +    commandList[3].cmdID = ITID_TOOLBARLOCKED;
 +    commandList[4].cmdID = ITID_CUSTOMIZEENABLED;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (SUCCEEDED(hResult))
 +        hResult = oleCommandTarget->QueryStatus(&CGID_PrivCITCommands, 5, commandList, NULL);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        DeleteMenu(theMenu, IDM_VIEW_TOOLBARS, MF_BYCOMMAND);
 +    else
 +    {
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_SUBMENU;
 +        GetMenuItemInfo(theMenu, IDM_VIEW_TOOLBARS, FALSE, &menuItemInfo);
 +        DestroyMenu(menuItemInfo.hSubMenu);
 +
 +        toolbarMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
 +        toolbarMenu = GetSubMenu(toolbarMenuBar, 0);
 +        RemoveMenu(toolbarMenuBar, 0, MF_BYPOSITION);
 +        DestroyMenu(toolbarMenuBar);
 +
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_STANDARDBUTTONS, commandList[0].cmdf);
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_ADDRESSBAR, commandList[1].cmdf & OLECMDF_ENABLED);
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_LINKSBAR, commandList[2].cmdf & OLECMDF_ENABLED);
 +        SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_LOCKTOOLBARS, commandList[3].cmdf & OLECMDF_ENABLED);
 +        if ((commandList[4].cmdf & OLECMDF_ENABLED) == 0)
 +            DeleteMenu(toolbarMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
 +        DeleteMenu(toolbarMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
 +        DeleteMenu(toolbarMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
 +
 +        menuItemInfo.cbSize = sizeof(menuItemInfo);
 +        menuItemInfo.fMask = MIIM_SUBMENU;
 +        menuItemInfo.hSubMenu = toolbarMenu;
 +        SetMenuItemInfo(theMenu, IDM_VIEW_TOOLBARS, FALSE, &menuItemInfo);
 +    }
 +    SHCheckMenuItem(theMenu, IDM_VIEW_STATUSBAR, fStatusBarVisible ? TRUE : FALSE);
 +}
 +
 +bool IUnknownIsEqual(IUnknown *int1, IUnknown *int2)
 +{
 +    CComPtr<IUnknown>                       int1Retry;
 +    CComPtr<IUnknown>                       int2Retry;
 +    HRESULT                                 hResult;
 +
 +    if (int1 == int2)
 +        return true;
 +    if (int1 == NULL || int2 == NULL)
 +        return false;
 +    hResult = int1->QueryInterface(IID_PPV_ARG(IUnknown, &int1Retry));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return false;
 +    hResult = int2->QueryInterface(IID_PPV_ARG(IUnknown, &int2Retry));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return false;
 +    if (int1Retry == int2Retry)
 +        return true;
 +    return false;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetBorderDW(IUnknown *punkObj, LPRECT prcBorder)
 +{
 +    static const INT excludeItems[] = { 1, 1, 1, 0xa001, 0, 0 };
 +
 +    RECT availableBounds;
 +
 +    GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
 +    for (INT x = 0; x < 3; x++)
 +    {
 +        if (fClientBars[x].clientBar.p != NULL && !IUnknownIsEqual(fClientBars[x].clientBar, punkObj))
 +        {
 +            availableBounds.top += fClientBars[x].borderSpace.top;
 +            availableBounds.left += fClientBars[x].borderSpace.left;
 +            availableBounds.bottom -= fClientBars[x].borderSpace.bottom;
 +            availableBounds.right -= fClientBars[x].borderSpace.right;
 +        }
 +    }
 +    *prcBorder = availableBounds;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
 +{
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
 +{
 +    for (INT x = 0; x < 3; x++)
 +    {
 +        if (IUnknownIsEqual(fClientBars[x].clientBar, punkObj))
 +        {
 +            fClientBars[x].borderSpace = *pbw;
 +            // if this bar changed size, it cascades and forces all subsequent bars to resize
 +            RepositionBars();
 +            return S_OK;
 +        }
 +    }
 +    return E_INVALIDARG;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatus(const GUID *pguidCmdGroup,
 +    ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    if (prgCmds == NULL)
 +        return E_INVALIDARG;
 +    if (pguidCmdGroup == NULL)
 +    {
 +        if (fCurrentShellView.p != NULL)
 +        {
 +            hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +            if (SUCCEEDED(hResult) && commandTarget.p != NULL)
 +                return commandTarget->QueryStatus(NULL, 1, prgCmds, pCmdText);
 +        }
 +        while (cCmds != 0)
 +        {
 +            prgCmds->cmdf = 0;
 +            prgCmds++;
 +            cCmds--;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
 +    {
 +        while (cCmds != 0)
 +        {
 +            switch (prgCmds->cmdID)
 +            {
 +                case 0x1c:  // search
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case 0x1d:  // history
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case 0x1e:  // favorites
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
 +                    break;
 +                case 0x23:  // folders
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED | OLECMDF_LATCHED;
 +                    break;
 +                default:
 +                    prgCmds->cmdf = 0;
 +                    break;
 +            }
 +            prgCmds++;
 +            cCmds--;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_ShellBrowser))
 +    {
 +        while (cCmds != 0)
 +        {
 +            switch (prgCmds->cmdID)
 +            {
 +                case 0xa022:    // up level
 +                    prgCmds->cmdf = OLECMDF_SUPPORTED;
 +                    if (fCurrentDirectoryPIDL->mkid.cb != 0)
 +                        prgCmds->cmdf |= OLECMDF_ENABLED;
 +                    break;
 +            }
 +            prgCmds++;
 +            cCmds--;
 +        }
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
 +    DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
 +{
 +    HRESULT                                 hResult;
 +
 +    if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x23:
 +                hResult = ShowBand(CLSID_ExplorerBand, true);
 +                return S_OK;
 +            case 0x27:
 +                if (nCmdexecopt == 1)
 +                {
 +                    // pvaIn is a VT_UNKNOWN with a band that is being hidden
 +                }
 +                else
 +                {
 +                    // update zones part of the status bar
 +                }
 +                return S_OK;
 +            case 0x35: // don't do this, and the internet toolbar doesn't create a menu band
 +                V_VT(pvaOut) = VT_INT_PTR;
 +                V_INTREF(pvaOut) = reinterpret_cast<INT *>(
 +                    LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU)));
 +                return S_OK;
 +            case 0x38:
 +                // indicate if this cabinet was opened as a browser
 +                return S_FALSE;
 +            default:
 +                return E_NOTIMPL;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_InternetButtons))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x23:
 +                // placeholder
 +                return S_OK;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_Theater))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 6:
 +                // what is theater mode and why do we receive this?
 +                return E_NOTIMPL;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_MenuBand))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 14:
 +                // initialize favorites menu
 +                return S_OK;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x12:
 +                // refresh on toolbar clicked
 +                return S_OK;
 +            case 0x4d:
 +                // tell the view if it should hide the task pane or not
 +                return (fClientBars[BIVerticalBaseBar].clientBar.p == NULL) ? S_FALSE : S_OK;
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_ShellBrowser))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 40994:
 +                return NavigateToParent();
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_IExplorerToolbar))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 0x7063:
 +                return DoFolderOptions();
 +        }
 +    }
 +    else if (IsEqualIID(*pguidCmdGroup, CGID_DefView))
 +    {
 +        switch (nCmdID)
 +        {
 +            case 1:
 +                // Reset All Folders option in Folder Options
 +                break;
 +        }
 +    }
 +    else
 +    {
 +        return E_NOTIMPL;
 +    }
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetWindow(HWND *lphwnd)
 +{
 +    if (lphwnd == NULL)
 +        return E_POINTER;
 +    *lphwnd = m_hWnd;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ContextSensitiveHelp(BOOL fEnterMode)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
 +{
 +    HMENU mainMenu = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU));
 +
 +    //DbgPrint("Menu from shell32:\n");
 +    //DbgDumpMenu(hmenuShared);
 +
 +    //DbgPrint("Menu from browseui:\n");
 +    //DbgDumpMenu(mainMenu);
 +
 +    Shell_MergeMenus(hmenuShared, mainMenu, 0, 0, FCIDM_BROWSERLAST, MM_SUBMENUSHAVEIDS);
 +
 +    //DbgPrint("Merged menu:\n");
 +    //DbgDumpMenu(hmenuShared);
 +
 +    int GCCU(itemCount3) = GetMenuItemCount(hmenuShared);
 +    Unused(itemCount3);
 +
 +    DestroyMenu(mainMenu);
 +
 +    lpMenuWidths->width[0] = 2;
 +    lpMenuWidths->width[2] = 3;
 +    lpMenuWidths->width[4] = 1;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
 +{
 +    CComPtr<IShellMenu>                     shellMenu;
 +    HRESULT                                 hResult;
 +
 +    //DbgPrint("SetMenuSB:\n");
 +    //DbgDumpMenu(hmenuShared);
 +
 +    if (hmenuShared && IsMenu(hmenuShared) == FALSE)
 +        return E_FAIL;
 +    hResult = GetMenuBand(IID_PPV_ARG(IShellMenu, &shellMenu));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = shellMenu->SetMenu(hmenuShared, NULL, SMSET_DONTOWN);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    fCurrentMenuBar = hmenuShared;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::RemoveMenusSB(HMENU hmenuShared)
 +{
 +    if (hmenuShared == fCurrentMenuBar)
 +    {
 +        //DestroyMenu(fCurrentMenuBar);
 +        SetMenuSB(NULL, NULL, NULL);
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetStatusTextSB(LPCOLESTR pszStatusText)
 +{
 +    //
 +    if (pszStatusText)
 +    {
 +        ::SetWindowText(fStatusBar, pszStatusText);
 +    }
 +    else
 +    {
 +
 +    }
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::EnableModelessSB(BOOL fEnable)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::TranslateAcceleratorSB(MSG *pmsg, WORD wID)
 +{
 +    if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, pmsg))
 +        return S_FALSE;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
 +{
 +    return BrowseToPIDL(pidl, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetControlWindow(UINT id, HWND *lphwnd)
 +{
 +    if (lphwnd == NULL)
 +        return E_POINTER;
 +    *lphwnd = NULL;
 +    switch(id)
 +    {
 +        case FCW_TOOLBAR:
 +            *lphwnd = fToolbarProxy.m_hWnd;
 +            return S_OK;
 +        case FCW_STATUS:
 +            *lphwnd = fStatusBar;
 +            return S_OK;
 +        case FCW_TREE:
 +            // find the directory browser and return it
 +            // this should be used only to determine if a tree is present
 +            return S_OK;
 +        case FCW_PROGRESS:
 +            // is this a progress dialog?
 +            return S_OK;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SendControlMsg(
 +    UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
 +{
 +    LPARAM                                  result;
 +
 +    if (pret != NULL)
 +        *pret = 0;
 +    switch(id)
 +    {
 +        case FCW_TOOLBAR:
 +            result = fToolbarProxy.SendMessage(uMsg, wParam, lParam);
 +            if (pret != NULL)
 +                *pret = result;
 +            break;
 +        case FCW_STATUS:
 +            result = SendMessage(fStatusBar, uMsg, wParam, lParam);
 +            if (pret != NULL)
 +                *pret = result;
 +            break;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryActiveShellView(IShellView **ppshv)
 +{
 +    if (ppshv == NULL)
 +        return E_POINTER;
 +    *ppshv = fCurrentShellView;
 +    if (fCurrentShellView.p != NULL)
 +        fCurrentShellView.p->AddRef();
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnViewWindowActive(IShellView *ppshv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DragEnter(
 +    IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DragLeave()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Drop(
 +    IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 +{
 +    // view does a query for SID_STopLevelBrowser, IID_IShellBrowserService
 +    // the returned interface has a method GetPropertyBag on it
 +    if (IsEqualIID(guidService, SID_STopLevelBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_SShellBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_ITargetFrame2))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_IWebBrowserApp))        // without this, the internet toolbar won't reflect notifications
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_SProxyBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(guidService, SID_IExplorerToolbar))
 +        return fClientBars[BIInternetToolbar].clientBar->QueryInterface(riid, ppvObject);
 +    if (IsEqualIID(riid, IID_IShellBrowser))
 +        return this->QueryInterface(riid, ppvObject);
 +    return E_NOINTERFACE;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPropertyBag(long flags, REFIID riid, void **ppvObject)
 +{
 +    if (ppvObject == NULL)
 +        return E_POINTER;
 +    *ppvObject = NULL;
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTypeInfoCount(UINT *pctinfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames,
 +    UINT cNames, LCID lcid, DISPID *rgDispId)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
 +    WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetParentSite(IOleInPlaceSite **ppipsite)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetTitle(IShellView *psv, LPCWSTR pszName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTitle(IShellView *psv, LPWSTR pszName, DWORD cchName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetOleObject(IOleObject **ppobjv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetTravelLog(ITravelLog **pptl)
 +{
 +    HRESULT                                 hResult;
 +
 +    // called by toolbar when displaying tooltips
 +    if (pptl == NULL)
 +        return E_FAIL;
 +
 +    *pptl = NULL;
 +    if (fTravelLog.p == NULL)
 +    {
 +        hResult = CreateTravelLog(IID_PPV_ARG(ITravelLog, &fTravelLog));
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +    }
 +    *pptl = fTravelLog.p;
 +    fTravelLog.p->AddRef();
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ShowControlWindow(UINT id, BOOL fShow)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::IsControlWindowShown(UINT id, BOOL *pfShown)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::IEGetDisplayName(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::IEParseDisplayName(UINT uiCP, LPCWSTR pwszPath, LPITEMIDLIST *ppidlOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::DisplayParseError(HRESULT hres, LPCWSTR pwszPath)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetNavigateState(BNSTATE bnstate)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetNavigateState(BNSTATE *pbnstate)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::NotifyRedirect(IShellView *psv, LPCITEMIDLIST pidl, BOOL *pfDidBrowse)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateWindowList()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateBackForwardState()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetFlags(DWORD dwFlags, DWORD dwFlagMask)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetFlags(DWORD *pdwFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CanNavigateNow()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPidl(LPITEMIDLIST *ppidl)
 +{
 +    // called by explorer bar to get current pidl
 +    if (ppidl == NULL)
 +        return E_POINTER;
 +    *ppidl = ILClone(fCurrentDirectoryPIDL);
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetReferrer(LPCITEMIDLIST pidl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +DWORD STDMETHODCALLTYPE CShellBrowser::GetBrowserIndex()
 +{
 +    return -1;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetBrowserByIndex(DWORD dwID, IUnknown **ppunk)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetHistoryObject(IOleObject **ppole, IStream **pstm, IBindCtx **ppbc)
 +{
 +    if (ppole == NULL || pstm == NULL || ppbc == NULL)
 +        return E_INVALIDARG;
 +    *ppole = fHistoryObject;
 +    if (fHistoryObject != NULL)
 +        fHistoryObject->AddRef();
 +    *pstm = fHistoryStream;
 +    if (fHistoryStream != NULL)
 +        fHistoryStream->AddRef();
 +    *ppbc = fHistoryBindContext;
 +    if (fHistoryBindContext != NULL)
 +        fHistoryBindContext->AddRef();
 +    fHistoryObject = NULL;
 +    fHistoryStream = NULL;
 +    fHistoryBindContext = NULL;
 +    if (*ppole == NULL)
 +        return E_FAIL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetHistoryObject(IOleObject *pole, BOOL fIsLocalAnchor)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CacheOLEServer(IOleObject *pole)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetSetCodePage(VARIANT *pvarIn, VARIANT *pvarOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnHttpEquiv(
 +    IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPalette(HPALETTE *hpal)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::RegisterWindow(BOOL fForceRegister, int swc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::WndProcBS(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetAsDefFolderSettings()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewRect(RECT *prc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnSize(WPARAM wParam)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnCreate(struct tagCREATESTRUCTW *pcs)
 +{
 +    m_hAccel = LoadAcceleratorsW(GetModuleHandle(L"browseui.dll"), MAKEINTRESOURCEW(256));
 +    return S_OK;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::OnCommand(WPARAM wParam, LPARAM lParam)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnDestroy()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::OnNotify(struct tagNMHDR *pnm)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnSetFocus()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::OnFrameWindowActivateBS(BOOL fActive)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ReleaseShellView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ActivatePendingView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CreateViewWindow(
 +    IShellView *psvNew, IShellView *psvOld, LPRECT prcView, HWND *phwnd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::CreateBrowserPropSheetExt(REFIID riid, void **ppv)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewWindow(HWND *phwndView)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetBaseBrowserData(LPCBASEBROWSERDATA *pbbd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LPBASEBROWSERDATA STDMETHODCALLTYPE CShellBrowser::PutBaseBrowserData()
 +{
 +    return NULL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTravelLog(ITravelLog *ptl, DWORD dw)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetTopBrowser()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Offline(int iCmd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::AllowViewResize(BOOL f)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetActivateState(UINT u)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateSecureLockIcon(int eSecureLock)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeDownloadManager()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTransitionSite()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_Initialize(HWND hwnd, IUnknown *pauto)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_CancelPendingNavigationAsync()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_CancelPendingView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_MaySaveChanges()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_PauseOrResumeView(BOOL fPaused)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_DisableModeless()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF, DWORD dwFlags)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_TryShell2Rename(IShellView *psv, LPCITEMIDLIST pidlNew)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SwitchActivationNow()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ExecChildren(IUnknown *punkBar, BOOL fBroadcast,
 +    const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SendChildren(
 +    HWND hwndBar, BOOL fBroadcast, UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetFolderSetData(struct tagFolderSetData *pfsd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_OnFocusChange(UINT itb)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_ShowHideChildWindows(BOOL fChildOnly)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +UINT STDMETHODCALLTYPE CShellBrowser::_get_itbLastFocus()
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_put_itbLastFocus(UINT itbLastFocus)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_UIActivateView(UINT uState)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_GetViewBorderRect(RECT *prc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_UpdateViewRectSize()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeNextBorder(UINT itb)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeView()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_GetEffectiveClientArea(LPRECT lprectBorder, HMONITOR hmon)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +IStream *STDMETHODCALLTYPE CShellBrowser::v_GetViewStream(LPCITEMIDLIST pidl, DWORD grfMode, LPCWSTR pwszName)
 +{
 +    return NULL;
 +}
 +
 +LRESULT STDMETHODCALLTYPE CShellBrowser::ForwardViewMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetAcceleratorMenu(HACCEL hacc)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +int STDMETHODCALLTYPE CShellBrowser::_GetToolbarCount()
 +{
 +    return 0;
 +}
 +
 +LPTOOLBARITEM STDMETHODCALLTYPE CShellBrowser::_GetToolbarItem(int itb)
 +{
 +    return NULL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SaveToolbars(IStream *pstm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_LoadToolbars(IStream *pstm)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_CloseAndReleaseToolbars(BOOL fClose)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayGetNextToolbarFocus(
 +    LPMSG lpMsg, UINT itbNext, int citb, LPTOOLBARITEM *pptbi, HWND *phwnd)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeNextBorderHelper(UINT itb, BOOL bUseHmonitor)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +UINT STDMETHODCALLTYPE CShellBrowser::_FindTBar(IUnknown *punkSrc)
 +{
 +    return 0;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_SetFocus(LPTOOLBARITEM ptbi, HWND hwnd, LPMSG lpMsg)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +extern HRESULT IUnknown_HasFocusIO(IUnknown * punk);
 +extern HRESULT IUnknown_TranslateAcceleratorIO(IUnknown * punk, MSG * pmsg);
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayTranslateAccelerator(MSG *pmsg)
 +{
 +    for (int i = 0; i < 3; i++)
 +    {
 +        if (IUnknown_TranslateAcceleratorIO(fClientBars[i].clientBar, pmsg) == S_OK)
 +            return S_OK;
 +    }
 +
 +    if (fCurrentShellView->TranslateAcceleratorW(pmsg) != S_OK)
 +    {
 +        if (TranslateAcceleratorSB(pmsg, 0) != S_OK)
 +            return S_FALSE;
 +        return S_OK;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::_GetBorderDWHelper(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::v_CheckZoneCrossing(LPCITEMIDLIST pidl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoBack()
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    HRESULT                                 hResult;
 +
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return travelLog->Travel(static_cast<IDropTarget *>(this), TLOG_BACK);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoForward()
 +{
 +    CComPtr<ITravelLog>                     travelLog;
 +    HRESULT                                 hResult;
 +
 +    hResult = GetTravelLog(&travelLog);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return travelLog->Travel(static_cast<IDropTarget *>(this), TLOG_FORE);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoHome()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GoSearch()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate(BSTR URL, VARIANT *Flags,
 +    VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh()
 +{
 +    VARIANT                                 level;
 +
 +    V_VT(&level) = VT_I4;
 +    V_I4(&level) = 4;
 +    return Refresh2(&level);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh2(VARIANT *Level)
 +{
 +    CComPtr<IOleCommandTarget>              oleCommandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return oleCommandTarget->Exec(NULL, 22, 1, Level, NULL);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Stop()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Application(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Parent(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Container(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Document(IDispatch **ppDisp)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_TopLevelContainer(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Type(BSTR *Type)
 +{
 +    return E_NOTIMPL;
 +}
 +#ifdef __exdisp_h__
 +#define long LONG
 +#endif
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Left(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Left(long Left)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Top(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Top(long Top)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Width(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Width(long Width)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Height(long *pl)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Height(long Height)
 +{
 +    return E_NOTIMPL;
 +}
 +#ifdef __exdisp_h__
 +#undef long
 +#endif
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_LocationName(BSTR *LocationName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_LocationURL(BSTR *LocationURL)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Busy(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Quit()
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ClientToWindow(int *pcx, int *pcy)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::PutProperty(BSTR Property, VARIANT vtValue)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetProperty(BSTR Property, VARIANT *pvtValue)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Name(BSTR *Name)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_HWND(SHANDLE_PTR *pHWND)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullName(BSTR *FullName)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Path(BSTR *Path)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Visible(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Visible(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusBar(VARIANT_BOOL *pBool)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusBar(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusText(BSTR *StatusText)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusText(BSTR StatusText)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_ToolBar(int *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_ToolBar(int Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_MenuBar(VARIANT_BOOL *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_MenuBar(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullScreen(VARIANT_BOOL *pbFullScreen)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_FullScreen(VARIANT_BOOL bFullScreen)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate2(VARIANT *URL, VARIANT *Flags,
 +    VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
 +{
 +    LPITEMIDLIST                            pidl;
 +    HRESULT                                 hResult;
 +
 +    // called from drive combo box to navigate to a directory
 +    if (V_VT(URL) != (VT_ARRAY | VT_UI1))
 +        return E_INVALIDARG;
 +    if (V_ARRAY(URL)->cDims != 1 || V_ARRAY(URL)->cbElements != 1)
 +        return E_INVALIDARG;
 +    pidl = (LPITEMIDLIST)V_ARRAY(URL)->pvData;
 +    hResult = BrowseToPIDL((LPITEMIDLIST)pidl, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatusWB(OLECMDID cmdID, OLECMDF *pcmdf)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt,
 +    VARIANT *pvaIn, VARIANT *pvaOut)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::ShowBrowserBar(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize)
 +{
 +    CLSID                                   classID;
 +    bool                                    vertical;
 +
 +    // called to show search bar
 +    if (V_VT(pvaClsid) != VT_BSTR)
 +        return E_INVALIDARG;
 +    CLSIDFromString(V_BSTR(pvaClsid), &classID);
 +    // TODO: properly compute the value of vertical
 +    vertical = true;
 +    return ShowBand(classID, vertical);
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_ReadyState(READYSTATE *plReadyState)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Offline(VARIANT_BOOL *pbOffline)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Offline(VARIANT_BOOL bOffline)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Silent(VARIANT_BOOL *pbSilent)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Silent(VARIANT_BOOL bSilent)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsBrowser(VARIANT_BOOL *pbRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsBrowser(VARIANT_BOOL bRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsDropTarget(VARIANT_BOOL *pbRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsDropTarget(VARIANT_BOOL bRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_TheaterMode(VARIANT_BOOL *pbRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_TheaterMode(VARIANT_BOOL bRegister)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_AddressBar(VARIANT_BOOL *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_AddressBar(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::get_Resizable(VARIANT_BOOL *Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::put_Resizable(VARIANT_BOOL Value)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::FindWindowByIndex(DWORD dwID, IUnknown **ppunk)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetWindowData(IStream *pStream, LPWINDOWDATA pWinData)
 +{
 +    if (pWinData == NULL)
 +        return E_POINTER;
 +
 +    pWinData->dwWindowID = -1;
 +    pWinData->uiCP = 0;
 +    pWinData->pidl = ILClone(fCurrentDirectoryPIDL);
 +    pWinData->lpszUrl = NULL;
 +    pWinData->lpszUrlLocation = NULL;
 +    pWinData->lpszTitle = NULL;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistoryPosition(LPWSTR pszUrlLocation, DWORD dwPosition)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetClassID(CLSID *pClassID)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistory(IStream *pStream, IBindCtx *pbc)
 +{
 +    CComPtr<IPersistHistory>                viewPersistHistory;
 +    CComPtr<IOleObject>                     viewHistoryObject;
 +    persistState                            oldState;
 +    ULONG                                   numRead;
 +    LPITEMIDLIST                            pidl;
 +    HRESULT                                 hResult;
 +
 +    hResult = pStream->Read(&oldState, sizeof(oldState), &numRead);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    if (numRead != sizeof(oldState) || oldState.dwSize != sizeof(oldState))
 +        return E_FAIL;
 +    if (oldState.browseType != 2)
 +        return E_FAIL;
 +    pidl = static_cast<LPITEMIDLIST>(CoTaskMemAlloc(oldState.pidlSize));
 +    if (pidl == NULL)
 +        return E_OUTOFMEMORY;
 +    hResult = pStream->Read(pidl, oldState.pidlSize, &numRead);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +    {
 +        ILFree(pidl);
 +        return hResult;
 +    }
 +    if (numRead != oldState.pidlSize)
 +    {
 +        ILFree(pidl);
 +        return E_FAIL;
 +    }
 +    hResult = CoCreateInstance(oldState.persistClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER,
 +        IID_PPV_ARG(IOleObject, &viewHistoryObject));
 +    fHistoryObject = viewHistoryObject;
 +    fHistoryStream = pStream;
 +    fHistoryBindContext = pbc;
 +    hResult = BrowseToPIDL(pidl, BTP_UPDATE_CUR_HISTORY);
 +    fHistoryObject = NULL;
 +    fHistoryStream = NULL;
 +    fHistoryBindContext = NULL;
 +    ILFree(pidl);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SaveHistory(IStream *pStream)
 +{
 +    CComPtr<IPersistHistory>                viewPersistHistory;
 +    persistState                            newState;
 +    HRESULT                                 hResult;
 +
 +    hResult = fCurrentShellView->GetItemObject(
 +        SVGIO_BACKGROUND, IID_PPV_ARG(IPersistHistory, &viewPersistHistory));
 +    memset(&newState, 0, sizeof(newState));
 +    newState.dwSize = sizeof(newState);
 +    newState.browseType = 2;
 +    newState.browserIndex = GetBrowserIndex();
 +    if (viewPersistHistory.p != NULL)
 +    {
 +        hResult = viewPersistHistory->GetClassID(&newState.persistClass);
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +    }
 +    newState.pidlSize = ILGetSize(fCurrentDirectoryPIDL);
 +    hResult = pStream->Write(&newState, sizeof(newState), NULL);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    hResult = pStream->Write(fCurrentDirectoryPIDL, newState.pidlSize, NULL);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return hResult;
 +    if (viewPersistHistory.p != NULL)
 +    {
 +        hResult = viewPersistHistory->SaveHistory(pStream);
 +        if (FAILED_UNEXPECTEDLY(hResult))
 +            return hResult;
 +    }
 +    return S_OK;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::SetPositionCookie(DWORD dwPositioncookie)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +HRESULT STDMETHODCALLTYPE CShellBrowser::GetPositionCookie(DWORD *pdwPositioncookie)
 +{
 +    return E_NOTIMPL;
 +}
 +
 +LRESULT CShellBrowser::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    OnCreate(reinterpret_cast<LPCREATESTRUCT> (lParam));
 +    return 0;
 +}
 +
 +template<class T>
 +void ReleaseCComPtrExpectZero(CComPtr<T>& cptr, BOOL forceRelease = FALSE)
 +{
 +    if (cptr.p != NULL)
 +    {
 +        int nrc = cptr->Release();
 +        if (nrc > 0)
 +        {
 +            DbgPrint("WARNING: Unexpected RefCount > 0!\n");
 +            if (forceRelease)
 +            {
 +                while (nrc > 0)
 +                {
 +                    nrc = cptr->Release();
 +                }
 +            }
 +        }
 +        cptr.Detach();
 +    }
 +}
 +
 +LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    HRESULT hr;
 +    // TODO: rip down everything
 +    {
 +        fCurrentShellView->DestroyViewWindow();
 +        fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
 +        ReleaseCComPtrExpectZero(fCurrentShellView);
 +
 +        for (int i = 0; i < 3; i++)
 +        {
 +            if (fClientBars[i].clientBar == NULL)
 +                continue;
 +            IDockingWindow * pdw;
 +            hr = fClientBars[i].clientBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &pdw));
 +            if (FAILED_UNEXPECTEDLY(hr))
 +                continue;
 +            pdw->ShowDW(FALSE);
 +            pdw->CloseDW(0);
 +            pdw->Release();
 +            ReleaseCComPtrExpectZero(fClientBars[i].clientBar);
 +        }
 +        ReleaseCComPtrExpectZero(fTravelLog);
 +
 +        fCurrentShellFolder.Release();
 +        ILFree(fCurrentDirectoryPIDL);
 +        ::DestroyWindow(fStatusBar);
 +        DestroyMenu(fCurrentMenuBar);
 +    }
 +    PostQuitMessage(0);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    CComPtr<IDockingWindow>                 dockingWindow;
 +    RECT                                    availableBounds;
 +    static const INT                        excludeItems[] = {1, 1, 1, 0xa001, 0, 0};
 +    HRESULT                                 hResult;
 +
 +    if (wParam != SIZE_MINIMIZED)
 +    {
 +        GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
 +        for (INT x = 0; x < 3; x++)
 +        {
 +            if (fClientBars[x].clientBar != NULL)
 +            {
 +                hResult = fClientBars[x].clientBar->QueryInterface(
 +                    IID_PPV_ARG(IDockingWindow, &dockingWindow));
 +                if (SUCCEEDED(hResult) && dockingWindow != NULL)
 +                {
 +                    hResult = dockingWindow->ResizeBorderDW(
 +                        &availableBounds, static_cast<IDropTarget *>(this), TRUE);
 +                    break;
 +                }
 +            }
 +        }
 +        RepositionBars();
 +    }
 +    return 1;
 +}
 +
 +LRESULT CShellBrowser::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    HMENU  theMenu;
 +    LPARAM menuIndex = lParam;
 +
 +    theMenu = reinterpret_cast<HMENU>(wParam);
 +
 +    if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_FILE))
 +    {
 +        menuIndex = 0;
 +    }
 +    else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_EDIT))
 +    {
 +        menuIndex = 1;
 +    }
 +    else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_VIEW))
 +    {
 +        UpdateViewMenu(theMenu);
 +        menuIndex = 2;
 +    }
 +    else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_FAVORITES))
 +    {
 +        menuIndex = 3;
 +    }
 +    else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_TOOLS))
 +    {
 +        menuIndex = 4;
 +    }
 +    else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_HELP))
 +    {
 +        menuIndex = 5;
 +    }
 +
 +    //DbgPrint("Before relay:\n");
 +    //DbgDumpMenu(theMenu);
 +
 +    LRESULT ret = RelayMsgToShellView(uMsg, wParam, menuIndex, bHandled);
 +
 +    //DbgPrint("After relay:\n");
 +    //DbgDumpMenu(theMenu);
 +
 +    return ret;
 +}
 +
 +LRESULT CShellBrowser::RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    if (fCurrentShellViewWindow != NULL)
 +        return SendMessage(fCurrentShellViewWindow, uMsg, wParam, lParam);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = DoFolderOptions();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +#ifndef __REACTOS__
 +    WNetConnectionDialog(m_hWnd, RESOURCETYPE_DISK);
 +#endif /* __REACTOS__ */
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnDisconnectNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +#ifndef __REACTOS__
 +    WNetDisconnectDialog(m_hWnd, RESOURCETYPE_DISK);
 +#endif /* __REACTOS__ */
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnAboutReactOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    ShellAbout(m_hWnd, _T("ReactOS"), _T(""), NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = GoBack();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = GoForward();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = NavigateToParent();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    hResult = GoHome();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    // FIXME: This does not appear to be what windows does.
 +    hResult = NavigateToParent();
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnIsThisLegal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    HRESULT                                 hResult;
 +
 +    typedef HRESULT (WINAPI *PSHOpenNewFrame)(LPITEMIDLIST pidl, IUnknown *b, long c, long d);
 +    PSHOpenNewFrame Func = NULL;
 +    HMODULE Module = GetModuleHandle(TEXT("browseui.dll"));
 +    if (Module != NULL)
 +        Func = reinterpret_cast<PSHOpenNewFrame>(GetProcAddress(Module, (LPCSTR) 103));
 +    if (Func != NULL)
 +    {
 +        LPITEMIDLIST                        desktopPIDL;
 +
 +        hResult = SHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, 0, &desktopPIDL);
 +        if (SUCCEEDED(hResult))
 +        {
 +            hResult = Func(desktopPIDL, NULL, -1, 1);
 +        }
 +    }
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    fStatusBarVisible = !fStatusBarVisible;
 +    // TODO: trigger a relayout of contained items
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TOOLBARLOCKED, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TOOLBARBANDSHOWN, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_LINKSBANDSHOWN, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TEXTLABELS, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    CComPtr<IOleCommandTarget>              commandTarget;
 +    HRESULT                                 hResult;
 +
 +    hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
 +        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return 0;
 +    hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_CUSTOMIZEENABLED, 0, NULL, NULL);
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::OnGoTravel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 +{
 +    return 0;
 +}
 +
 +LRESULT CShellBrowser::RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 +{
 +    if (HIWORD(wParam) == 0 && LOWORD(wParam) < FCIDM_SHVIEWLAST && fCurrentShellViewWindow != NULL)
 +        return SendMessage(fCurrentShellViewWindow, uMsg, wParam, lParam);
 +    return 0;
 +}
 +
 +static HRESULT ExplorerMessageLoop(IEThreadParamBlock * parameters)
 +{
 +    CComPtr<CShellBrowser>    theCabinet;
 +    HRESULT                   hResult;
 +    MSG Msg;
 +    BOOL Ret;
 +    
 +    ATLTRY(theCabinet = new CComObject<CShellBrowser>);
 +    if (theCabinet == NULL)
 +    {
 +        return E_OUTOFMEMORY;
 +    }
 +    
 +    hResult = theCabinet->Initialize(parameters->directoryPIDL, 0, 0, 0);
 +    if (FAILED_UNEXPECTEDLY(hResult))
 +        return E_OUTOFMEMORY;
 +
 +    while ((Ret = GetMessage(&Msg, NULL, 0, 0)) != 0)
 +    {
 +        if (Ret == -1)
 +        {
 +            // Error: continue or exit?
 +            break;
 +        }
 +
 +        if (Msg.message == WM_QUIT)
 +            break;
 +
 +        if (theCabinet->v_MayTranslateAccelerator(&Msg) != S_OK)
 +        {
 +            TranslateMessage(&Msg);
 +            DispatchMessage(&Msg);
 +        }
 +    }
 +    
 +    //TerminateProcess(GetCurrentProcess(), hResult);
 +
 +    int nrc = theCabinet->Release();
 +    if (nrc > 0)
 +    {
 +        DbgPrint("WARNING: There are %d references to the CShellBrowser active or leaked, process will never terminate. Terminating forcefully.\n", nrc);
 +
 +        //TerminateProcess(GetCurrentProcess(), 1);
 +    }
 +
 +    theCabinet.Detach();
 +
 +    return hResult;
 +}
 +
 +DWORD WINAPI BrowserThreadProc(LPVOID lpThreadParameter)
 +{
 +    HRESULT hr;
 +    IEThreadParamBlock * parameters = (IEThreadParamBlock *) lpThreadParameter;
 +    INITCOMMONCONTROLSEX iccex =
 +    {
 +        sizeof(iccex),
 +        0xFFFF /* everything! */
 +    };
 +
 +    OleInitialize(NULL);
 +    InitCommonControlsEx(&iccex);
 +
 +    ATLTRY(hr = ExplorerMessageLoop(parameters));
 +
 +    OleUninitialize();
 +
 +    return hr;
 +}
index 0000000,228093f..228093f
mode 000000,100644..100644
--- /dev/null
index 3bc6caf,be4f63e..be4f63e
Binary files differ
index 60270db,efeb917..efeb917
Binary files differ
index c0ea235,c608c72..c608c72
Binary files differ
index 654147f,326acb4..326acb4
Binary files differ
index 8614148,982babd..982babd
Binary files differ
index efeb917,d04cc5e..d04cc5e
Binary files differ
index 29083ba,1122201..1122201
Binary files differ
index 796bfc3,2e446ea..2e446ea
Binary files differ
index 24e06a6,b5c3440..b5c3440
Binary files differ
index 80a9055,106ee53..106ee53
Binary files differ
index 5bf64ee,5e026e9..5e026e9
Binary files differ
index 4873f86,4de1118..4de1118
Binary files differ
index ee440b0,fc01955..fc01955
Binary files differ
index 0a49309,e02cfee..e02cfee
Binary files differ
index 1c68ad0,5d8d9e8..5d8d9e8
Binary files differ
index d5ea09d,9cc351d..9cc351d
Binary files differ
index ea01402,1663601..1663601
Binary files differ
index 9191f4e,0c4b90a..0c4b90a
Binary files differ
index fecefae,93d90e6..93d90e6
Binary files differ
index 384c87d,c3bc210..c3bc210
Binary files differ
index 3050eb6,f983c73..f983c73
Binary files differ
index f97061a,cdef71a..cdef71a
Binary files differ
index 401adfb,4a3cf4a..4a3cf4a
Binary files differ
index 5938cd0,30c71d7..30c71d7
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
index 0dc5e78,0000000..1e05702
mode 100644,000000..100644
--- /dev/null
@@@ -1,424 -1,0 +1,442 @@@
-     if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconFile,
-                                          wszPath, MAX_PATH))
 +/*
 + *    Copyright 1997    Marcus Meissner
 + *    Copyright 1998    Juergen Schmied
 + *
 + * 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"
 +
 +WCHAR swShell32Name[MAX_PATH];
 +
 +DWORD NumIconOverlayHandlers = 0;
 +IShellIconOverlayIdentifier ** Handlers = NULL;
 +
 +static HRESULT getIconLocationForFolder(LPCITEMIDLIST pidl, UINT uFlags,
 +                                        LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
 +{
 +    int icon_idx;
++    bool cont=TRUE;
 +    WCHAR wszPath[MAX_PATH];
 +    WCHAR wszCLSIDValue[CHARS_IN_GUID];
 +    static const WCHAR shellClassInfo[] = { '.', 'S', 'h', 'e', 'l', 'l', 'C', 'l', 'a', 's', 's', 'I', 'n', 'f', 'o', 0 };
 +    static const WCHAR iconFile[] = { 'I', 'c', 'o', 'n', 'F', 'i', 'l', 'e', 0 };
 +    static const WCHAR clsid[] = { 'C', 'L', 'S', 'I', 'D', 0 };
 +    static const WCHAR clsid2[] = { 'C', 'L', 'S', 'I', 'D', '2', 0 };
 +    static const WCHAR iconIndex[] = { 'I', 'c', 'o', 'n', 'I', 'n', 'd', 'e', 'x', 0 };
 +
-         WCHAR wszIconIndex[10];
-         SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconIndex,
-                                          wszIconIndex, 10);
-         *piIndex = _wtoi(wszIconIndex);
-     }
-     else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid,
-              wszCLSIDValue, CHARS_IN_GUID) &&
-              HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx))
-     {
-         *piIndex = icon_idx;
-     }
-     else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid2,
-              wszCLSIDValue, CHARS_IN_GUID) &&
-              HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx))
-     {
-         *piIndex = icon_idx;
++    /*
++    Optimisation. GetCustomFolderAttribute has a critical lock on it, and isn't fast.
++    Test the water (i.e., see if the attribute exists) before questioning it three times
++    when most folders don't use it at all.
++    */
++    WCHAR wszBigToe[3];
++    if (!(uFlags & GIL_DEFAULTICON) && SHELL32_GetCustomFolderAttributes(pidl, shellClassInfo,
++                                         wszBigToe, 3))
 +    {
-     else
++        if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconFile,
++                                             wszPath, MAX_PATH))
++        {
++            WCHAR wszIconIndex[10];
++            SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconIndex,
++                                             wszIconIndex, 10);
++            *piIndex = _wtoi(wszIconIndex);
++            cont=FALSE;
++        }
++        else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid,
++                 wszCLSIDValue, CHARS_IN_GUID) &&
++                 HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx))
++        {
++            *piIndex = icon_idx;
++            cont=FALSE;
++        }
++        else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid2,
++                 wszCLSIDValue, CHARS_IN_GUID) &&
++                 HCR_GetIconW(wszCLSIDValue, szIconFile, NULL, cchMax, &icon_idx))
++        {
++            *piIndex = icon_idx;
++            cont=FALSE;
++        }
 +    }
-         if (SUCCEEDED(getIconLocationForFolder(
-                           pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH,
-                           &icon_idx,
-                           &flags)))
-         {
-             initIcon->SetShortcutIcon(wTemp, icon_idx);
-         }
++    if (cont)
 +    {
 +        static const WCHAR folder[] = { 'F', 'o', 'l', 'd', 'e', 'r', 0 };
 +
 +        if (!HCR_GetIconW(folder, szIconFile, NULL, cchMax, &icon_idx))
 +        {
 +            lstrcpynW(szIconFile, swShell32Name, cchMax);
 +            icon_idx = -IDI_SHELL_FOLDER;
 +        }
 +
 +        if (uFlags & GIL_OPENICON)
 +            *piIndex = icon_idx < 0 ? icon_idx - 1 : icon_idx + 1;
 +        else
 +            *piIndex = icon_idx;
 +    }
 +
 +    return S_OK;
 +}
 +
 +void InitIconOverlays(void)
 +{
 +    HKEY hKey;
 +    DWORD dwIndex, dwResult, dwSize;
 +    WCHAR szName[MAX_PATH];
 +    WCHAR szValue[100];
 +    CLSID clsid;
 +    IShellIconOverlayIdentifier * Overlay;
 +
 +    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
 +        return;
 +
 +    if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwResult, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
 +    {
 +        RegCloseKey(hKey);
 +        return;
 +    }
 +
 +    Handlers = (IShellIconOverlayIdentifier **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwResult * sizeof(IShellIconOverlayIdentifier*));
 +    if (!Handlers)
 +    {
 +        RegCloseKey(hKey);
 +        return;
 +    }
 +
 +    dwIndex = 0;
 +
 +    CoInitialize(0);
 +
 +    do
 +    {
 +        dwSize = sizeof(szName) / sizeof(WCHAR);
 +        dwResult = RegEnumKeyExW(hKey, dwIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
 +
 +        if (dwResult == ERROR_NO_MORE_ITEMS)
 +            break;
 +
 +        if (dwResult == ERROR_SUCCESS)
 +        {
 +            dwSize = sizeof(szValue) / sizeof(WCHAR);
 +            if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szValue, &dwSize) == ERROR_SUCCESS)
 +            {
 +
 +                CLSIDFromString(szValue, &clsid);
 +                dwResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellIconOverlayIdentifier, &Overlay));
 +                if (dwResult == S_OK)
 +                {
 +                    Handlers[NumIconOverlayHandlers] = Overlay;
 +                    NumIconOverlayHandlers++;
 +                }
 +            }
 +        }
 +
 +        dwIndex++;
 +
 +    } while(1);
 +
 +    RegCloseKey(hKey);
 +}
 +
 +BOOL
 +GetIconOverlay(LPCITEMIDLIST pidl, WCHAR * wTemp, int* pIndex)
 +{
 +    DWORD Index;
 +    HRESULT hResult;
 +    int Priority;
 +    int HighestPriority;
 +    ULONG IconIndex;
 +    ULONG Flags;
 +    WCHAR szPath[MAX_PATH];
 +
 +    if(!SHGetPathFromIDListW(pidl, szPath))
 +        return FALSE;
 +
 +
 +    HighestPriority = 101;
 +    IconIndex = NumIconOverlayHandlers;
 +    for(Index = 0; Index < NumIconOverlayHandlers; Index++)
 +    {
 +        hResult = Handlers[Index]->IsMemberOf(szPath, SFGAO_FILESYSTEM);
 +        if (hResult == S_OK)
 +        {
 +            hResult = Handlers[Index]->GetPriority(&Priority);
 +            if (hResult == S_OK)
 +            {
 +                if (Priority < HighestPriority)
 +                {
 +                    HighestPriority = Priority;
 +                    IconIndex = Index;
 +                }
 +            }
 +        }
 +    }
 +
 +    if (IconIndex == NumIconOverlayHandlers)
 +        return FALSE;
 +
 +    hResult = Handlers[IconIndex]->GetOverlayInfo(wTemp, MAX_PATH, pIndex, &Flags);
 +
 +    if (hResult == S_OK)
 +        return TRUE;
 +    else
 +        return FALSE;
 +}
 +
 +/**************************************************************************
 +*  IExtractIconW_Constructor
 +*/
 +IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl)
 +{
 +    CComPtr<IDefaultExtractIconInit>    initIcon;
 +    IExtractIconW *extractIcon;
 +    GUID const * riid;
 +    int icon_idx;
 +    UINT flags;
 +    CHAR sTemp[MAX_PATH];
 +    WCHAR wTemp[MAX_PATH];
 +    LPITEMIDLIST pSimplePidl = ILFindLastID(pidl);
 +    HRESULT hr;
 +
 +    hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon));
 +    if (FAILED(hr))
 +        return NULL;
 +
 +    hr = initIcon->QueryInterface(IID_PPV_ARG(IExtractIconW,&extractIcon));
 +    if (FAILED(hr))
 +        return NULL;
 +
 +    if (_ILIsDesktop(pSimplePidl))
 +    {
 +        initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP);
 +    }
 +    else if ((riid = _ILGetGUIDPointer(pSimplePidl)))
 +    {
 +        /* my computer and other shell extensions */
 +        static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\',
 +                                     '{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-',
 +                                     '%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x',
 +                                     '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0
 +                                   };
 +        WCHAR xriid[50];
 +
 +        swprintf(xriid, fmt,
 +                 riid->Data1, riid->Data2, riid->Data3,
 +                 riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
 +                 riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
 +
 +        const WCHAR* iconname = NULL;
 +        if (_ILIsBitBucket(pSimplePidl))
 +        {
 +            static const WCHAR szFull[] = {'F','u','l','l',0};
 +            static const WCHAR szEmpty[] = {'E','m','p','t','y',0};
 +            IEnumIDList *EnumIDList = NULL;
 +            CoInitialize(NULL);
 +
 +            IShellFolder2 *psfRecycleBin = NULL;
 +            IShellFolder *psfDesktop = NULL;
 +            hr = SHGetDesktopFolder(&psfDesktop);
 +
 +            if (SUCCEEDED(hr))
 +                hr = psfDesktop->BindToObject(pSimplePidl, NULL, IID_PPV_ARG(IShellFolder2, &psfRecycleBin));
 +            if (SUCCEEDED(hr))
 +                hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList);
 +
 +            ULONG itemcount;
 +            LPITEMIDLIST pidl = NULL;
 +            if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK)
 +            {
 +                CoTaskMemFree(pidl);
 +                iconname = szFull;
 +            } else {
 +                iconname = szEmpty;
 +            }
 +
 +            if (psfDesktop)
 +                psfDesktop->Release();
 +            if (psfRecycleBin)
 +                psfRecycleBin->Release();
 +            if (EnumIDList)
 +                EnumIDList->Release();
 +        }
 +
 +        if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx))
 +        {
 +            initIcon->SetNormalIcon(wTemp, icon_idx);
 +        }
 +        else
 +        {
 +            if (IsEqualGUID(*riid, CLSID_MyComputer))
 +                initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER);
 +            else if (IsEqualGUID(*riid, CLSID_MyDocuments))
 +                initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS);
 +            else if (IsEqualGUID(*riid, CLSID_NetworkPlaces))
 +                initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES);
 +            else
 +                initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER);
 +        }
 +    }
 +
 +    else if (_ILIsDrive (pSimplePidl))
 +    {
 +        static const WCHAR drive[] = { 'D', 'r', 'i', 'v', 'e', 0 };
 +        int icon_idx = -1;
 +
 +        if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH))
 +        {
 +            switch(GetDriveTypeA(sTemp))
 +            {
 +                case DRIVE_REMOVABLE:
 +                    icon_idx = IDI_SHELL_FLOPPY;
 +                    break;
 +                case DRIVE_CDROM:
 +                    icon_idx = IDI_SHELL_CDROM;
 +                    break;
 +                case DRIVE_REMOTE:
 +                    icon_idx = IDI_SHELL_NETDRIVE;
 +                    break;
 +                case DRIVE_RAMDISK:
 +                    icon_idx = IDI_SHELL_RAMDISK;
 +                    break;
 +                case DRIVE_NO_ROOT_DIR:
 +                    icon_idx = IDI_SHELL_CDROM;
 +                    break;
 +            }
 +        }
 +
 +        if (icon_idx != -1)
 +        {
 +            initIcon->SetNormalIcon(swShell32Name, -icon_idx);
 +        }
 +        else
 +        {
 +            if (HCR_GetIconW(drive, wTemp, NULL, MAX_PATH, &icon_idx))
 +                initIcon->SetNormalIcon(wTemp, icon_idx);
 +            else
 +                initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE);
 +        }
 +    }
 +
 +    else if (_ILIsFolder (pSimplePidl))
 +    {
 +        if (SUCCEEDED(getIconLocationForFolder(
 +                          pidl, 0, wTemp, MAX_PATH,
 +                          &icon_idx,
 +                          &flags)))
 +        {
 +            initIcon->SetNormalIcon(wTemp, icon_idx);
++            // FIXME: if/when getIconLocationForFolder does something for 
++            //        GIL_FORSHORTCUT, code below should be uncommented. and
++            //        the following line removed.
++            initIcon->SetShortcutIcon(wTemp, icon_idx);
 +        }
 +        if (SUCCEEDED(getIconLocationForFolder(
 +                          pidl, GIL_DEFAULTICON, wTemp, MAX_PATH,
 +                          &icon_idx,
 +                          &flags)))
 +        {
 +            initIcon->SetDefaultIcon(wTemp, icon_idx);
 +        }
++        // if (SUCCEEDED(getIconLocationForFolder(
++        //                   pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH,
++        //                   &icon_idx,
++        //                   &flags)))
++        // {
++        //     initIcon->SetShortcutIcon(wTemp, icon_idx);
++        // }
 +        if (SUCCEEDED(getIconLocationForFolder(
 +                          pidl, GIL_OPENICON, wTemp, MAX_PATH,
 +                          &icon_idx,
 +                          &flags)))
 +        {
 +            initIcon->SetOpenIcon(wTemp, icon_idx);
 +        }
 +    }
 +    else
 +    {
 +        BOOL found = FALSE;
 +
 +        if (_ILIsCPanelStruct(pSimplePidl))
 +        {
 +            if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, wTemp, MAX_PATH, &icon_idx)))
 +                found = TRUE;
 +        }
 +        else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH))
 +        {
 +            if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
 +                    && HCR_GetIconA(sTemp, sTemp, NULL, MAX_PATH, &icon_idx))
 +            {
 +                if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
 +                {
 +                    SHGetPathFromIDListW(pidl, wTemp);
 +                    icon_idx = 0;
 +                }
 +                else
 +                {
 +                    MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH);
 +                }
 +
 +                found = TRUE;
 +            }
 +            else if (!lstrcmpiA(sTemp, "lnkfile"))
 +            {
 +                /* extract icon from shell shortcut */
 +                CComPtr<IShellFolder>        dsf;
 +                CComPtr<IShellLinkW>        psl;
 +
 +                if (SUCCEEDED(SHGetDesktopFolder(&dsf)))
 +                {
 +                    HRESULT hr = dsf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*) &pidl, IID_NULL_PPV_ARG(IShellLinkW, &psl));
 +
 +                    if (SUCCEEDED(hr))
 +                    {
 +                        hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx);
 +
 +                        if (SUCCEEDED(hr) && *sTemp)
 +                            found = TRUE;
 +
 +                    }
 +                }
 +            }
 +        }
 +
 +        if (!found)
 +            /* default icon */
 +            initIcon->SetNormalIcon(swShell32Name, 0);
 +        else
 +            initIcon->SetNormalIcon(wTemp, icon_idx);
 +    }
 +
 +    return extractIcon;
 +}
 +
 +/**************************************************************************
 +*  IExtractIconA_Constructor
 +*/
 +IExtractIconA* IExtractIconA_Constructor(LPCITEMIDLIST pidl)
 +{
 +    IExtractIconW *extractIconW;
 +    IExtractIconA *extractIconA;
 +    HRESULT hr;
 +
 +    extractIconW = IExtractIconW_Constructor(pidl);
 +    if (!extractIconW)
 +        return NULL;
 +
 +    hr = extractIconW->QueryInterface(IID_PPV_ARG(IExtractIconA, &extractIconA));
 +    extractIconW->Release();
 +    if (FAILED(hr))
 +        return NULL;
 +    return extractIconA;
 +}
index 0ba1e18,0000000..aa3cbfb
mode 100644,000000..100644
--- /dev/null
@@@ -1,1077 -1,0 +1,1078 @@@
-     if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the faster one */
-         (e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT))
-       return 1;
-     if (wcsicmp(e1->sSourceFile,e2->sSourceFile))
-       return 1;
-     return 0;
 +/*
 + *    shell icon cache (SIC)
 + *
 + * Copyright 1998, 1999 Juergen Schmied
 + *
 + * 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(shell);
 +
 +/********************** THE ICON CACHE ********************************/
 +
 +#define INVALID_INDEX -1
 +
 +typedef struct
 +{
 +    LPWSTR sSourceFile;    /* file (not path!) containing the icon */
 +    DWORD dwSourceIndex;    /* index within the file, if it is a resoure ID it will be negated */
 +    DWORD dwListIndex;    /* index within the iconlist */
 +    DWORD dwFlags;        /* GIL_* flags */
 +    DWORD dwAccessTime;
 +} SIC_ENTRY, * LPSIC_ENTRY;
 +
 +static HDPA        sic_hdpa = 0;
 +
 +namespace
 +{
 +extern CRITICAL_SECTION SHELL32_SicCS;
 +CRITICAL_SECTION_DEBUG critsect_debug =
 +{
 +    0, 0, &SHELL32_SicCS,
 +    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
 +      0, 0, { (DWORD_PTR)(__FILE__ ": SHELL32_SicCS") }
 +};
 +CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
 +}
 +
 +/*****************************************************************************
 + * SIC_CompareEntries
 + *
 + * NOTES
 + *  Callback for DPA_Search
 + */
 +static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
 +{    LPSIC_ENTRY e1 = (LPSIC_ENTRY)p1, e2 = (LPSIC_ENTRY)p2;
 +
 +    TRACE("%p %p %8lx\n", p1, p2, lparam);
 +
 +    /* Icons in the cache are keyed by the name of the file they are
 +     * loaded from, their resource index and the fact if they have a shortcut
 +     * icon overlay or not.
 +     */
-     indexDPA = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice);
++    /* first the faster one */
++    if (e1->dwSourceIndex != e2->dwSourceIndex)
++      return (e1->dwSourceIndex < e2->dwSourceIndex) ? -1 : 1;
++
++    if ((e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT)) 
++      return ((e1->dwFlags & GIL_FORSHORTCUT) < (e2->dwFlags & GIL_FORSHORTCUT)) ? -1 : 1;
++  
++    return wcsicmp(e1->sSourceFile,e2->sSourceFile);
 +}
 +
 +/* declare SIC_LoadOverlayIcon() */
 +static int SIC_LoadOverlayIcon(int icon_idx);
 +
 +/*****************************************************************************
 + * SIC_OverlayShortcutImage            [internal]
 + *
 + * NOTES
 + *  Creates a new icon as a copy of the passed-in icon, overlayed with a
 + *  shortcut image.
 + * FIXME: This should go to the ImageList implementation!
 + */
 +static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
 +{    
 +    ICONINFO ShortcutIconInfo, TargetIconInfo;
 +    HICON ShortcutIcon = NULL, TargetIcon;
 +    BITMAP TargetBitmapInfo, ShortcutBitmapInfo;
 +    HDC ShortcutDC = NULL,
 +      TargetDC = NULL;
 +    HBITMAP OldShortcutBitmap = NULL,
 +      OldTargetBitmap = NULL;
 +
 +    static int s_imgListIdx = -1;
 +    ZeroMemory(&ShortcutIconInfo, sizeof(ShortcutIconInfo));
 +    ZeroMemory(&TargetIconInfo, sizeof(TargetIconInfo));
 +
 +    /* Get information about the source icon and shortcut overlay.
 +     * We will write over the source bitmaps to get the final ones */
 +    if (! GetIconInfo(SourceIcon, &TargetIconInfo))
 +        return NULL;
 +    
 +    /* Is it possible with the ImageList implementation? */
 +    if(!TargetIconInfo.hbmColor)
 +    {
 +        /* Maybe we'll support this at some point */
 +        FIXME("1bpp icon wants its overlay!\n");
 +        goto fail;
 +    }
 +        
 +    if(!GetObjectW(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo))
 +    {
 +        goto fail;
 +    }
 +
 +    /* search for the shortcut icon only once */
 +    if (s_imgListIdx == -1)
 +        s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT);
 +                           /* FIXME should use icon index 29 instead of the
 +                              resource id, but not all icons are present yet
 +                              so we can't use icon indices */
 +
 +    if (s_imgListIdx != -1)
 +    {
 +        if (large)
 +            ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT);
 +        else
 +            ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT);
 +    } else
 +        ShortcutIcon = NULL;
 +
 +    if (!ShortcutIcon || !GetIconInfo(ShortcutIcon, &ShortcutIconInfo))
 +    {
 +        goto fail;
 +    }
 +    
 +    /* Is it possible with the ImageLists ? */
 +    if(!ShortcutIconInfo.hbmColor)
 +    {
 +        /* Maybe we'll support this at some point */
 +        FIXME("Should draw 1bpp overlay!\n");
 +        goto fail;
 +    }
 +    
 +    if(!GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
 +    {
 +        goto fail;
 +    }
 +
 +    /* Setup the masks */
 +    ShortcutDC = CreateCompatibleDC(NULL);
 +    if (NULL == ShortcutDC) goto fail;
 +    OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
 +    if (NULL == OldShortcutBitmap) goto fail;
 +
 +    TargetDC = CreateCompatibleDC(NULL);
 +    if (NULL == TargetDC) goto fail;
 +    OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask);
 +    if (NULL == OldTargetBitmap) goto fail;
 +
 +    /* Create the complete mask by ANDing the source and shortcut masks.
 +     * NOTE: in an ImageList, all icons have the same dimensions */
 +    if (!BitBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
 +                ShortcutDC, 0, 0, SRCAND))
 +    {
 +      goto fail;
 +    }
 +
 +    /*
 +     * We must remove or add the alpha component to the shortcut overlay:
 +     * If we don't, SRCCOPY will copy it to our resulting icon, resulting in a
 +     * partially transparent icons where it shouldn't be, and to an invisible icon
 +     * if the underlying icon don't have any alpha channel information. (16bpp only icon for instance).
 +     * But if the underlying icon has alpha channel information, then we must mark the overlay information
 +     * as opaque.
 +     * NOTE: This code sucks(tm) and should belong to the ImageList implementation.
 +     * NOTE2: there are better ways to do this.
 +     */
 +    if(ShortcutBitmapInfo.bmBitsPixel == 32)
 +    {
 +        BOOL add_alpha;
 +        BYTE buffer[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
 +        BITMAPINFO* lpbmi = (BITMAPINFO*)buffer;
 +        PVOID bits;
 +        PULONG pixel;
 +        INT i, j;
 +        
 +        /* Find if the source bitmap has an alpha channel */
 +        if(TargetBitmapInfo.bmBitsPixel != 32) add_alpha = FALSE;
 +        else
 +        {
 +            ZeroMemory(buffer, sizeof(buffer));
 +            lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 +            lpbmi->bmiHeader.biWidth = TargetBitmapInfo.bmWidth;
 +            lpbmi->bmiHeader.biHeight = TargetBitmapInfo.bmHeight;
 +            lpbmi->bmiHeader.biPlanes = 1;
 +            lpbmi->bmiHeader.biBitCount = 32;
 +            
 +            bits = HeapAlloc(GetProcessHeap(), 0, TargetBitmapInfo.bmHeight * TargetBitmapInfo.bmWidthBytes);
 +            
 +            if(!bits) goto fail;
 +            
 +            if(!GetDIBits(TargetDC, TargetIconInfo.hbmColor, 0, TargetBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
 +            {
 +                ERR("GetBIBits failed!\n");
 +                HeapFree(GetProcessHeap(), 0, bits);
 +                goto fail;
 +            }
 +            
 +            i = j = 0;
 +            pixel = (PULONG)bits;
 +            
 +            for(i=0; i<TargetBitmapInfo.bmHeight; i++)
 +            {
 +                for(j=0; j<TargetBitmapInfo.bmWidth; j++)
 +                {
 +                    add_alpha = (*pixel++ & 0xFF000000) != 0;
 +                    if(add_alpha) break;
 +                }
 +                if(add_alpha) break;
 +            }
 +            HeapFree(GetProcessHeap(), 0, bits);
 +        }
 +        
 +        /* Allocate the bits */
 +        bits = HeapAlloc(GetProcessHeap(), 0, ShortcutBitmapInfo.bmHeight*ShortcutBitmapInfo.bmWidthBytes);
 +        if(!bits) goto fail;
 +        
 +        ZeroMemory(buffer, sizeof(buffer));
 +        lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 +        lpbmi->bmiHeader.biWidth = ShortcutBitmapInfo.bmWidth;
 +        lpbmi->bmiHeader.biHeight = ShortcutBitmapInfo.bmHeight;
 +        lpbmi->bmiHeader.biPlanes = 1;
 +        lpbmi->bmiHeader.biBitCount = 32;
 +        
 +        if(!GetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
 +        {
 +            ERR("GetBIBits failed!\n");
 +            HeapFree(GetProcessHeap(), 0, bits);
 +            goto fail;
 +        }
 +        
 +        pixel = (PULONG)bits;
 +        /* Remove alpha channel component or make it totally opaque */
 +        for(i=0; i<ShortcutBitmapInfo.bmHeight; i++)
 +        {
 +            for(j=0; j<ShortcutBitmapInfo.bmWidth; j++)
 +            {
 +                if(add_alpha) *pixel++ |= 0xFF000000;
 +                else *pixel++ &= 0x00FFFFFF;
 +            }
 +        }
 +        
 +        /* GetDIBits return BI_BITFIELDS with masks set to 0, and SetDIBits fails when masks are 0. The irony... */
 +        lpbmi->bmiHeader.biCompression = BI_RGB;
 +        
 +        /* Set the bits again */
 +        if(!SetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
 +        {
 +            ERR("SetBIBits failed!, %lu\n", GetLastError());
 +            HeapFree(GetProcessHeap(), 0, bits);
 +            goto fail;
 +        }
 +        HeapFree(GetProcessHeap(), 0, bits);
 +    }
 +
 +    /* Now do the copy. We overwrite the original icon data */
 +    if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor) ||
 +        NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
 +        goto fail;
 +    if (!MaskBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
 +                 ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
 +                 MAKEROP4(0xAA0000, SRCCOPY)))
 +    {
 +        goto fail;
 +    }
 +
 +    /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
 +       handles to NULL */
 +    SelectObject(TargetDC, OldTargetBitmap);
 +    DeleteDC(TargetDC);
 +    SelectObject(ShortcutDC, OldShortcutBitmap);
 +    DeleteDC(ShortcutDC);
 +
 +    /* Create the icon using the bitmaps prepared earlier */
 +    TargetIcon = CreateIconIndirect(&TargetIconInfo);
 +
 +    /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
 +    DeleteObject(TargetIconInfo.hbmColor);
 +    DeleteObject(TargetIconInfo.hbmMask);
 +    /* Delete what GetIconInfo gave us */
 +    DeleteObject(ShortcutIconInfo.hbmColor);
 +    DeleteObject(ShortcutIconInfo.hbmMask);
 +    DestroyIcon(ShortcutIcon);
 +
 +    return TargetIcon;
 +
 +fail:
 +    /* Clean up scratch resources we created */
 +    if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap);
 +    if (NULL != TargetDC) DeleteDC(TargetDC);
 +    if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
 +    if (NULL != ShortcutDC) DeleteDC(ShortcutDC);
 +    if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
 +    if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
 +    if (NULL != ShortcutIconInfo.hbmColor) DeleteObject(ShortcutIconInfo.hbmColor);
 +    if (NULL != ShortcutIconInfo.hbmMask) DeleteObject(ShortcutIconInfo.hbmColor);
 +    if (NULL != ShortcutIcon) DestroyIcon(ShortcutIcon);
 +
 +    return NULL;
 +}
 +
 +/*****************************************************************************
 + * SIC_IconAppend            [internal]
 + *
 + * NOTES
 + *  appends an icon pair to the end of the cache
 + */
 +static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
 +{
 +    LPSIC_ENTRY lpsice;
 +    INT ret, index, index1, indexDPA;
 +    WCHAR path[MAX_PATH];
 +    TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon);
 +
 +    lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
 +
 +    GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
 +    lpsice->sSourceFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, (wcslen(path)+1)*sizeof(WCHAR) );
 +    wcscpy( lpsice->sSourceFile, path );
 +
 +    lpsice->dwSourceIndex = dwSourceIndex;
 +    lpsice->dwFlags = dwFlags;
 +
 +    EnterCriticalSection(&SHELL32_SicCS);
 +
-       index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0);
++    indexDPA = DPA_Search (sic_hdpa, lpsice, 0, SIC_CompareEntries, 0, DPAS_SORTED|DPAS_INSERTAFTER);
++    indexDPA = DPA_InsertPtr(sic_hdpa, indexDPA, lpsice);
 +    if ( -1 == indexDPA )
 +    {
 +        ret = INVALID_INDEX;
 +        goto leave;
 +    }
 +
 +    index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
 +    index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
 +
 +    /* Something went wrong when allocating a new image in the list. Abort. */
 +    if((index == -1) || (index1 == -1))
 +    {
 +        WARN("Something went wrong when adding the icon to the list: small - 0x%x, big - 0x%x.\n",
 +            index, index1);
 +        if(index != -1) ImageList_Remove(ShellSmallIconList, index);
 +        if(index1 != -1) ImageList_Remove(ShellBigIconList, index1);
 +        ret = INVALID_INDEX;
 +        goto leave;
 +    }
 +
 +    if (index!=index1)
 +    {
 +        FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
 +        /* What to do ???? */
 +    }
 +    lpsice->dwListIndex = index;
 +    ret = lpsice->dwListIndex;
 +
 +leave:
 +    if(ret == INVALID_INDEX)
 +    {
 +        if(indexDPA != -1) DPA_DeletePtr(sic_hdpa, indexDPA);
 +        HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile);
 +        SHFree(lpsice);
 +    }
 +    LeaveCriticalSection(&SHELL32_SicCS);
 +    return ret;
 +}
 +/****************************************************************************
 + * SIC_LoadIcon                [internal]
 + *
 + * NOTES
 + *  gets small/big icon by number from a file
 + */
 +static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
 +{
 +    HICON hiconLarge=0;
 +    HICON hiconSmall=0;
 +    UINT ret;
 +    static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
 +
 +    if (!PrivateExtractIconExW)
 +    {
 +        HMODULE hUser32 = GetModuleHandleA("user32");
 +        PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
 +    }
 +
 +    if (PrivateExtractIconExW)
 +    {
 +        PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1);
 +    }
 +    else
 +    {
 +        PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0);
 +        PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0);
 +    }
 +
 +    if ( !hiconLarge ||  !hiconSmall)
 +    {
 +        WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
 +        if(hiconLarge) DestroyIcon(hiconLarge);
 +        if(hiconSmall) DestroyIcon(hiconSmall);
 +        return INVALID_INDEX;
 +    }
 +
 +    if (0 != (dwFlags & GIL_FORSHORTCUT))
 +    {
 +        HICON hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
 +        HICON hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
 +        if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
 +        {
 +            DestroyIcon(hiconLarge);
 +            DestroyIcon(hiconSmall);
 +            hiconLarge = hiconLargeShortcut;
 +            hiconSmall = hiconSmallShortcut;
 +        }
 +        else
 +        {
 +            WARN("Failed to create shortcut overlayed icons\n");
 +            if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
 +            if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
 +            dwFlags &= ~ GIL_FORSHORTCUT;
 +        }
 +    }
 +
 +    ret = SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
 +    DestroyIcon(hiconLarge);
 +    DestroyIcon(hiconSmall);
 +    return ret;
 +}
 +/*****************************************************************************
 + * SIC_GetIconIndex            [internal]
 + *
 + * Parameters
 + *    sSourceFile    [IN]    filename of file containing the icon
 + *    index        [IN]    index/resID (negated) in this file
 + *
 + * NOTES
 + *  look in the cache for a proper icon. if not available the icon is taken
 + *  from the file and cached
 + */
 +INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
 +{
 +    SIC_ENTRY sice;
 +    INT ret, index = INVALID_INDEX;
 +    WCHAR path[MAX_PATH];
 +
 +    TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex);
 +
 +    GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
 +    sice.sSourceFile = path;
 +    sice.dwSourceIndex = dwSourceIndex;
 +    sice.dwFlags = dwFlags;
 +
 +    EnterCriticalSection(&SHELL32_SicCS);
 +
 +    if (NULL != DPA_GetPtr (sic_hdpa, 0))
 +    {
 +      /* search linear from position 0*/
++      index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, DPAS_SORTED);
 +    }
 +
 +    if ( INVALID_INDEX == index )
 +    {
 +          ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
 +    }
 +    else
 +    {
 +      TRACE("-- found\n");
 +      ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex;
 +    }
 +
 +    LeaveCriticalSection(&SHELL32_SicCS);
 +    return ret;
 +}
 +
 +/*****************************************************************************
 + * SIC_Initialize            [internal]
 + */
 +BOOL SIC_Initialize(void)
 +{
 +    HICON hSm = NULL, hLg = NULL;
 +    INT cx_small, cy_small;
 +    INT cx_large, cy_large;
 +    HDC hDC;
 +    INT bpp;
 +    DWORD ilMask;
 +    BOOL result = FALSE;
 +
 +    TRACE("Entered SIC_Initialize\n");
 +
 +    if (sic_hdpa)
 +    {
 +        TRACE("Icon cache already initialized\n");
 +        return TRUE;
 +    }
 +
 +    sic_hdpa = DPA_Create(16);
 +    if (!sic_hdpa)
 +    {
 +        return FALSE;
 +    }
 +
 +    hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL);
 +    if (!hDC)
 +    {
 +        ERR("Failed to create information context (error %d)\n", GetLastError());
 +        goto end;
 +    }
 +
 +    bpp = GetDeviceCaps(hDC, BITSPIXEL);
 +    DeleteDC(hDC);
 +
 +    if (bpp <= 4)
 +        ilMask = ILC_COLOR4;
 +    else if (bpp <= 8)
 +        ilMask = ILC_COLOR8;
 +    else if (bpp <= 16)
 +        ilMask = ILC_COLOR16;
 +    else if (bpp <= 24)
 +        ilMask = ILC_COLOR24;
 +    else if (bpp <= 32)
 +        ilMask = ILC_COLOR32;
 +    else
 +        ilMask = ILC_COLOR;
 +
 +    ilMask |= ILC_MASK;
 +
 +    cx_small = GetSystemMetrics(SM_CXSMICON);
 +    cy_small = GetSystemMetrics(SM_CYSMICON);
 +    cx_large = GetSystemMetrics(SM_CXICON);
 +    cy_large = GetSystemMetrics(SM_CYICON);
 +
 +    ShellSmallIconList = ImageList_Create(cx_small,
 +                                          cy_small,
 +                                          ilMask,
 +                                          100,
 +                                          100);
 +    if (!ShellSmallIconList)
 +    {
 +        ERR("Failed to create the small icon list.\n");
 +        goto end;
 +    }
 +
 +    ShellBigIconList = ImageList_Create(cx_large,
 +                                        cy_large,
 +                                        ilMask,
 +                                        100,
 +                                        100);
 +    if (!ShellBigIconList)
 +    {
 +        ERR("Failed to create the big icon list.\n");
 +        goto end;
 +    }
 +    
 +    /* Load the document icon, which is used as the default if an icon isn't found. */
 +    hSm = (HICON)LoadImageW(shell32_hInstance,
 +                            MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
 +                            IMAGE_ICON,
 +                            cx_small,
 +                            cy_small,
 +                            LR_SHARED | LR_DEFAULTCOLOR);
 +    if (!hSm)
 +    {
 +        ERR("Failed to load small IDI_SHELL_DOCUMENT icon!\n");
 +        goto end;
 +    }
 +
 +    hLg = (HICON)LoadImageW(shell32_hInstance,
 +                            MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
 +                            IMAGE_ICON,
 +                            cx_large,
 +                            cy_large,
 +                            LR_SHARED | LR_DEFAULTCOLOR);
 +    if (!hLg)
 +    {
 +        ERR("Failed to load large IDI_SHELL_DOCUMENT icon!\n");
 +        goto end;
 +    }
 +
 +    if(SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0) == INVALID_INDEX)
 +    {
 +        ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n");
 +        goto end;
 +    }
 +    if(SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0) == INVALID_INDEX)
 +    {
 +        ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n");
 +        goto end;
 +    }
 +    
 +    /* Everything went fine */
 +    result = TRUE;
 +    
 +end:
 +    /* The image list keeps a copy of the icons, we must destroy them */
 +    if(hSm) DestroyIcon(hSm);
 +    if(hLg) DestroyIcon(hLg);
 +    
 +    /* Clean everything if something went wrong */
 +    if(!result)
 +    {
 +        if(sic_hdpa) DPA_Destroy(sic_hdpa);
 +        if(ShellSmallIconList) ImageList_Destroy(ShellSmallIconList);
 +        if(ShellBigIconList) ImageList_Destroy(ShellSmallIconList);
 +        sic_hdpa = NULL;
 +        ShellSmallIconList = NULL;
 +        ShellBigIconList = NULL;
 +    }
 +
 +    TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
 +
 +    return result;
 +}
 +
 +/*************************************************************************
 + * SIC_Destroy
 + *
 + * frees the cache
 + */
 +static INT CALLBACK sic_free( LPVOID ptr, LPVOID lparam )
 +{
 +    HeapFree(GetProcessHeap(), 0, ((LPSIC_ENTRY)ptr)->sSourceFile);
 +    SHFree(ptr);
 +    return TRUE;
 +}
 +
 +void SIC_Destroy(void)
 +{
 +    TRACE("\n");
 +
 +    EnterCriticalSection(&SHELL32_SicCS);
 +
 +    if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
 +
 +    sic_hdpa = NULL;
 +    ImageList_Destroy(ShellSmallIconList);
 +    ShellSmallIconList = 0;
 +    ImageList_Destroy(ShellBigIconList);
 +    ShellBigIconList = 0;
 +
 +    LeaveCriticalSection(&SHELL32_SicCS);
 +    //DeleteCriticalSection(&SHELL32_SicCS); //static
 +}
 +
 +/*****************************************************************************
 + * SIC_LoadOverlayIcon            [internal]
 + *
 + * Load a shell overlay icon and return its icon cache index.
 + */
 +static int SIC_LoadOverlayIcon(int icon_idx)
 +{
 +    WCHAR buffer[1024], wszIdx[8];
 +    HKEY hKeyShellIcons;
 +    LPCWSTR iconPath;
 +    int iconIdx;
 +
 +    static const WCHAR wszShellIcons[] = {
 +        'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
 +        'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
 +        'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0
 +    };
 +    static const WCHAR wszNumFmt[] = {'%','d',0};
 +
 +    iconPath = swShell32Name;    /* default: load icon from shell32.dll */
 +    iconIdx = icon_idx;
 +
 +    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS)
 +    {
 +        DWORD count = sizeof(buffer);
 +
 +        swprintf(wszIdx, wszNumFmt, icon_idx);
 +
 +        /* read icon path and index */
 +        if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS)
 +        {
 +        LPWSTR p = wcschr(buffer, ',');
 +
 +        if (p)
 +            *p++ = 0;
 +
 +        iconPath = buffer;
 +        iconIdx = _wtoi(p);
 +        }
 +
 +        RegCloseKey(hKeyShellIcons);
 +    }
 +
 +    return SIC_LoadIcon(iconPath, iconIdx, 0);
 +}
 +
 +/*************************************************************************
 + * Shell_GetImageLists            [SHELL32.71]
 + *
 + * PARAMETERS
 + *  imglist[1|2] [OUT] pointer which receives imagelist handles
 + *
 + */
 +BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
 +{    TRACE("(%p,%p)\n",lpBigList,lpSmallList);
 +    if (lpBigList)
 +    { *lpBigList = ShellBigIconList;
 +    }
 +    if (lpSmallList)
 +    { *lpSmallList = ShellSmallIconList;
 +    }
 +
 +    return TRUE;
 +}
 +/*************************************************************************
 + * PidlToSicIndex            [INTERNAL]
 + *
 + * PARAMETERS
 + *    sh    [IN]    IShellFolder
 + *    pidl    [IN]
 + *    bBigIcon [IN]
 + *    uFlags    [IN]    GIL_*
 + *    pIndex    [OUT]    index within the SIC
 + *
 + */
 +BOOL PidlToSicIndex (
 +    IShellFolder * sh,
 +    LPCITEMIDLIST pidl,
 +    BOOL bBigIcon,
 +    UINT uFlags,
 +    int * pIndex)
 +{
 +    CComPtr<IExtractIconW>        ei;
 +    WCHAR        szIconFile[MAX_PATH];    /* file containing the icon */
 +    INT        iSourceIndex;        /* index or resID(negated) in this file */
 +    BOOL        ret = FALSE;
 +    UINT        dwFlags = 0;
 +    int        iShortcutDefaultIndex = INVALID_INDEX;
 +
 +    TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
 +
 +    if (SUCCEEDED (sh->GetUIObjectOf(0, 1, &pidl, IID_NULL_PPV_ARG(IExtractIconW, &ei))))
 +    {
 +      if (SUCCEEDED(ei->GetIconLocation(uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
 +      {
 +        *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
 +        ret = TRUE;
 +      }
 +    }
 +
 +    if (INVALID_INDEX == *pIndex)    /* default icon when failed */
 +    {
 +      if (0 == (uFlags & GIL_FORSHORTCUT))
 +      {
 +        *pIndex = 0;
 +      }
 +      else
 +      {
 +        if (INVALID_INDEX == iShortcutDefaultIndex)
 +        {
 +          iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT);
 +        }
 +        *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0);
 +      }
 +    }
 +
 +    return ret;
 +
 +}
 +
 +/*************************************************************************
 + * SHMapPIDLToSystemImageListIndex    [SHELL32.77]
 + *
 + * PARAMETERS
 + *    sh    [IN]        pointer to an instance of IShellFolder
 + *    pidl    [IN]
 + *    pIndex    [OUT][OPTIONAL]    SIC index for big icon
 + *
 + */
 +int WINAPI SHMapPIDLToSystemImageListIndex(
 +    IShellFolder *sh,
 +    LPCITEMIDLIST pidl,
 +    int *pIndex)
 +{
 +    int Index;
 +    UINT uGilFlags = 0;
 +
 +    TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex);
 +    pdump(pidl);
 +
 +    if (SHELL_IsShortcut(pidl))
 +        uGilFlags |= GIL_FORSHORTCUT;
 +
 +    if (pIndex)
 +        if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex))
 +            *pIndex = -1;
 +
 +    if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index))
 +        return -1;
 +
 +    return Index;
 +}
 +
 +/*************************************************************************
 + * SHMapIDListToImageListIndexAsync  [SHELL32.148]
 + */
 +EXTERN_C HRESULT WINAPI SHMapIDListToImageListIndexAsync(IShellTaskScheduler *pts, IShellFolder *psf,
 +                                                LPCITEMIDLIST pidl, UINT flags,
 +                                                PFNASYNCICONTASKBALLBACK pfn, void *pvData, void *pvHint,
 +                                                int *piIndex, int *piIndexSel)
 +{
 +    FIXME("(%p, %p, %p, 0x%08x, %p, %p, %p, %p, %p)\n",
 +            pts, psf, pidl, flags, pfn, pvData, pvHint, piIndex, piIndexSel);
 +    return E_FAIL;
 +}
 +
 +/*************************************************************************
 + * Shell_GetCachedImageIndex        [SHELL32.72]
 + *
 + */
 +INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, UINT bSimulateDoc)
 +{
 +    INT ret, len;
 +    LPWSTR szTemp;
 +
 +    WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc);
 +
 +    len = MultiByteToWideChar( CP_ACP, 0, szPath, -1, NULL, 0 );
 +    szTemp = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
 +    MultiByteToWideChar( CP_ACP, 0, szPath, -1, szTemp, len );
 +
 +    ret = SIC_GetIconIndex( szTemp, nIndex, 0 );
 +
 +    HeapFree( GetProcessHeap(), 0, szTemp );
 +
 +    return ret;
 +}
 +
 +INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, UINT bSimulateDoc)
 +{
 +    WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc);
 +
 +    return SIC_GetIconIndex(szPath, nIndex, 0);
 +}
 +
 +EXTERN_C INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc)
 +{    if( SHELL_OsIsUnicode())
 +      return Shell_GetCachedImageIndexW((LPCWSTR)szPath, nIndex, bSimulateDoc);
 +    return Shell_GetCachedImageIndexA((LPCSTR)szPath, nIndex, bSimulateDoc);
 +}
 +
 +/*************************************************************************
 + * ExtractIconExW            [SHELL32.@]
 + * RETURNS
 + *  0 no icon found
 + *  -1 file is not valid
 + *  or number of icons extracted
 + */
 +UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
 +{
 +    /* get entry point of undocumented function PrivateExtractIconExW() in user32 */
 +#if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
 +    static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
 +
 +    if (!PrivateExtractIconExW) {
 +        HMODULE hUser32 = GetModuleHandleA("user32");
 +        PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
 +
 +        if (!PrivateExtractIconExW)
 +        return 0;
 +    }
 +#endif
 +
 +    TRACE("%s %i %p %p %i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons);
 +
 +    return PrivateExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
 +}
 +
 +/*************************************************************************
 + * ExtractIconExA            [SHELL32.@]
 + */
 +UINT WINAPI ExtractIconExA(LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
 +{
 +    UINT ret = 0;
 +    INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
 +    LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +
 +    TRACE("%s %i %p %p %i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
 +
 +    if (lpwstrFile)
 +    {
 +        MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
 +        ret = ExtractIconExW(lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
 +        HeapFree(GetProcessHeap(), 0, lpwstrFile);
 +    }
 +    return ret;
 +}
 +
 +/*************************************************************************
 + *                ExtractAssociatedIconA (SHELL32.@)
 + *
 + * Return icon for given file (either from file itself or from associated
 + * executable) and patch parameters if needed.
 + */
 +HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIcon)
 +{
 +    HICON hIcon = NULL;
 +    INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0);
 +    /* Note that we need to allocate MAX_PATH, since we are supposed to fill
 +     * the correct executable if there is no icon in lpIconPath directly.
 +     * lpIconPath itself is supposed to be large enough, so make sure lpIconPathW
 +     * is large enough too. Yes, I am puking too.
 +     */
 +    LPWSTR lpIconPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
 +
 +    TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon);
 +
 +    if (lpIconPathW)
 +    {
 +        MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, lpIconPathW, len);
 +        hIcon = ExtractAssociatedIconW(hInst, lpIconPathW, lpiIcon);
 +        WideCharToMultiByte(CP_ACP, 0, lpIconPathW, -1, lpIconPath, MAX_PATH , NULL, NULL);
 +        HeapFree(GetProcessHeap(), 0, lpIconPathW);
 +    }
 +    return hIcon;
 +}
 +
 +/*************************************************************************
 + *                ExtractAssociatedIconW (SHELL32.@)
 + *
 + * Return icon for given file (either from file itself or from associated
 + * executable) and patch parameters if needed.
 + */
 +HICON WINAPI ExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon)
 +{
 +    HICON hIcon = NULL;
 +    WORD wDummyIcon = 0;
 +
 +    TRACE("%p %s %p\n", hInst, debugstr_w(lpIconPath), lpiIcon);
 +
 +    if(lpiIcon == NULL)
 +        lpiIcon = &wDummyIcon;
 +
 +    hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
 +
 +    if( hIcon < (HICON)2 )
 +    { if( hIcon == (HICON)1 ) /* no icons found in given file */
 +      { WCHAR tempPath[MAX_PATH];
 +        HINSTANCE uRet = FindExecutableW(lpIconPath,NULL,tempPath);
 +
 +        if( uRet > (HINSTANCE)32 && tempPath[0] )
 +        { wcscpy(lpIconPath,tempPath);
 +          hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
 +          if( hIcon > (HICON)2 )
 +            return hIcon;
 +        }
 +      }
 +
 +      if( hIcon == (HICON)1 )
 +        *lpiIcon = 2;   /* MSDOS icon - we found .exe but no icons in it */
 +      else
 +        *lpiIcon = 6;   /* generic icon - found nothing */
 +
 +      if (GetModuleFileNameW(hInst, lpIconPath, MAX_PATH))
 +        hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(*lpiIcon));
 +    }
 +    return hIcon;
 +}
 +
 +/*************************************************************************
 + *                ExtractAssociatedIconExW (SHELL32.@)
 + *
 + * Return icon for given file (either from file itself or from associated
 + * executable) and patch parameters if needed.
 + */
 +EXTERN_C HICON WINAPI ExtractAssociatedIconExW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
 +{
 +  FIXME("%p %s %p %p): stub\n", hInst, debugstr_w(lpIconPath), lpiIconIdx, lpiIconId);
 +  return 0;
 +}
 +
 +/*************************************************************************
 + *                ExtractAssociatedIconExA (SHELL32.@)
 + *
 + * Return icon for given file (either from file itself or from associated
 + * executable) and patch parameters if needed.
 + */
 +EXTERN_C HICON WINAPI ExtractAssociatedIconExA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
 +{
 +  HICON ret;
 +  INT len = MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, NULL, 0 );
 +  LPWSTR lpwstrFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
 +
 +  TRACE("%p %s %p %p)\n", hInst, lpIconPath, lpiIconIdx, lpiIconId);
 +
 +  MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, lpwstrFile, len );
 +  ret = ExtractAssociatedIconExW(hInst, lpwstrFile, lpiIconIdx, lpiIconId);
 +  HeapFree(GetProcessHeap(), 0, lpwstrFile);
 +  return ret;
 +}
 +
 +
 +/****************************************************************************
 + * SHDefExtractIconW        [SHELL32.@]
 + */
 +HRESULT WINAPI SHDefExtractIconW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
 +                                 HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
 +{
 +    UINT ret;
 +    HICON hIcons[2];
 +    WARN("%s %d 0x%08x %p %p %d, semi-stub\n", debugstr_w(pszIconFile), iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
 +
 +    ret = PrivateExtractIconsW(pszIconFile, iIndex, nIconSize, nIconSize, hIcons, NULL, 2, LR_DEFAULTCOLOR);
 +    /* FIXME: deal with uFlags parameter which contains GIL_ flags */
 +    if (ret == 0xFFFFFFFF)
 +      return E_FAIL;
 +    if (ret > 0) {
 +      if (phiconLarge)
 +        *phiconLarge = hIcons[0];
 +      else
 +        DestroyIcon(hIcons[0]);
 +      if (phiconSmall)
 +        *phiconSmall = hIcons[1];
 +      else
 +        DestroyIcon(hIcons[1]);
 +      return S_OK;
 +    }
 +    return S_FALSE;
 +}
 +
 +/****************************************************************************
 + * SHDefExtractIconA        [SHELL32.@]
 + */
 +HRESULT WINAPI SHDefExtractIconA(LPCSTR pszIconFile, int iIndex, UINT uFlags,
 +                                 HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
 +{
 +  HRESULT ret;
 +  INT len = MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, NULL, 0);
 +  LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +
 +  TRACE("%s %d 0x%08x %p %p %d\n", pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
 +
 +  MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, lpwstrFile, len);
 +  ret = SHDefExtractIconW(lpwstrFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
 +  HeapFree(GetProcessHeap(), 0, lpwstrFile);
 +  return ret;
 +}
 +
 +/****************************************************************************
 + * SHGetIconOverlayIndexA    [SHELL32.@]
 + *
 + * Returns the index of the overlay icon in the system image list.
 + */
 +EXTERN_C INT WINAPI SHGetIconOverlayIndexA(LPCSTR pszIconPath, INT iIconIndex)
 +{
 +  FIXME("%s, %d\n", debugstr_a(pszIconPath), iIconIndex);
 +
 +  return -1;
 +}
 +
 +/****************************************************************************
 + * SHGetIconOverlayIndexW    [SHELL32.@]
 + *
 + * Returns the index of the overlay icon in the system image list.
 + */
 +EXTERN_C INT WINAPI SHGetIconOverlayIndexW(LPCWSTR pszIconPath, INT iIconIndex)
 +{
 +  FIXME("%s, %d\n", debugstr_w(pszIconPath), iIconIndex);
 +
 +  return -1;
 +}
Simple merge
index 30dab9e,0000000..bbecaea
mode 100644,000000..100644
--- /dev/null
@@@ -1,581 -1,0 +1,608 @@@
 +/*
 + *    Shell Folder stuff
 + *
 + *    Copyright 1997            Marcus Meissner
 + *    Copyright 1998, 1999, 2002    Juergen Schmied
 + *
 + *    IShellFolder2 and related interfaces
 + *
 + * 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(shell);
 +
 +static const WCHAR wszDotShellClassInfo[] = {
 +    '.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0};
 +
 +/***************************************************************************
 + *  SHELL32_GetCustomFolderAttribute (internal function)
 + *
 + * Gets a value from the folder's desktop.ini file, if one exists.
 + *
 + * PARAMETERS
 + *  pidl          [I] Folder containing the desktop.ini file.
 + *  pwszHeading   [I] Heading in .ini file.
 + *  pwszAttribute [I] Attribute in .ini file.
 + *  pwszValue     [O] Buffer to store value into.
 + *  cchValue      [I] Size in characters including NULL of buffer pointed to
 + *                    by pwszValue.
 + *
 + *  RETURNS
 + *    TRUE if returned non-NULL value.
 + *    FALSE otherwise.
 + */
 +static BOOL __inline SHELL32_GetCustomFolderAttributeFromPath(
 +    LPWSTR pwszFolderPath, LPCWSTR pwszHeading, LPCWSTR pwszAttribute,
 +    LPWSTR pwszValue, DWORD cchValue)
 +{
 +    static const WCHAR wszDesktopIni[] =
 +            {'d','e','s','k','t','o','p','.','i','n','i',0};
 +    static const WCHAR wszDefault[] = {0};
 +
 +    PathAddBackslashW(pwszFolderPath);
 +    PathAppendW(pwszFolderPath, wszDesktopIni);
 +    return GetPrivateProfileStringW(pwszHeading, pwszAttribute, wszDefault,
 +                                    pwszValue, cchValue, pwszFolderPath);
 +}
 +
 +BOOL SHELL32_GetCustomFolderAttribute(
 +    LPCITEMIDLIST pidl, LPCWSTR pwszHeading, LPCWSTR pwszAttribute,
 +    LPWSTR pwszValue, DWORD cchValue)
 +{
 +    DWORD dwAttrib = FILE_ATTRIBUTE_SYSTEM;
 +    WCHAR wszFolderPath[MAX_PATH];
 +
 +    /* Hack around not having system attribute on non-Windows file systems */
 +    if (0)
 +        dwAttrib = _ILGetFileAttributes(pidl, NULL, 0);
 +
 +    if (dwAttrib & FILE_ATTRIBUTE_SYSTEM)
 +    {
 +        if (!SHGetPathFromIDListW(pidl, wszFolderPath))
 +            return FALSE;
 +
 +        return SHELL32_GetCustomFolderAttributeFromPath(wszFolderPath, pwszHeading,
 +                                                pwszAttribute, pwszValue, cchValue);
 +    }
 +    return FALSE;
 +}
 +
++BOOL SHELL32_GetCustomFolderAttributes(
++    LPCITEMIDLIST pidl, LPCWSTR pwszHeading,
++    LPWSTR pwszValue, DWORD cchValue)
++{
++    DWORD dwAttrib = FILE_ATTRIBUTE_SYSTEM;
++    WCHAR wszFolderPath[MAX_PATH];
++
++    /* Hack around not having system attribute on non-Windows file systems */
++    if (0)
++        dwAttrib = _ILGetFileAttributes(pidl, NULL, 0);
++
++    if (dwAttrib & FILE_ATTRIBUTE_SYSTEM)
++    {
++        if (!SHGetPathFromIDListW(pidl, wszFolderPath))
++            return FALSE;
++
++        static const WCHAR wszDesktopIni[] =
++                {'d','e','s','k','t','o','p','.','i','n','i',0};
++
++        PathAddBackslashW(wszFolderPath);
++        PathAppendW(wszFolderPath, wszDesktopIni);
++        return GetPrivateProfileSectionW(pwszHeading, pwszValue, cchValue, wszFolderPath);
++    }
++    return FALSE;
++}
++
++
 +/***************************************************************************
 + *  GetNextElement (internal function)
 + *
 + * Gets a part of a string till the first backslash.
 + *
 + * PARAMETERS
 + *  pszNext [IN] string to get the element from
 + *  pszOut  [IN] pointer to buffer which receives string
 + *  dwOut   [IN] length of pszOut
 + *
 + *  RETURNS
 + *    LPSTR pointer to first, not yet parsed char
 + */
 +
 +LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut)
 +{
 +    LPCWSTR pszTail = pszNext;
 +    DWORD dwCopy;
 +
 +    TRACE ("(%s %p 0x%08x)\n", debugstr_w (pszNext), pszOut, dwOut);
 +
 +    *pszOut = 0x0000;
 +
 +    if (!pszNext || !*pszNext)
 +        return NULL;
 +
 +    while (*pszTail && (*pszTail != (WCHAR) '\\'))
 +        pszTail++;
 +
 +    dwCopy = pszTail - pszNext + 1;
 +    lstrcpynW (pszOut, pszNext, (dwOut < dwCopy) ? dwOut : dwCopy);
 +
 +    if (*pszTail)
 +        pszTail++;
 +    else
 +        pszTail = NULL;
 +
 +    TRACE ("--(%s %s 0x%08x %p)\n", debugstr_w (pszNext), debugstr_w (pszOut), dwOut, pszTail);
 +    return pszTail;
 +}
 +
 +HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
 +                  LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes)
 +{
 +    HRESULT hr = E_INVALIDARG;
 +    LPITEMIDLIST pidlIn = pidlInOut ? *pidlInOut : NULL;
 +    LPITEMIDLIST pidlOut = NULL;
 +    LPITEMIDLIST pidlTemp = NULL;
 +    CComPtr<IShellFolder> psfChild;
 +
 +    TRACE ("(%p, %p, %p, %s)\n", psf, pbc, pidlIn, debugstr_w (szNext));
 +
 +    /* get the shellfolder for the child pidl and let it analyse further */
 +    hr = psf->BindToObject(pidlIn, pbc, IID_PPV_ARG(IShellFolder, &psfChild));
 +    if (FAILED(hr))
 +        return hr;
 +
 +    hr = psfChild->ParseDisplayName(hwndOwner, pbc, szNext, pEaten, &pidlOut, pdwAttributes);
 +    if (FAILED(hr))
 +        return hr;
 +
 +    pidlTemp = ILCombine (pidlIn, pidlOut);
 +    if (!pidlTemp)
 +    {
 +        hr = E_OUTOFMEMORY;
 +        if (pidlOut)
 +            ILFree(pidlOut);
 +        return hr;
 +    }
 +
 +    if (pidlOut)
 +        ILFree (pidlOut);
 +
 +    if (pidlIn)
 +        ILFree (pidlIn);
 +
 +    *pidlInOut = pidlTemp;
 +
 +    TRACE ("-- pidl=%p ret=0x%08x\n", pidlInOut ? *pidlInOut : NULL, hr);
 +    return S_OK;
 +}
 +
 +/***********************************************************************
 + *    SHELL32_CoCreateInitSF
 + *
 + * Creates a shell folder and initializes it with a pidl and a root folder
 + * via IPersistFolder3 or IPersistFolder.
 + *
 + * NOTES
 + *   pathRoot can be NULL for Folders being a drive.
 + *   In this case the absolute path is built from pidlChild (eg. C:)
 + */
 +static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
 +                LPCITEMIDLIST pidlChild, REFCLSID clsid, LPVOID * ppvOut)
 +{
 +    HRESULT hr;
 +    IShellFolder* pShellFolder = NULL;
 +
 +    TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild);
 +
 +    hr = SHCoCreateInstance(NULL, &clsid, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
 +    if (SUCCEEDED (hr))
 +    {
 +        LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
 +        IPersistFolder *pPF;
 +        IPersistFolder3 *ppf;
 +
 +        if (_ILIsFolder(pidlChild) &&
 +            SUCCEEDED(pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder3, &ppf))))
 +        {
 +            PERSIST_FOLDER_TARGET_INFO ppfti;
 +
 +            ZeroMemory (&ppfti, sizeof (ppfti));
 +
 +            /* fill the PERSIST_FOLDER_TARGET_INFO */
 +            ppfti.dwAttributes = -1;
 +            ppfti.csidl = -1;
 +
 +            /* build path */
 +            if (pathRoot)
 +            {
 +                lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
 +                PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */
 +            }
 +
 +            if (pidlChild)
 +            {
 +                int len = wcslen(ppfti.szTargetParsingName);
 +
 +                if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len))
 +                    hr = E_INVALIDARG;
 +            }
 +
 +            ppf->InitializeEx(NULL, pidlAbsolute, &ppfti);
 +            ppf->Release();
 +        }
 +        else if (SUCCEEDED((hr = pShellFolder->QueryInterface(IID_PPV_ARG(IPersistFolder, &pPF)))))
 +        {
 +            pPF->Initialize(pidlAbsolute);
 +            pPF->Release();
 +        }
 +        ILFree (pidlAbsolute);
 +    }
 +
 +    *ppvOut = pShellFolder;
 +
 +    TRACE ("-- (%p) ret=0x%08x\n", *ppvOut, hr);
 +
 +    return hr;
 +}
 +
 +/***********************************************************************
 + *    SHELL32_BindToChild [Internal]
 + *
 + * Common code for IShellFolder_BindToObject.
 + *
 + * PARAMS
 + *  pidlRoot     [I] The parent shell folder's absolute pidl.
 + *  pathRoot     [I] Absolute dos path of the parent shell folder.
 + *  pidlComplete [I] PIDL of the child. Relative to pidlRoot.
 + *  riid         [I] GUID of the interface, which ppvOut shall be bound to.
 + *  ppvOut       [O] A reference to the child's interface (riid).
 + *
 + * NOTES
 + *  pidlComplete has to contain at least one non empty SHITEMID.
 + *  This function makes special assumptions on the shell namespace, which
 + *  means you probably can't use it for your IShellFolder implementation.
 + */
 +HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
 +                             LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
 +{
 +    GUID const *clsid;
 +    IShellFolder *pSF;
 +    HRESULT hr;
 +    LPITEMIDLIST pidlChild;
 +
 +    if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb)
 +        return E_INVALIDARG;
 +
 +    *ppvOut = NULL;
 +
 +    pidlChild = ILCloneFirst (pidlComplete);
 +
 +    if ((clsid = _ILGetGUIDPointer (pidlChild))) {
 +        /* virtual folder */
 +        hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, *clsid, (LPVOID *)&pSF);
 +    } else {
 +        /* file system folder */
 +        CLSID clsidFolder = CLSID_ShellFSFolder;
 +        static const WCHAR wszCLSID[] = {'C','L','S','I','D',0};
 +        WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail = wszFolderPath;
 +
 +        /* see if folder CLSID should be overridden by desktop.ini file */
 +        if (pathRoot) {
 +            lstrcpynW(wszFolderPath, pathRoot, MAX_PATH);
 +            pwszPathTail = PathAddBackslashW(wszFolderPath);
 +        }
 +
 +        _ILSimpleGetTextW(pidlChild,pwszPathTail,MAX_PATH - (int)(pwszPathTail - wszFolderPath));
 +
 +        if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath,
 +            wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID))
 +            CLSIDFromString (wszCLSIDValue, &clsidFolder);
 +
 +        hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild,
 +                                     clsidFolder, (LPVOID *)&pSF);
 +    }
 +    ILFree (pidlChild);
 +
 +    if (SUCCEEDED (hr)) {
 +        if (_ILIsPidlSimple (pidlComplete)) {
 +            /* no sub folders */
 +            hr = pSF->QueryInterface(riid, ppvOut);
 +        } else {
 +            /* go deeper */
 +            hr = pSF->BindToObject(ILGetNext (pidlComplete), NULL, riid, ppvOut);
 +        }
 +        pSF->Release();
 +    }
 +
 +    TRACE ("-- returning (%p) %08x\n", *ppvOut, hr);
 +
 +    return hr;
 +}
 +
 +/***********************************************************************
 + *    SHELL32_GetDisplayNameOfChild
 + *
 + * Retrieves the display name of a child object of a shellfolder.
 + *
 + * For a pidl eg. [subpidl1][subpidl2][subpidl3]:
 + * - it binds to the child shellfolder [subpidl1]
 + * - asks it for the displayname of [subpidl2][subpidl3]
 + *
 + * Is possible the pidl is a simple pidl. In this case it asks the
 + * subfolder for the displayname of an empty pidl. The subfolder
 + * returns the own displayname eg. "::{guid}". This is used for
 + * virtual folders with the registry key WantsFORPARSING set.
 + */
 +HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf,
 +                       LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut, DWORD dwOutLen)
 +{
 +    LPITEMIDLIST pidlFirst;
 +    HRESULT hr = E_INVALIDARG;
 +
 +    TRACE ("(%p)->(pidl=%p 0x%08x %p 0x%08x)\n", psf, pidl, dwFlags, szOut, dwOutLen);
 +    pdump (pidl);
 +
 +    pidlFirst = ILCloneFirst(pidl);
 +    if (pidlFirst)
 +    {
 +        IShellFolder *psfChild;
 +
 +        hr = psf->BindToObject(pidlFirst, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
 +        if (SUCCEEDED (hr))
 +        {
 +            STRRET strTemp;
 +            LPITEMIDLIST pidlNext = ILGetNext (pidl);
 +
 +            hr = psfChild->GetDisplayNameOf(pidlNext, dwFlags, &strTemp);
 +            if (SUCCEEDED (hr))
 +            {
 +                if(!StrRetToStrNW (szOut, dwOutLen, &strTemp, pidlNext))
 +                    hr = E_FAIL;
 +            }
 +            psfChild->Release();
 +        }
 +        ILFree (pidlFirst);
 +    } else
 +        hr = E_OUTOFMEMORY;
 +
 +    TRACE ("-- ret=0x%08x %s\n", hr, debugstr_w(szOut));
 +
 +    return hr;
 +}
 +
 +/***********************************************************************
 + *  SHELL32_GetItemAttributes
 + *
 + * NOTES
 + * Observed values:
 + *  folder:    0xE0000177    FILESYSTEM | HASSUBFOLDER | FOLDER
 + *  file:    0x40000177    FILESYSTEM
 + *  drive:    0xf0000144    FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
 + *  mycomputer:    0xb0000154    HASSUBFOLDER | FOLDER | FILESYSANCESTOR
 + *  (seems to be default for shell extensions if no registry entry exists)
 + *
 + * win2k:
 + *  folder:    0xF0400177      FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER
 + *  file:      0x40400177      FILESYSTEM | CANMONIKER
 + *  drive      0xF0400154      FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL)
 + *
 + * According to the MSDN documentation this function should not set flags. It claims only to reset flags when necessary.
 + * However it turns out the native shell32.dll _sets_ flags in several cases - so do we.
 + */
 +HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
 +{
 +    DWORD dwAttributes;
 +    BOOL has_guid;
 +    static const DWORD dwSupportedAttr=
 +                          SFGAO_CANCOPY |           /*0x00000001 */
 +                          SFGAO_CANMOVE |           /*0x00000002 */
 +                          SFGAO_CANLINK |           /*0x00000004 */
 +                          SFGAO_CANRENAME |         /*0x00000010 */
 +                          SFGAO_CANDELETE |         /*0x00000020 */
 +                          SFGAO_HASPROPSHEET |      /*0x00000040 */
 +                          SFGAO_DROPTARGET |        /*0x00000100 */
 +                          SFGAO_LINK |              /*0x00010000 */
 +                          SFGAO_READONLY |          /*0x00040000 */
 +                          SFGAO_HIDDEN |            /*0x00080000 */
 +                          SFGAO_FILESYSANCESTOR |   /*0x10000000 */
 +                          SFGAO_FOLDER |            /*0x20000000 */
 +                          SFGAO_FILESYSTEM |        /*0x40000000 */
 +                          SFGAO_HASSUBFOLDER;       /*0x80000000 */
 +
 +    TRACE ("0x%08x\n", *pdwAttributes);
 +
 +    if (*pdwAttributes & ~dwSupportedAttr)
 +    {
 +        WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr));
 +        *pdwAttributes &= dwSupportedAttr;
 +    }
 +
 +    has_guid = _ILGetGUIDPointer(pidl) != NULL;
 +
 +    dwAttributes = *pdwAttributes;
 +
 +    if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes))
 +        *pdwAttributes = dwAttributes;
 +    else if (_ILGetDataPointer(pidl))
 +    {
 +        dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
 +
 +        if (!dwAttributes && has_guid)
 +        {
 +            WCHAR path[MAX_PATH];
 +            STRRET strret;
 +
 +            /* File attributes are not present in the internal PIDL structure, so get them from the file system. */
 +
 +            HRESULT hr = psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
 +
 +            if (SUCCEEDED(hr))
 +            {
 +                hr = StrRetToBufW(&strret, pidl, path, MAX_PATH);
 +
 +                /* call GetFileAttributes() only for file system paths, not for parsing names like "::{...}" */
 +                if (SUCCEEDED(hr) && path[0]!=':')
 +                    dwAttributes = GetFileAttributesW(path);
 +            }
 +        }
 +
 +        /* Set common attributes */
 +        *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE |
 +                          SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY;
 +
 +        if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
 +        {
 +            *pdwAttributes |=  (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
 +        }
 +        else
 +            *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
 +
 +        if (dwAttributes & FILE_ATTRIBUTE_HIDDEN)
 +            *pdwAttributes |=  SFGAO_HIDDEN;
 +        else
 +            *pdwAttributes &= ~SFGAO_HIDDEN;
 +
 +        if (dwAttributes & FILE_ATTRIBUTE_READONLY)
 +            *pdwAttributes |=  SFGAO_READONLY;
 +        else
 +            *pdwAttributes &= ~SFGAO_READONLY;
 +
 +        if (SFGAO_LINK & *pdwAttributes)
 +        {
 +            char ext[MAX_PATH];
 +
 +            if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk"))
 +            *pdwAttributes &= ~SFGAO_LINK;
 +        }
 +
 +        if (SFGAO_HASSUBFOLDER & *pdwAttributes)
 +        {
 +            IShellFolder *psf2;
 +            if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2))))
 +            {
 +                IEnumIDList *pEnumIL = NULL;
 +                if (SUCCEEDED(psf2->EnumObjects(0, SHCONTF_FOLDERS, &pEnumIL)))
 +                {
 +                    if (pEnumIL->Skip(1) != S_OK)
 +                        *pdwAttributes &= ~SFGAO_HASSUBFOLDER;
 +                    pEnumIL->Release();
 +                }
 +                psf2->Release();
 +            }
 +        }
 +    } else
 +        *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
 +
 +    TRACE ("-- 0x%08x\n", *pdwAttributes);
 +    return S_OK;
 +}
 +
 +/***********************************************************************
 + *  SHELL32_CompareIDs
 + */
 +HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 +{
 +    int type1,
 +      type2;
 +    char szTemp1[MAX_PATH];
 +    char szTemp2[MAX_PATH];
 +    HRESULT nReturn;
 +    LPITEMIDLIST firstpidl,
 +      nextpidl1,
 +      nextpidl2;
 +    IShellFolder *psf;
 +
 +    /* test for empty pidls */
 +    BOOL isEmpty1 = _ILIsDesktop (pidl1);
 +    BOOL isEmpty2 = _ILIsDesktop (pidl2);
 +
 +    if (isEmpty1 && isEmpty2)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 );
 +    if (isEmpty1)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 );
 +    if (isEmpty2)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 );
 +
 +    /* test for different types. Sort order is the PT_* constant */
 +    type1 = _ILGetDataPointer (pidl1)->type;
 +    type2 = _ILGetDataPointer (pidl2)->type;
 +    if (type1 < type2)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 );
 +    else if (type1 > type2)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 );
 +
 +    /* test for name of pidl */
 +    _ILSimpleGetText (pidl1, szTemp1, MAX_PATH);
 +    _ILSimpleGetText (pidl2, szTemp2, MAX_PATH);
 +    nReturn = lstrcmpiA (szTemp1, szTemp2);
 +    if (nReturn < 0)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 );
 +    else if (nReturn > 0)
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 );
 +
 +    /* test of complex pidls */
 +    firstpidl = ILCloneFirst (pidl1);
 +    nextpidl1 = ILGetNext (pidl1);
 +    nextpidl2 = ILGetNext (pidl2);
 +
 +    /* optimizing: test special cases and bind not deeper */
 +    /* the deeper shellfolder would do the same */
 +    isEmpty1 = _ILIsDesktop (nextpidl1);
 +    isEmpty2 = _ILIsDesktop (nextpidl2);
 +
 +    if (isEmpty1 && isEmpty2) {
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 );
 +    } else if (isEmpty1) {
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 );
 +    } else if (isEmpty2) {
 +        return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 );
 +    /* optimizing end */
 +    } else if (SUCCEEDED (iface->BindToObject(firstpidl, NULL, IID_PPV_ARG(IShellFolder, &psf)))) {
 +    nReturn = psf->CompareIDs(lParam, nextpidl1, nextpidl2);
 +    psf->Release();
 +    }
 +    ILFree (firstpidl);
 +    return nReturn;
 +}
 +
 +/***********************************************************************
 + *  SHCreateLinks
 + *
 + *   Undocumented.
 + */
 +HRESULT WINAPI SHCreateLinks( HWND hWnd, LPCSTR lpszDir, LPDATAOBJECT lpDataObject,
 +                              UINT uFlags, LPITEMIDLIST *lppidlLinks)
 +{
 +    FIXME("%p %s %p %08x %p\n",hWnd,lpszDir,lpDataObject,uFlags,lppidlLinks);
 +    return E_NOTIMPL;
 +}
 +
 +/***********************************************************************
 + *  SHOpenFolderAndSelectItems
 + *
 + *   Unimplemented.
 + */
 +EXTERN_C HRESULT
 +WINAPI
 +SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder,
 +                           UINT cidl,
 +                           PCUITEMID_CHILD_ARRAY apidl,
 +                           DWORD dwFlags)
 +{
 +    FIXME("SHOpenFolderAndSelectItems() stub\n");
 +    return E_NOTIMPL;
 +}
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 0000000,63399d9..63399d9
mode 000000,100644..100644
--- /dev/null
index 0000000,49136dc..49136dc
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
diff --cc