- Create a new sublibrary for shell32 that will contain the implementation of CDesktopBrowser and desktop dde support. Link it to both shell32 and rshell. Also add a win8+ hack.
svn path=/trunk/; revision=68769
target_link_libraries(rshell
shellmenu
+ shelldesktop
atlnew
uuid
wine)
add_importlibs(rshell
+ browseui
uxtheme
shlwapi
advapi32
#include "shellmenu.h"
+extern "C"
HINSTANCE shell32_hInstance = NULL;
DWORD WINAPI WinList_Init(void)
@ stdcall CMenuSite_Constructor(ptr ptr);
@ stdcall CMenuBand_Constructor(ptr ptr);
@ stdcall CMergedFolder_Constructor(ptr ptr);
-@ stdcall ShellDDEInit(long);
\ No newline at end of file
+@ stdcall ShellDDEInit(long);
+@ stdcall SHCreateDesktop(ptr);
+@ stdcall SHDesktopMessageLoop(ptr);
PROJECT(SHELL)
+add_subdirectory(shelldesktop)
add_subdirectory(shellmenu)
set_cpp(WITH_RUNTIME)
list(APPEND SOURCE
CIDLDataObj.cpp
CQueryAssociations.cpp
- dde.cpp
debughlp.cpp
- CDesktopBrowser.cpp
dialogs/dialogs.cpp
dialogs/drive.cpp
dialogs/drvdefext.cpp
${CMAKE_CURRENT_BINARY_DIR}/shell32.def)
set_module_type(shell32 win32dll UNICODE HOTPATCHABLE)
-target_link_libraries(shell32 shellmenu atlnew wine uuid recyclebin)
+target_link_libraries(shell32 shellmenu shelldesktop atlnew wine uuid recyclebin)
add_delay_importlibs(shell32 uxtheme ole32 userenv version fmifs)
add_importlibs(shell32 advapi32 browseui gdi32 user32 powrprof comctl32 comdlg32 shdocvw shlwapi devmgr winspool winmm msvcrt kernel32 ntdll)
add_pch(shell32 precomp.h SOURCE)
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "precomp.h"
+#include "shelldesktop.h"
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
SetShellWindowEx(hWnd, FindDesktopListView());
+#if 1
+ /* A Windows8+ specific hack */
+ ::ShowWindow(hWndShellView, SW_SHOW);
+ ::ShowWindow(FindDesktopListView(), SW_SHOW);
+#endif
+
return TRUE;
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "precomp.h"
+#include "shelldesktop.h"
#include <ddeml.h>
#include <strsafe.h>
+++ /dev/null
-/*
- * Shell Desktop
- *
- * Copyright 2008 Thomas Bluemel
- *
- * 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 "shellmenu.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(desktop);
-
-#define SHDESK_TAG 'KSED'
-
-static const WCHAR szProgmanClassName [] = L"Progman";
-static const WCHAR szProgmanWindowName [] = L"Program Manager";
-
-class CDesktopBrowser :
- public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IShellBrowser,
- public ICommDlgBrowser,
- public IServiceProvider
-{
-public:
- DWORD Tag;
-private:
- HWND hWnd;
- HWND hWndShellView;
- HWND hWndDesktopListView;
- CComPtr<IShellDesktopTray> ShellDesk;
- CComPtr<IShellView> DesktopView;
- IShellBrowser *DefaultShellBrowser;
- LPITEMIDLIST pidlDesktopDirectory;
- LPITEMIDLIST pidlDesktop;
-public:
- CDesktopBrowser();
- ~CDesktopBrowser();
- HRESULT Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx);
- HWND FindDesktopListView();
- BOOL CreateDeskWnd();
- HWND DesktopGetWindowControl(IN UINT id);
- static LRESULT CALLBACK ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam);
- static BOOL MessageLoop();
-
- // *** 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(struct IShellView **ppshv);
- virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv);
- virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags);
-
- // *** ICommDlgBrowser methods ***
- virtual HRESULT STDMETHODCALLTYPE OnDefaultCommand(struct IShellView *ppshv);
- virtual HRESULT STDMETHODCALLTYPE OnStateChange(struct IShellView *ppshv, ULONG uChange);
- virtual HRESULT STDMETHODCALLTYPE IncludeObject(struct IShellView *ppshv, LPCITEMIDLIST pidl);
-
- // *** IServiceProvider methods ***
- virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
-
- BEGIN_COM_MAP(CDesktopBrowser)
- COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
- COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
- COM_INTERFACE_ENTRY_IID(IID_ICommDlgBrowser, ICommDlgBrowser)
- COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
- END_COM_MAP()
-};
-
-CDesktopBrowser::CDesktopBrowser()
-{
- Tag = SHDESK_TAG;
- hWnd = NULL;
- hWndShellView = NULL;
- hWndDesktopListView = NULL;
- DefaultShellBrowser = NULL;
- pidlDesktopDirectory = NULL;
- pidlDesktop = NULL;
-}
-
-CDesktopBrowser::~CDesktopBrowser()
-{
- if (DesktopView.p != NULL)
- {
- if (hWndShellView != NULL)
- DesktopView->DestroyViewWindow();
-
- hWndShellView = NULL;
- hWndDesktopListView = NULL;
- }
-
- if (pidlDesktopDirectory != NULL)
- {
- ILFree(pidlDesktopDirectory);
- pidlDesktopDirectory = NULL;
- }
-
- if (pidlDesktop != NULL)
- {
- ILFree(pidlDesktop);
- pidlDesktop = NULL;
- }
-}
-
-HRESULT CDesktopBrowser::Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx)
-{
- CComPtr<IShellFolder> psfDesktopFolder;
- CSFV csfv;
- HRESULT hRet;
-
- hWnd = hWndx;
- ShellDesk = ShellDeskx;
- ShellDesk->AddRef();
-
- pidlDesktopDirectory = SHCloneSpecialIDList(hWnd, CSIDL_DESKTOPDIRECTORY, FALSE);
- hRet = SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlDesktop);
- if (FAILED(hRet))
- return hRet;
-
- hRet = SHGetDesktopFolder(&psfDesktopFolder);
- if (FAILED(hRet))
- return hRet;
-
- ZeroMemory(&csfv, sizeof(csfv));
- csfv.cbSize = sizeof(csfv);
- csfv.pshf = psfDesktopFolder;
- csfv.psvOuter = NULL;
-
- hRet = SHCreateShellFolderViewEx(&csfv, &DesktopView);
-
- return hRet;
-}
-
-static CDesktopBrowser *SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
-{
- IShellDesktopTray *ShellDesk;
- CComObject<CDesktopBrowser> *pThis;
- HRESULT hRet;
-
- ShellDesk = static_cast<IShellDesktopTray *>(lpCreateStruct->lpCreateParams);
- if (ShellDesk == NULL)
- {
- WARN("No IShellDesk interface provided!");
- return NULL;
- }
-
- pThis = new CComObject<CDesktopBrowser>;
- if (pThis == NULL)
- return NULL;
- pThis->AddRef();
-
- hRet = pThis->Initialize(hWnd, ShellDesk);
- if (FAILED(hRet))
- {
- pThis->Release();
- return NULL;
- }
-
- return pThis;
-}
-
-HWND CDesktopBrowser::FindDesktopListView()
-{
- return FindWindowExW(hWndShellView, NULL, WC_LISTVIEW, NULL);
-}
-
-BOOL CDesktopBrowser::CreateDeskWnd()
-{
- FOLDERSETTINGS fs;
- RECT rcClient;
- HRESULT hRet;
-
- if (!GetClientRect(hWnd, &rcClient))
- {
- return FALSE;
- }
-
- fs.ViewMode = FVM_ICON;
- fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
- hRet = DesktopView->CreateViewWindow(NULL, &fs, static_cast<IShellBrowser *>(this), &rcClient, &hWndShellView);
- if (!SUCCEEDED(hRet))
- return FALSE;
-
- SetShellWindowEx(hWnd, FindDesktopListView());
-
-#if 1
- /* A windows 8 specific hack */
- ::ShowWindow(hWndShellView, SW_SHOW);
- ::ShowWindow(FindDesktopListView(), SW_SHOW);
-#endif
-
- return TRUE;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *phwnd)
-{
- if (hWnd != NULL)
- {
- *phwnd = hWnd;
- return S_OK;
- }
-
- *phwnd = NULL;
- return E_UNEXPECTED;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::RemoveMenusSB(HMENU hmenuShared)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetStatusTextSB(LPCOLESTR lpszStatusText)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID)
-{
- return S_FALSE;
-}
-
-typedef HRESULT(WINAPI *SH_OPEN_NEW_FRAME)(LPITEMIDLIST pidl, IUnknown *paramC, long param10, long param14);
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
-{
- /* FIXME: Implement executing filebrowser.exe and somehow pass the pidl to it */
-
- /* Returning failure here will make windows 7 and 8 to use the default file browser */
- return E_FAIL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
-{
- return E_NOTIMPL;
-}
-
-HWND CDesktopBrowser::DesktopGetWindowControl(IN UINT id)
-{
- switch (id)
- {
- case FCW_TOOLBAR:
- case FCW_STATUS:
- case FCW_TREE:
- case FCW_PROGRESS:
- return NULL;
-
- default:
- return NULL;
- }
-
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd)
-{
- HWND hWnd;
-
- hWnd = DesktopGetWindowControl(id);
- if (hWnd != NULL)
- {
- *lphwnd = hWnd;
- return S_OK;
- }
-
- *lphwnd = NULL;
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
-{
- HWND hWnd;
-
- if (pret == NULL)
- return E_POINTER;
-
- hWnd = DesktopGetWindowControl(id);
- if (hWnd != NULL)
- {
- *pret = SendMessageW(hWnd, uMsg, wParam, lParam);
- return S_OK;
- }
-
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv)
-{
- *ppshv = DesktopView;
- if (DesktopView != NULL)
- DesktopView->AddRef();
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnViewWindowActive(IShellView *ppshv)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnDefaultCommand(IShellView *ppshv)
-{
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnStateChange(IShellView *ppshv, ULONG uChange)
-{
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::IncludeObject(IShellView *ppshv, LPCITEMIDLIST pidl)
-{
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv)
-{
- /* FIXME - handle guidService */
- return QueryInterface(riid, ppv);
-}
-
-BOOL CDesktopBrowser::MessageLoop()
-{
- MSG Msg;
- BOOL bRet;
-
- while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
- {
- if (bRet != -1)
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }
- }
-
- return TRUE;
-}
-
-LRESULT CALLBACK CDesktopBrowser::ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
-{
- CDesktopBrowser *pThis = NULL;
- LRESULT Ret = FALSE;
-
- if (uMsg != WM_NCCREATE)
- {
- pThis = reinterpret_cast<CDesktopBrowser*>(GetWindowLongPtrW(hwnd, 0));
- if (pThis == NULL)
- goto DefMsgHandler;
- }
-
- if (pThis != NULL || uMsg == WM_NCCREATE)
- {
- switch (uMsg)
- {
- case WM_ERASEBKGND:
- return (LRESULT) PaintDesktop(reinterpret_cast<HDC>(wParam));
-
- case WM_GETISHELLBROWSER:
- Ret = reinterpret_cast<LRESULT>(static_cast<IShellBrowser *>(pThis));
- break;
-
- case WM_SIZE:
- if (wParam == SIZE_MINIMIZED)
- {
- /* Hey, we're the desktop!!! */
- ShowWindow(hwnd,
- SW_RESTORE);
- }
- else
- {
-
- /* FIXME: Update work area */
-#if 0
- RECT rcDesktop;
-
- rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
- rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
- rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
- rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
-#endif
- }
- break;
-
- case WM_SYSCOLORCHANGE:
- case WM_SETTINGCHANGE:
- {
- if (uMsg == WM_SYSCOLORCHANGE || wParam == SPI_SETDESKWALLPAPER || wParam == 0)
- {
- if (pThis->hWndShellView != NULL)
- {
- /* Forward the message */
- SendMessageW(pThis->hWndShellView,
- uMsg,
- wParam,
- lParam);
- }
- }
- break;
- }
-
- case WM_CREATE:
- {
- pThis->ShellDesk->RegisterDesktopWindow(pThis->hWnd);
-
- if (!pThis->CreateDeskWnd())
- WARN("Could not create the desktop view control!\n");
- break;
- }
-
- case WM_NCCREATE:
- {
- LPCREATESTRUCT CreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
- pThis = SHDESK_Create(hwnd, CreateStruct);
- if (pThis == NULL)
- {
- WARN("Failed to create desktop structure\n");
- break;
- }
-
- SetWindowLongPtrW(hwnd,
- 0,
- reinterpret_cast<LONG_PTR>(pThis));
- Ret = TRUE;
- break;
- }
-
- case WM_NCDESTROY:
- {
- pThis->Release();
- break;
- }
-
- default:
- DefMsgHandler :
- Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
- break;
- }
- }
-
- return Ret;
-}
-
-static BOOL
-RegisterProgmanWindowClass(VOID)
-{
- WNDCLASSW wcProgman;
-
- wcProgman.style = CS_DBLCLKS;
- wcProgman.lpfnWndProc = CDesktopBrowser::ProgmanWindowProc;
- wcProgman.cbClsExtra = 0;
- wcProgman.cbWndExtra = sizeof(CDesktopBrowser *);
- wcProgman.hInstance = shell32_hInstance;
- wcProgman.hIcon = NULL;
- wcProgman.hCursor = LoadCursorW(NULL, IDC_ARROW);
- wcProgman.hbrBackground = NULL;
- wcProgman.lpszMenuName = NULL;
- wcProgman.lpszClassName = szProgmanClassName;
-
- return RegisterClassW(&wcProgman) != 0;
-}
-
-
-/*************************************************************************
- * SHCreateDesktop [SHELL32.200]
- *
- */
-HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
-{
- HWND hWndDesk;
- RECT rcDesk;
-
- if (ShellDesk == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- if (RegisterProgmanWindowClass() == 0)
- {
- WARN("Failed to register the Progman window class!\n");
- return NULL;
- }
-
- rcDesk.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
- rcDesk.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
- rcDesk.right = rcDesk.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
- rcDesk.bottom = rcDesk.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
-
- if (IsRectEmpty(&rcDesk))
- {
- rcDesk.left = rcDesk.top = 0;
- rcDesk.right = GetSystemMetrics(SM_CXSCREEN);
- rcDesk.bottom = GetSystemMetrics(SM_CYSCREEN);
- }
-
- hWndDesk = CreateWindowExW(WS_EX_TOOLWINDOW, szProgmanClassName, szProgmanWindowName,
- WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
- rcDesk.left, rcDesk.top, rcDesk.right, rcDesk.bottom,
- NULL, NULL, shell32_hInstance, reinterpret_cast<LPVOID>(ShellDesk));
- if (hWndDesk != NULL)
- return (HANDLE) GetWindowLongPtrW(hWndDesk, 0);
-
- return NULL;
-}
-
-/*************************************************************************
- * SHCreateDesktop [SHELL32.201]
- *
- */
-BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
-{
- CDesktopBrowser *Desk = reinterpret_cast<CDesktopBrowser *>(hDesktop);
-
- if (Desk == NULL || Desk->Tag != SHDESK_TAG)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- return Desk->MessageLoop();
-}
list(APPEND SOURCE
CBandSite.cpp
- CDesktopBrowser.cpp
CMenuBand.cpp
CMenuDeskBar.cpp
CMenuFocusManager.cpp
CMenuSite.cpp
CMenuToolbars.cpp
CMergedFolder.cpp
- CStartMenu.cpp
- ShellDDE.cpp)
+ CStartMenu.cpp)
add_library(shellmenu ${SOURCE})
+++ /dev/null
-/*
- * Shell DDE Handling
- *
- * Copyright 2004 Robert Shearman
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "shellmenu.h"
-#include <ddeml.h>
-#include <strsafe.h>
-#include <shlwapi_undoc.h>
-
-/* WARNING: Although this is a functional implementation of the DDE parsing, the handlers are not implemented here.
-The actual working implementation is in shell32 instead. */
-
-WINE_DEFAULT_DEBUG_CHANNEL(shelldde);
-
-typedef DWORD(CALLBACK * pfnCommandHandler)(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS);
-
-struct DDECommandHandler
-{
- WCHAR Command[32];
- pfnCommandHandler Handler;
-};
-
-extern DDECommandHandler HandlerList [];
-extern const int HandlerListLength;
-
-/* DDE Instance ID */
-static DWORD dwDDEInst;
-
-/* String handles */
-static HSZ hszProgmanTopic;
-static HSZ hszProgmanService;
-static HSZ hszShell;
-static HSZ hszAppProperties;
-static HSZ hszFolders;
-
-static BOOL bInitialized;
-
-static BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
-{
- WCHAR szTopic[MAX_PATH];
- WCHAR szService[MAX_PATH];
-
- DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
- DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE);
-
- TRACE("Dde_OnConnect: topic=%S, service=%S\n", szTopic, szService);
-
- return TRUE;
-}
-
-static void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
-{
- WCHAR szTopic[MAX_PATH];
- WCHAR szService[MAX_PATH];
-
- DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
- DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE);
-
- TRACE("Dde_OnConnectConfirm: hconv=%p, topic=%S, service=%S\n", hconv, szTopic, szService);
-}
-
-static BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
-{
- WCHAR szTopic[MAX_PATH];
- WCHAR szService[MAX_PATH];
-
- DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
- DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE);
-
- TRACE("Dde_OnWildConnect: topic=%S, service=%S\n", szTopic, szService);
-
- return FALSE;
-}
-
-static HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic, HSZ hszItem)
-{
- WCHAR szTopic[MAX_PATH];
- WCHAR szItem[MAX_PATH];
-
- DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
- DdeQueryStringW(dwDDEInst, hszItem, szItem, _countof(szItem), CP_WINUNICODE);
-
- TRACE("Dde_OnRequest: uFmt=%d, hconv=%p, topic=%S, item=%S\n", hconv, szTopic, szItem);
-
- return NULL;
-}
-
-static LPITEMIDLIST _ILReadFromSharedMemory(PCWSTR strField)
-{
- LPITEMIDLIST ret = NULL;
-
- // Ensure it really is an IDLIST-formatted parameter
- // Format for IDLIST params: ":pid:shared"
- if (*strField != L':')
- return NULL;
-
- HANDLE hData = (HANDLE) StrToIntW(strField + 1);
- PWSTR strSecond = StrChrW(strField + 1, L':');
-
- if (strSecond)
- {
- int pid = StrToIntW(strSecond + 1);
- void* pvShared = SHLockShared(hData, pid);
- if (pvShared)
- {
- ret = ILClone((LPCITEMIDLIST) pvShared);
- SHUnlockShared(pvShared);
- SHFreeShared(hData, pid);
- }
- }
- return ret;
-}
-
-static DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
-{
- WCHAR szTopic[MAX_PATH];
- WCHAR szCommand[MAX_PATH];
- WCHAR *pszCommand;
-
- DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE);
-
- pszCommand = (WCHAR*) DdeAccessData(hdata, NULL);
- if (!pszCommand)
- return DDE_FNOTPROCESSED;
-
- StringCchCopyW(szCommand, _countof(szCommand), pszCommand);
-
- DdeUnaccessData(hdata);
-
- TRACE("Dde_OnExecute: hconv=%p, topic=%S, command=%S\n", hconv, szTopic, pszCommand);
-
- /*
- [ViewFolder("%l", %I, %S)] -- Open a folder in standard mode
- [ExploreFolder("%l", %I, %S)] -- Open a folder in "explore" mode (file tree is shown to the left by default)
- [FindFolder("%l", %I)] -- Open a folder in "find" mode (search panel is shown to the left by default)
- [ShellFile("%1","%1",%S)] -- Execute the contents of the specified .SCF file
-
- Approximate grammar (Upper names define rules, <lower> names define terminals, single-quotes are literals):
-
- Rules
- Command = ('[' Function ']') | Function
- Function = <identifier> '(' Parameters ')'
- Parameters = (<quoted-string> (',' <idlist> (',' <number>)?)?)?
-
- Terminals
- <identifier> = [a-zA-Z]+
- <quoted-string> = \"([^\"]|\\.)\"
- <idlist> = \:[0-9]+\:[0-9]+
- <number> = [0-9]+
- */
-
- WCHAR Command[MAX_PATH] = L"";
- WCHAR Path[MAX_PATH] = L"";
- LPITEMIDLIST IdList = NULL;
- INT UnknownParameter = 0;
-
- // Simplified parsing (assumes the command will not be TOO broken):
-
- PWSTR cmd = szCommand;
- // 1. if starts with [, skip first char
- if (*cmd == L'[')
- cmd++;
-
- if (*cmd == L']')
- {
- ERR("Empty command. Nothing to run.\n");
- return DDE_FNOTPROCESSED;
- }
-
- // Read until first (, and take text before ( as command name
- {
- PWSTR cmdEnd = StrChrW(cmd, L'(');
-
- if (!cmdEnd)
- {
- ERR("Could not find '('. Invalid command.\n");
- return DDE_FNOTPROCESSED;
- }
-
- *cmdEnd = 0;
-
- StringCchCopy(Command, _countof(Command), cmd);
-
- cmd = cmdEnd + 1;
- }
-
- // Read first param after (, expecting quoted string
- if (*cmd != L')')
- {
- // Copy unescaped string
- PWSTR dst = Path;
- BOOL isQuote = FALSE;
-
- PWSTR arg = cmd;
-
- while (*arg && (isQuote || *arg != L','))
- {
- if (*arg == L'"')
- {
- isQuote = !isQuote;
- if (isQuote && arg != cmd) // do not copy the " at the beginning of the string
- {
- *(dst++) = L'"';
- }
- }
- else
- {
- *(dst++) = *arg;
- }
-
- arg++;
- }
-
- cmd = arg + 1;
-
- while (*cmd == L' ')
- cmd++;
- }
-
- // Read second param, expecting an idlist in shared memory
- if (*cmd != L')')
- {
- if (*cmd != ':')
- {
- ERR("Expected ':'. Invalid command.\n");
- return DDE_FNOTPROCESSED;
- }
-
- PWSTR idlistEnd = StrChrW(cmd, L',');
-
- if (!idlistEnd)
- idlistEnd = StrChrW(cmd, L')');
-
- if (!idlistEnd)
- {
- ERR("Expected ',' or ')'. Invalid command.\n");
- return DDE_FNOTPROCESSED;
- }
-
- IdList = _ILReadFromSharedMemory(cmd);
-
- cmd = idlistEnd + 1;
- }
-
- // Read third param, expecting an integer
- if (*cmd != L')')
- {
- UnknownParameter = StrToIntW(cmd);
- }
-
- TRACE("Parse end: cmd=%S, S=%d, pidl=%p, path=%S\n", Command, UnknownParameter, IdList, Path);
-
- // Find handler in list
- for (int i = 0; i < HandlerListLength; i++)
- {
- DDECommandHandler & handler = HandlerList[i];
- if (StrCmpW(handler.Command, Command) == 0)
- {
- return handler.Handler(Command, Path, IdList, UnknownParameter);
- }
- }
-
- // No handler found
- ERR("Unknown command %S\n", Command);
- return DDE_FNOTPROCESSED;
-}
-
-static void Dde_OnDisconnect(HCONV hconv)
-{
- TRACE("Dde_OnDisconnect: hconv=%p\n", hconv);
-}
-
-static HDDEDATA CALLBACK DdeCallback(
- UINT uType,
- UINT uFmt,
- HCONV hconv,
- HSZ hsz1,
- HSZ hsz2,
- HDDEDATA hdata,
- ULONG_PTR dwData1,
- ULONG_PTR dwData2)
-{
- switch (uType)
- {
- case XTYP_CONNECT:
- return (HDDEDATA) (DWORD_PTR) Dde_OnConnect(hsz1, hsz2);
- case XTYP_CONNECT_CONFIRM:
- Dde_OnConnectConfirm(hconv, hsz1, hsz2);
- return NULL;
- case XTYP_WILDCONNECT:
- return (HDDEDATA) (DWORD_PTR) Dde_OnWildConnect(hsz1, hsz2);
- case XTYP_REQUEST:
- return Dde_OnRequest(uFmt, hconv, hsz1, hsz2);
- case XTYP_EXECUTE:
- return (HDDEDATA) (DWORD_PTR) Dde_OnExecute(hconv, hsz1, hdata);
- case XTYP_DISCONNECT:
- Dde_OnDisconnect(hconv);
- return NULL;
- case XTYP_REGISTER:
- return NULL;
- default:
- TRACE("DdeCallback: unknown uType=%d\n", uType);
- return NULL;
- }
-}
-/*************************************************************************
- * ShellDDEInit (SHELL32.@)
- *
- * Registers the Shell DDE services with the system so that applications
- * can use them.
- *
- * PARAMS
- * bInit [I] TRUE to initialize the services, FALSE to uninitialize.
- *
- * RETURNS
- * Nothing.
- */
-EXTERN_C void WINAPI ShellDDEInit(BOOL bInit)
-{
- TRACE("ShellDDEInit bInit = %s\n", bInit ? "TRUE" : "FALSE");
-
- if (bInit && !bInitialized)
- {
- DdeInitializeW(&dwDDEInst, DdeCallback, CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
-
- hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, L"Progman", CP_WINUNICODE);
- hszProgmanService = DdeCreateStringHandleW(dwDDEInst, L"Progman", CP_WINUNICODE);
- hszShell = DdeCreateStringHandleW(dwDDEInst, L"Shell", CP_WINUNICODE);
- hszAppProperties = DdeCreateStringHandleW(dwDDEInst, L"AppProperties", CP_WINUNICODE);
- hszFolders = DdeCreateStringHandleW(dwDDEInst, L"Folders", CP_WINUNICODE);
-
- if (hszProgmanTopic && hszProgmanService &&
- hszShell && hszAppProperties && hszFolders &&
- DdeNameService(dwDDEInst, hszFolders, 0, DNS_REGISTER) &&
- DdeNameService(dwDDEInst, hszProgmanService, 0, DNS_REGISTER) &&
- DdeNameService(dwDDEInst, hszShell, 0, DNS_REGISTER))
- {
- bInitialized = TRUE;
- }
- }
- else if (!bInit && bInitialized)
- {
- /* unregister all services */
- DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
-
- if (hszFolders)
- DdeFreeStringHandle(dwDDEInst, hszFolders);
- if (hszAppProperties)
- DdeFreeStringHandle(dwDDEInst, hszAppProperties);
- if (hszShell)
- DdeFreeStringHandle(dwDDEInst, hszShell);
- if (hszProgmanService)
- DdeFreeStringHandle(dwDDEInst, hszProgmanService);
- if (hszProgmanTopic)
- DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
-
- DdeUninitialize(dwDDEInst);
-
- bInitialized = FALSE;
- }
-}
-
-static DWORD CALLBACK DDE_OnViewFolder(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
-{
- UNIMPLEMENTED;
- return DDE_FACK;
-}
-
-static DWORD CALLBACK DDW_OnExploreFolder(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
-{
- UNIMPLEMENTED;
- return DDE_FACK;
-}
-
-static DWORD CALLBACK DDE_OnFindFolder(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
-{
- UNIMPLEMENTED;
- return DDE_FNOTPROCESSED;
-}
-
-static DWORD CALLBACK DDE_OnShellFile(PWSTR strCommand, PWSTR strPath, LPITEMIDLIST pidl, INT unkS)
-{
- UNIMPLEMENTED;
- return DDE_FNOTPROCESSED;
-}
-
-DDECommandHandler HandlerList [] = {
-
- { L"ViewFolder", DDE_OnViewFolder },
- { L"ExploreFolder", DDW_OnExploreFolder },
- { L"FindFolder", DDE_OnFindFolder },
- { L"ShellFile", DDE_OnShellFile }
-};
-
-const int HandlerListLength = _countof(HandlerList);
#pragma warning(pop)
#endif
-extern HINSTANCE shell32_hInstance;
-
extern "C" HRESULT WINAPI CStartMenu_Constructor(REFIID riid, void **ppv);
extern "C" HRESULT WINAPI CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv);
extern "C" HRESULT WINAPI CMenuSite_Constructor(REFIID riid, LPVOID *ppv);