Added patch to implement shell32 NewMenu class with new folder item.

This commit is contained in:
Sebastian Lackner 2015-08-16 23:19:29 +02:00
parent 67f1219393
commit 79253e6534
5 changed files with 671 additions and 1 deletions

View File

@ -39,12 +39,13 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
-----------------------------------
**Bug fixes and features included in the next upcoming release [9]:**
**Bug fixes and features included in the next upcoming release [10]:**
* Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699))
* Catch invalid memory accesses in imagehlp.CheckSumMappedFile
* Fix implementation of ntdll.MapViewOfSection
* Implement enumeration of sound devices and basic properties to dxdiagn ([Wine Bug #32613](https://bugs.winehq.org/show_bug.cgi?id=32613))
* Implement shell32 NewMenu class with new folder item ([Wine Bug #24812](https://bugs.winehq.org/show_bug.cgi?id=24812))
* Implement special handling for calling GetChildContainer with an empty string ([Wine Bug #38014](https://bugs.winehq.org/show_bug.cgi?id=38014))
* Implement vcomp locking functions ([Wine Bug #26688](https://bugs.winehq.org/show_bug.cgi?id=26688))
* Improve startup performance by delaying font initialization

1
debian/changelog vendored
View File

@ -11,6 +11,7 @@ wine-staging (1.7.50) UNRELEASED; urgency=low
(fixes Wine Staging Bug #401).
* Added patch to set SFGAO_HASSUBFOLDER only when there are really subfolders.
* Added patch to fix multiple uninitialized memory issues in wineserver.
* Added patch to implement shell32 NewMenu class with new folder item.
* Removed patch to move security cookie initialization from memory management
to loader.
-- Sebastian Lackner <sebastian@fds-team.de> Tue, 11 Aug 2015 06:12:14 +0200

View File

@ -229,6 +229,7 @@ patch_enable_all ()
enable_shell32_File_Property_Dialog="$1"
enable_shell32_IDragSourceHelper="$1"
enable_shell32_Icons="$1"
enable_shell32_NewMenu_Interface="$1"
enable_shell32_Placeholder_Icons="$1"
enable_shell32_Progress_Dialog="$1"
enable_shell32_RunDLL_CallEntry16="$1"
@ -777,6 +778,9 @@ patch_enable ()
shell32-Icons)
enable_shell32_Icons="$2"
;;
shell32-NewMenu_Interface)
enable_shell32_NewMenu_Interface="$2"
;;
shell32-Placeholder_Icons)
enable_shell32_Placeholder_Icons="$2"
;;
@ -4721,6 +4725,22 @@ if test "$enable_shell32_Icons" -eq 1; then
) >> "$patchlist"
fi
# Patchset shell32-NewMenu_Interface
# |
# | This patchset fixes the following Wine bugs:
# | * [#24812] Implement shell32 NewMenu class with new folder item
# |
# | Modified files:
# | * dlls/shell32/Makefile.in, dlls/shell32/shell32_classes.idl, dlls/shell32/shell32_main.h, dlls/shell32/shellnew.c,
# | dlls/shell32/shellole.c, include/shlguid.h
# |
if test "$enable_shell32_NewMenu_Interface" -eq 1; then
patch_apply shell32-NewMenu_Interface/0001-shell32-Implement-NewMenu-with-new-folder-item.patch
(
echo '+ { "Michael Müller", "shell32: Implement NewMenu with new folder item.", 1 },';
) >> "$patchlist"
fi
# Patchset shell32-Placeholder_Icons
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,647 @@
From 0e08c56df7f0d6beefbf6726f9db0b5ad3541348 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 16 Aug 2015 17:34:22 +0200
Subject: shell32: Implement NewMenu with new folder item.
---
dlls/shell32/Makefile.in | 1 +
dlls/shell32/shell32_classes.idl | 5 +
dlls/shell32/shell32_main.h | 1 +
dlls/shell32/shellnew.c | 558 +++++++++++++++++++++++++++++++++++++++
dlls/shell32/shellole.c | 1 +
include/shlguid.h | 2 +
6 files changed, 568 insertions(+)
create mode 100644 dlls/shell32/shellnew.c
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index 038db7f..7b677ff 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -32,6 +32,7 @@ C_SRCS = \
shelldispatch.c \
shellitem.c \
shelllink.c \
+ shellnew.c \
shellole.c \
shellord.c \
shellpath.c \
diff --git a/dlls/shell32/shell32_classes.idl b/dlls/shell32/shell32_classes.idl
index f0131e7..0140fec 100644
--- a/dlls/shell32/shell32_classes.idl
+++ b/dlls/shell32/shell32_classes.idl
@@ -76,6 +76,11 @@ coclass KnownFolderManager { interface IKnownFolderManager; }
[
threading(apartment),
+ uuid(d969a300-e7ff-11d0-a93b-00a0c90f2719)
+] coclass NewMenu { interface IShellExtInit; }
+
+[
+ threading(apartment),
uuid(00bb2763-6a77-11d0-a535-00c04fd7d062)
] coclass AutoComplete { interface IAutoComplete2; }
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index 492f79f..83c5655 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -98,6 +98,7 @@ HRESULT WINAPI RecycleBin_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID
HRESULT WINAPI QueryAssociations_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppOutput) DECLSPEC_HIDDEN;
HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
HRESULT WINAPI KnownFolderManager_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
+HRESULT WINAPI NewMenu_Constructor(IUnknown *outer, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
extern HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST, LPWSTR, UINT, int*) DECLSPEC_HIDDEN;
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN;
HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN;
diff --git a/dlls/shell32/shellnew.c b/dlls/shell32/shellnew.c
new file mode 100644
index 0000000..59e18d6
--- /dev/null
+++ b/dlls/shell32/shellnew.c
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2015 Michael Müller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "wine/debug.h"
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winreg.h"
+
+#include "winuser.h"
+#include "wingdi.h"
+#include "shlobj.h"
+#include "undocshell.h"
+
+#include "pidl.h"
+#include "shell32_main.h"
+#include "shlguid.h"
+#include "shlwapi.h"
+#include "shresdef.h"
+#include "shellfolder.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+typedef struct
+{
+ IShellExtInit IShellExtInit_iface;
+ IContextMenu IContextMenu_iface;
+ IContextMenu3 IContextMenu3_iface;
+ IObjectWithSite IObjectWithSite_iface;
+
+ LONG ref;
+ IUnknown *site;
+ LPITEMIDLIST pidl;
+ HICON icon_folder;
+
+ UINT folder_cmd;
+} NewMenuImpl;
+
+static inline NewMenuImpl *impl_from_IShellExtInit(IShellExtInit *iface)
+{
+ return CONTAINING_RECORD(iface, NewMenuImpl, IShellExtInit_iface);
+}
+
+static inline NewMenuImpl *impl_from_IContextMenu(IContextMenu *iface)
+{
+ return CONTAINING_RECORD(iface, NewMenuImpl, IContextMenu_iface);
+}
+
+static inline NewMenuImpl *impl_from_IContextMenu3(IContextMenu3 *iface)
+{
+ return CONTAINING_RECORD(iface, NewMenuImpl, IContextMenu3_iface);
+}
+
+static inline NewMenuImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
+{
+ return CONTAINING_RECORD(iface, NewMenuImpl, IObjectWithSite_iface);
+}
+
+static HRESULT WINAPI
+NewMenu_ExtInit_QueryInterface(IShellExtInit *iface, REFIID riid, void **ppv)
+{
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
+ TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
+
+ *ppv = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellExtInit))
+ {
+ *ppv = &This->IShellExtInit_iface;
+ }
+ else if (IsEqualIID(riid, &IID_IObjectWithSite))
+ {
+ *ppv = &This->IObjectWithSite_iface;
+ }
+ else if (IsEqualIID(riid, &IID_IContextMenu))
+ {
+ *ppv = &This->IContextMenu_iface;
+ }
+ else if (IsEqualIID(riid, &IID_IContextMenu3))
+ {
+ *ppv = &This->IContextMenu3_iface;
+ }
+
+ if (*ppv)
+ {
+ IUnknown_AddRef((IUnknown *)*ppv);
+ TRACE("-- Interface: (%p)->(%p)\n", ppv, *ppv);
+ return S_OK;
+ }
+
+ ERR("-- Interface: E_NOINTERFACE for %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+NewMenu_ExtInit_AddRef(IShellExtInit *iface)
+{
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p), new refcount=%i\n", iface, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI
+NewMenu_ExtInit_Release(IShellExtInit *iface)
+{
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p), new refcount=%i\n", iface, ref);
+
+ if (!ref)
+ {
+ if (This->site) IUnknown_Release(This->site);
+ if (This->pidl) ILFree(This->pidl);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI
+NewMenu_ExtInit_Initialize(IShellExtInit *iface, LPCITEMIDLIST pidl, IDataObject *obj, HKEY key)
+{
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
+
+ TRACE("(%p)->(%p, %p, %p)\n", This, pidl, obj, key );
+
+ if (!pidl)
+ return E_FAIL;
+
+ if (This->pidl) ILFree(This->pidl);
+ This->pidl = ILClone(pidl);
+ This->icon_folder = LoadImageW(shell32_hInstance, (LPCWSTR)MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
+
+ return S_OK;
+}
+
+static const IShellExtInitVtbl eivt =
+{
+ NewMenu_ExtInit_QueryInterface,
+ NewMenu_ExtInit_AddRef,
+ NewMenu_ExtInit_Release,
+ NewMenu_ExtInit_Initialize
+};
+
+
+static HRESULT WINAPI
+NewMenu_ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
+{
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
+ return NewMenu_ExtInit_QueryInterface(&This->IShellExtInit_iface, riid, ppv);
+}
+
+static ULONG WINAPI
+NewMenu_ObjectWithSite_AddRef(IObjectWithSite *iface)
+{
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
+ return NewMenu_ExtInit_AddRef(&This->IShellExtInit_iface);
+}
+
+static ULONG WINAPI
+NewMenu_ObjectWithSite_Release(IObjectWithSite *iface)
+{
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
+ return NewMenu_ExtInit_Release(&This->IShellExtInit_iface);
+}
+
+static HRESULT WINAPI
+NewMenu_ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID iid, void **ppv)
+{
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
+
+ TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), ppv);
+
+ if (!This->site)
+ return E_FAIL;
+
+ return IUnknown_QueryInterface(This->site, iid, ppv);
+}
+
+static HRESULT WINAPI
+NewMenu_ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *punk)
+{
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
+
+ TRACE("(%p)->(%p)\n", This, punk);
+
+ if (punk)
+ IUnknown_AddRef(punk);
+
+ if (This->site)
+ IUnknown_Release(This->site);
+
+ This->site = punk;
+ return S_OK;
+}
+
+static const IObjectWithSiteVtbl owsvt =
+{
+ NewMenu_ObjectWithSite_QueryInterface,
+ NewMenu_ObjectWithSite_AddRef,
+ NewMenu_ObjectWithSite_Release,
+ NewMenu_ObjectWithSite_SetSite,
+ NewMenu_ObjectWithSite_GetSite,
+};
+
+
+static HRESULT WINAPI
+NewMenu_ContextMenu3_QueryInterface(IContextMenu3 *iface, REFIID riid, void **ppv)
+{
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+ return NewMenu_ExtInit_QueryInterface(&This->IShellExtInit_iface, riid, ppv);
+}
+
+static ULONG WINAPI
+NewMenu_ContextMenu3_AddRef(IContextMenu3 *iface)
+{
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+ return NewMenu_ExtInit_AddRef(&This->IShellExtInit_iface);
+}
+
+static ULONG WINAPI
+NewMenu_ContextMenu3_Release(IContextMenu3 *iface)
+{
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+ return NewMenu_ExtInit_Release(&This->IShellExtInit_iface);
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu3_GetCommandString(IContextMenu3 *iface, UINT_PTR cmd, UINT type,
+ UINT *reserved, LPSTR name, UINT max_len)
+{
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+
+ FIXME("(%p)->(%lu %u %p %p %u): stub\n", This, cmd, type, reserved, name, max_len);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT create_folder(NewMenuImpl *This, IShellView *view)
+{
+ IFolderView *folder_view = NULL;
+ IShellFolder *desktop = NULL;
+ IShellFolder *parent = NULL;
+ ISFHelper *helper = NULL;
+ LPITEMIDLIST pidl = NULL;
+ WCHAR nameW[MAX_PATH];
+ HRESULT hr;
+
+ if (view)
+ {
+ hr = IShellView_QueryInterface(view, &IID_IFolderView, (void **)&folder_view);
+ if (FAILED(hr)) return hr;
+
+ hr = IFolderView_GetFolder(folder_view, &IID_IShellFolder, (void **)&parent);
+ if (FAILED(hr)) goto out;
+ }
+ else
+ {
+ hr = SHGetDesktopFolder(&desktop);
+ if (FAILED(hr)) goto out;
+
+ hr = IShellFolder_BindToObject(desktop, This->pidl, NULL, &IID_IShellFolder, (void **)&parent);
+ if (FAILED(hr)) goto out;
+ }
+
+ IShellFolder_QueryInterface(parent, &IID_ISFHelper, (void **)&helper);
+ if (FAILED(hr)) goto out;
+
+ hr = ISFHelper_GetUniqueName(helper, nameW, MAX_PATH);
+ if (FAILED(hr)) goto out;
+
+ hr = ISFHelper_AddFolder(helper, 0, nameW, &pidl);
+ if (FAILED(hr)) goto out;
+
+ if (view)
+ {
+ IShellView_SelectItem(view, pidl, SVSI_DESELECTOTHERS | SVSI_EDIT |
+ SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT);
+ }
+
+out:
+ if (pidl) SHFree(pidl);
+ if (helper) ISFHelper_Release(helper);
+ if (parent) IShellFolder_Release(parent);
+ if (desktop) IShellFolder_Release(desktop);
+ if (folder_view) IFolderView_Release(folder_view);
+ return hr;
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu3_InvokeCommand(IContextMenu3 *iface, LPCMINVOKECOMMANDINFO info)
+{
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+ IShellBrowser *browser;
+ IShellView *view = NULL;
+ HRESULT hr = E_FAIL;
+
+ TRACE("(%p)->(%p)\n", This, info);
+
+ /* New Folder */
+ if (info->lpVerb == 0)
+ {
+ if ((browser = (IShellBrowser *)SendMessageA(info->hwnd, CWM_GETISHELLBROWSER, 0, 0)))
+ {
+ if (FAILED(IShellBrowser_QueryActiveShellView(browser, &view)))
+ view = NULL;
+ }
+ hr = create_folder(This, view);
+ if (view) IShellView_Release(view);
+ }
+
+ return hr;
+}
+
+static UINT insert_new_menu_items(NewMenuImpl *This, HMENU menu, UINT pos, UINT cmd_first, UINT cmd_last)
+{
+ MENUITEMINFOW item;
+ WCHAR buffer[256];
+
+ memset(&item, 0, sizeof(item));
+ item.cbSize = sizeof(item);
+
+ if (cmd_first > cmd_last)
+ return cmd_first;
+
+ /* FIXME: on windows it is only 'Folder' not 'New Folder' */
+ if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, buffer, sizeof(buffer) / sizeof(WCHAR)))
+ buffer[0] = 0;
+
+ item.fMask = MIIM_ID | MIIM_BITMAP | MIIM_STRING;
+ item.dwTypeData = buffer;
+ item.cch = strlenW(buffer);
+ item.wID = cmd_first;
+ item.hbmpItem = HBMMENU_CALLBACK;
+ if (InsertMenuItemW(menu, pos, TRUE, &item))
+ {
+ This->folder_cmd = cmd_first++;
+ pos++;
+ }
+
+ return cmd_first;
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu3_QueryContextMenu(IContextMenu3 *iface, HMENU menu, UINT index,
+ UINT cmd_first, UINT cmd_last, UINT flags)
+{
+ static WCHAR newW[] = {'N','e','w',0};
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+ MENUITEMINFOW item;
+ HMENU submenu;
+ UINT id;
+
+ TRACE("(%p)->(%p, %u, %u, %u, %u)\n", This,
+ menu, index, cmd_first, cmd_last, flags );
+
+ if (!This->pidl)
+ return E_FAIL;
+
+ submenu = CreateMenu();
+ if (!submenu) return E_FAIL;
+
+ id = insert_new_menu_items(This, submenu, 0, cmd_first, cmd_last);
+
+ memset(&item, 0, sizeof(item));
+ item.cbSize = sizeof(item);
+ item.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
+ item.fType = MFT_STRING;
+ item.wID = -1;
+ item.dwTypeData = newW; /* FIXME: load from resource file */
+ item.cch = strlenW(newW);
+ item.fState = MFS_ENABLED;
+ item.hSubMenu = submenu;
+
+ if (!InsertMenuItemW(menu, index, TRUE, &item))
+ return E_FAIL;
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id);
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu3_HandleMenuMsg2(IContextMenu3 *iface, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *result)
+{
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
+
+ TRACE("(%p)->(%u, %lx, %lx, %p)\n", This, uMsg, wParam, lParam, result);
+
+ switch (uMsg)
+ {
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
+ if (!mis || mis->CtlType != ODT_MENU)
+ break;
+
+ if (This->folder_cmd == mis->itemID)
+ {
+ mis->itemWidth = GetSystemMetrics(SM_CXSMICON);
+ mis->itemHeight = GetSystemMetrics(SM_CYSMICON);
+ }
+
+ if (result) *result = TRUE;
+ break;
+ }
+
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+ HICON icon = 0;
+ UINT x, y;
+
+ if (!dis || dis->CtlType != ODT_MENU)
+ break;
+
+ if (This->folder_cmd == dis->itemID)
+ icon = This->icon_folder;
+
+ if (!icon)
+ break;
+
+ x = (dis->rcItem.right - dis->rcItem.left - GetSystemMetrics(SM_CXSMICON)) / 2;
+ y = (dis->rcItem.bottom - dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2;
+ DrawStateW(dis->hDC, NULL, NULL, (LPARAM)icon, 0, x, y, 0, 0, DST_ICON | DSS_NORMAL);
+
+ if (result) *result = TRUE;
+ break;
+ }
+ }
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu3_HandleMenuMsg(IContextMenu3 *iface, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return NewMenu_ContextMenu3_HandleMenuMsg2(iface, uMsg, wParam, lParam, NULL);
+}
+
+static const IContextMenu3Vtbl cmvt3 =
+{
+ NewMenu_ContextMenu3_QueryInterface,
+ NewMenu_ContextMenu3_AddRef,
+ NewMenu_ContextMenu3_Release,
+ NewMenu_ContextMenu3_QueryContextMenu,
+ NewMenu_ContextMenu3_InvokeCommand,
+ NewMenu_ContextMenu3_GetCommandString,
+ NewMenu_ContextMenu3_HandleMenuMsg,
+ NewMenu_ContextMenu3_HandleMenuMsg2
+};
+
+
+static HRESULT WINAPI
+NewMenu_ContextMenu_QueryInterface(IContextMenu *iface, REFIID riid, void **ppv)
+{
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
+ return NewMenu_ExtInit_QueryInterface(&This->IShellExtInit_iface, riid, ppv);
+}
+
+static ULONG WINAPI
+NewMenu_ContextMenu_AddRef(IContextMenu *iface)
+{
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
+ return NewMenu_ExtInit_AddRef(&This->IShellExtInit_iface);
+}
+
+static ULONG WINAPI
+NewMenu_ContextMenu_Release(IContextMenu *iface)
+{
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
+ return NewMenu_ExtInit_Release(&This->IShellExtInit_iface);
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu_QueryContextMenu(IContextMenu *iface, HMENU menu, UINT index,
+ UINT cmd_first, UINT cmd_last, UINT flags)
+{
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
+ return NewMenu_ContextMenu3_QueryContextMenu(&This->IContextMenu3_iface, menu, index,
+ cmd_first, cmd_last, flags);
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu_InvokeCommand(IContextMenu *iface, LPCMINVOKECOMMANDINFO info)
+{
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
+ return NewMenu_ContextMenu3_InvokeCommand(&This->IContextMenu3_iface, info);
+}
+
+static HRESULT WINAPI
+NewMenu_ContextMenu_GetCommandString(IContextMenu *iface, UINT_PTR cmd, UINT type,
+ UINT *reserved, LPSTR name, UINT max_len)
+{
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
+ return NewMenu_ContextMenu3_GetCommandString(&This->IContextMenu3_iface, cmd, type, reserved, name, max_len);
+}
+
+static const IContextMenuVtbl cmvt =
+{
+ NewMenu_ContextMenu_QueryInterface,
+ NewMenu_ContextMenu_AddRef,
+ NewMenu_ContextMenu_Release,
+ NewMenu_ContextMenu_QueryContextMenu,
+ NewMenu_ContextMenu_InvokeCommand,
+ NewMenu_ContextMenu_GetCommandString
+};
+
+
+HRESULT WINAPI NewMenu_Constructor(IUnknown *outer, REFIID riid, void **obj)
+{
+ NewMenuImpl *menu;
+ HRESULT hr;
+
+ TRACE("outer=%p riid=%s\n", outer, debugstr_guid(riid));
+
+ *obj = NULL;
+
+ if (outer)
+ return CLASS_E_NOAGGREGATION;
+
+ menu = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NewMenuImpl));
+ if (!menu) return E_OUTOFMEMORY;
+
+ menu->ref = 1;
+ menu->IShellExtInit_iface.lpVtbl = &eivt;
+ menu->IContextMenu_iface.lpVtbl = &cmvt;
+ menu->IContextMenu3_iface.lpVtbl = &cmvt3;
+ menu->IObjectWithSite_iface.lpVtbl = &owsvt;
+
+ TRACE("(%p)\n", menu);
+
+ hr = IShellExtInit_QueryInterface(&menu->IShellExtInit_iface, riid, obj);
+ IShellExtInit_Release(&menu->IShellExtInit_iface);
+ return hr;
+}
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
index 637a101..9c1df75 100644
--- a/dlls/shell32/shellole.c
+++ b/dlls/shell32/shellole.c
@@ -83,6 +83,7 @@ static const struct {
{&CLSID_ExplorerBrowser,ExplorerBrowser_Constructor},
{&CLSID_KnownFolderManager, KnownFolderManager_Constructor},
{&CLSID_Shell, IShellDispatch_Constructor},
+ {&CLSID_NewMenu, NewMenu_Constructor},
{NULL, NULL}
};
diff --git a/include/shlguid.h b/include/shlguid.h
index 2279def..09aacc5 100644
--- a/include/shlguid.h
+++ b/include/shlguid.h
@@ -146,6 +146,8 @@ DEFINE_GUID(CLSID_ProgressDialog, 0xf8383852, 0xfcd3, 0x11d1, 0xa6, 0xb9, 0x0, 0
DEFINE_GUID(CLSID_ShellItem, 0x2fe352ea, 0xfd1f, 0x11d2, 0xb1, 0xf4, 0x00, 0xc0, 0x4f, 0x8e, 0xeb, 0x3e);
+DEFINE_GUID(CLSID_NewMenu, 0xd969a300, 0xe7ff, 0x11d0, 0xa9, 0x3b, 0x0, 0xa0, 0xc9, 0xf, 0x27, 0x19);
+
#define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0}
DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0);
#define PID_FINDDATA 0
--
2.5.0

View File

@ -0,0 +1 @@
Fixes: [24812] Implement shell32 NewMenu class with new folder item