Author: cwittich Date: Sat Jul 23 12:31:30 2016 New Revision: 71980
URL: http://svn.reactos.org/svn/reactos?rev=71980&view=rev Log: [SHELL32] cache entries of "New" menu CORE-10439
Modified: trunk/reactos/dll/win32/shell32/CNewMenu.cpp trunk/reactos/dll/win32/shell32/CNewMenu.h
Modified: trunk/reactos/dll/win32/shell32/CNewMenu.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CNewMenu.... ============================================================================== --- trunk/reactos/dll/win32/shell32/CNewMenu.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/CNewMenu.cpp [iso-8859-1] Sat Jul 23 12:31:30 2016 @@ -163,17 +163,18 @@ }
BOOL -CNewMenu::LoadAllItems() -{ +CNewMenu::CacheItems() +{ + HKEY hKey; + DWORD dwSize = 0; DWORD dwIndex = 0; + LPWSTR lpValue; + LPWSTR lpValues; WCHAR wszName[MAX_PATH]; SHELLNEW_ITEM *pNewItem; SHELLNEW_ITEM *pCurItem = NULL;
- /* If there are any unload them */ - UnloadAllItems(); - - /* Enumerate all extesions */ + /* Enumerate all extensions */ while (RegEnumKeyW(HKEY_CLASSES_ROOT, dwIndex++, wszName, _countof(wszName)) == ERROR_SUCCESS) { if (wszName[0] != L'.') @@ -182,6 +183,7 @@ pNewItem = LoadItem(wszName); if (pNewItem) { + dwSize += wcslen(wszName) + 1; if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0) { /* Link handler */ @@ -200,7 +202,109 @@ } } } - + + dwSize++; + + lpValues = (LPWSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR)); + if (!lpValues) + return FALSE; + + lpValue = lpValues; + pCurItem = m_pItems; + while (pCurItem) + { + memcpy(lpValue, pCurItem->pwszExt, (wcslen(pCurItem->pwszExt) + 1) * sizeof(WCHAR)); + lpValue += wcslen(pCurItem->pwszExt) + 1; + pCurItem = pCurItem->pNext; + } + + if (RegCreateKeyEx(HKEY_CURRENT_USER, ShellNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, lpValues); + return FALSE; + } + + if (RegSetValueExW(hKey, L"Classes", NULL, REG_MULTI_SZ, (LPBYTE)lpValues, dwSize) != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, lpValues); + return FALSE; + } + + HeapFree(GetProcessHeap(), 0, lpValues); + RegCloseKey(hKey); + + return TRUE; +} + +BOOL +CNewMenu::LoadCachedItems() +{ + LPWSTR wszName; + LPWSTR lpValues; + DWORD dwSize; + HKEY hKey; + SHELLNEW_ITEM *pNewItem; + SHELLNEW_ITEM *pCurItem = NULL; + + if (RegOpenKeyExW(HKEY_CURRENT_USER, ShellNewKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) + return FALSE; + + if (RegQueryValueExW(hKey, L"Classes", NULL, NULL, NULL, &dwSize) != ERROR_SUCCESS) + return FALSE; + + lpValues = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwSize); + if (!lpValues) + return FALSE; + + if (RegQueryValueExW(hKey, L"Classes", NULL, NULL, (LPBYTE)lpValues, &dwSize) != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, lpValues); + return FALSE; + } + + wszName = lpValues; + + for (; '\0' != *wszName; wszName += wcslen(wszName) + 1) + { + pNewItem = LoadItem(wszName); + if (pNewItem) + { + if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0) + { + /* Link handler */ + m_pLinkItem = pNewItem; + } + else + { + /* Add at the end of list */ + if (pCurItem) + { + pCurItem->pNext = pNewItem; + pCurItem = pNewItem; + } + else + pCurItem = m_pItems = pNewItem; + } + } + } + + HeapFree(GetProcessHeap(), 0, lpValues); + RegCloseKey(hKey); + + return TRUE; +} + +BOOL +CNewMenu::LoadAllItems() +{ + /* If there are any unload them */ + UnloadAllItems(); + + if (!LoadCachedItems()) + { + CacheItems(); + } + if (!m_pLinkItem) { m_pLinkItem = static_cast<SHELLNEW_ITEM *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHELLNEW_ITEM)));
Modified: trunk/reactos/dll/win32/shell32/CNewMenu.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CNewMenu.... ============================================================================== --- trunk/reactos/dll/win32/shell32/CNewMenu.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/CNewMenu.h [iso-8859-1] Sat Jul 23 12:31:30 2016 @@ -23,33 +23,35 @@ #ifndef _SHV_ITEM_NEW_H_ #define _SHV_ITEM_NEW_H_
+const WCHAR ShellNewKey[] = L"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\ShellNew"; + class CNewMenu : - public CComCoClass<CNewMenu, &CLSID_NewMenu>, - public CComObjectRootEx<CComMultiThreadModelNoCS>, - public IObjectWithSite, - public IContextMenu3, - public IShellExtInit + public CComCoClass<CNewMenu, &CLSID_NewMenu>, + public CComObjectRootEx<CComMultiThreadModelNoCS>, + public IObjectWithSite, + public IContextMenu3, + public IShellExtInit { private: - enum SHELLNEW_TYPE - { - SHELLNEW_TYPE_INVALID = -1, - SHELLNEW_TYPE_COMMAND = 1, - SHELLNEW_TYPE_DATA = 2, - SHELLNEW_TYPE_FILENAME = 4, - SHELLNEW_TYPE_NULLFILE = 8 - }; + enum SHELLNEW_TYPE + { + SHELLNEW_TYPE_INVALID = -1, + SHELLNEW_TYPE_COMMAND = 1, + SHELLNEW_TYPE_DATA = 2, + SHELLNEW_TYPE_FILENAME = 4, + SHELLNEW_TYPE_NULLFILE = 8 + };
- struct SHELLNEW_ITEM - { - SHELLNEW_TYPE Type; - LPWSTR pwszExt; - PBYTE pData; - ULONG cbData; - LPWSTR pwszDesc; - HICON hIcon; - SHELLNEW_ITEM *pNext; - }; + struct SHELLNEW_ITEM + { + SHELLNEW_TYPE Type; + LPWSTR pwszExt; + PBYTE pData; + ULONG cbData; + LPWSTR pwszDesc; + HICON hIcon; + SHELLNEW_ITEM *pNext; + };
LPITEMIDLIST m_pidlFolder; LPWSTR m_wszPath; @@ -62,35 +64,37 @@
SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt); void UnloadItem(SHELLNEW_ITEM *pItem); - void UnloadAllItems(); - BOOL LoadAllItems(); - UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu); - SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset); - HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici); - HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi); + void UnloadAllItems(); + BOOL CacheItems(); + BOOL LoadCachedItems(); + BOOL LoadAllItems(); + UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu); + SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset); + HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici); + HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi); HRESULT SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR pszName);
public: - CNewMenu(); - ~CNewMenu(); + CNewMenu(); + ~CNewMenu();
- // IObjectWithSite - virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite); - virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite); + // IObjectWithSite + virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite); + virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
- // IContextMenu - virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); - virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi); - virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen); + // IContextMenu + virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); + virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi); + virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
- // IContextMenu3 - virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult); + // IContextMenu3 + virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
- // IContextMenu2 - virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam); + // IContextMenu2 + virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
- // IShellExtInit - virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID); + // IShellExtInit + virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
DECLARE_REGISTRY_RESOURCEID(IDR_NEWMENU) DECLARE_NOT_AGGREGATABLE(CNewMenu) @@ -98,11 +102,11 @@ DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CNewMenu) - COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite) - COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3) - COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2) - COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu) - COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit) + COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite) + COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3) + COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2) + COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu) + COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit) END_COM_MAP() };