2014-02-04 12:11:51 +00:00
|
|
|
/*
|
|
|
|
* ReactOS Explorer
|
|
|
|
*
|
|
|
|
* Copyright 2014 Giannis Adamopoulos
|
|
|
|
*
|
|
|
|
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
2017-04-09 15:10:08 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <tchar.h>
|
|
|
|
|
|
|
|
#define WIN32_NO_STATUS
|
|
|
|
#define _INC_WINDOWS
|
|
|
|
#define COM_NO_WINDOWS_H
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
|
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
#include <winreg.h>
|
|
|
|
#include <wingdi.h>
|
|
|
|
#include <winnls.h>
|
|
|
|
#include <wincon.h>
|
|
|
|
#include <shellapi.h>
|
|
|
|
#include <shlobj.h>
|
|
|
|
#include <shlobj_undoc.h>
|
|
|
|
#include <shlwapi.h>
|
|
|
|
#include <shlguid_undoc.h>
|
|
|
|
#include <uxtheme.h>
|
|
|
|
#include <strsafe.h>
|
|
|
|
|
|
|
|
#include <atlbase.h>
|
|
|
|
#include <atlcom.h>
|
|
|
|
#include <atlwin.h>
|
|
|
|
#include <undocshell.h>
|
|
|
|
#include <undocuser.h>
|
|
|
|
|
|
|
|
#include <shellutils.h>
|
|
|
|
|
2017-10-16 20:56:34 +00:00
|
|
|
#include <CQuickLaunchBand.h>
|
|
|
|
|
2017-04-09 15:10:08 +00:00
|
|
|
#include <wine/debug.h>
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
extern HINSTANCE shell32_hInstance;
|
|
|
|
|
2017-06-19 14:27:51 +00:00
|
|
|
HRESULT WINAPI RSHELL_CStartMenu_CreateInstance(REFIID riid, void **ppv);
|
|
|
|
HRESULT WINAPI RSHELL_CMenuDeskBar_CreateInstance(REFIID riid, LPVOID *ppv);
|
|
|
|
HRESULT WINAPI RSHELL_CMenuSite_CreateInstance(REFIID riid, LPVOID *ppv);
|
|
|
|
HRESULT WINAPI RSHELL_CMenuBand_CreateInstance(REFIID riid, LPVOID *ppv);
|
|
|
|
HRESULT WINAPI RSHELL_CMergedFolder_CreateInstance(REFIID riid, LPVOID *ppv);
|
2017-04-09 15:10:08 +00:00
|
|
|
}
|
2014-02-04 12:11:51 +00:00
|
|
|
|
|
|
|
DWORD WINAPI WinList_Init(void)
|
|
|
|
{
|
|
|
|
/* do something here (perhaps we may want to add our own implementation fo win8) */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
class CRShellModule : public CComModule
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
};
|
|
|
|
|
2016-06-04 22:50:33 +00:00
|
|
|
CRShellModule gModule;
|
|
|
|
CAtlWinModule gWinModule;
|
2014-02-04 12:11:51 +00:00
|
|
|
|
2016-06-04 22:50:33 +00:00
|
|
|
HINSTANCE shell32_hInstance = NULL;
|
2014-12-20 16:04:45 +00:00
|
|
|
|
|
|
|
static LSTATUS inline _RegSetStringValueW(HKEY hKey, LPCWSTR lpValueName, LPCWSTR lpStringData)
|
|
|
|
{
|
|
|
|
DWORD dwStringDataLen = lstrlenW(lpStringData);
|
|
|
|
|
|
|
|
return RegSetValueExW(hKey, lpValueName, 0, REG_SZ, (BYTE *) lpStringData, 2 * (dwStringDataLen + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT RegisterComponent(REFGUID clsid, LPCWSTR szDisplayName)
|
|
|
|
{
|
|
|
|
WCHAR szFilename[MAX_PATH];
|
|
|
|
WCHAR szClsid[MAX_PATH];
|
|
|
|
WCHAR szRoot[MAX_PATH];
|
|
|
|
|
|
|
|
if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
|
|
|
|
return E_FAIL;
|
|
|
|
|
2016-06-04 22:50:33 +00:00
|
|
|
if (!GetModuleFileNameW(shell32_hInstance, szFilename, _countof(szFilename)))
|
2014-12-20 16:04:45 +00:00
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
|
|
|
|
if (FAILED(hr))
|
|
|
|
return hr;
|
|
|
|
|
|
|
|
DWORD dwDisposition;
|
|
|
|
HKEY hkRoot;
|
|
|
|
if (RegCreateKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, NULL, 0, KEY_WRITE, 0, &hkRoot, &dwDisposition) != 0)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
HKEY hkServer;
|
|
|
|
|
|
|
|
_RegSetStringValueW(hkRoot, NULL, szDisplayName);
|
|
|
|
|
|
|
|
if (RegCreateKeyExW(hkRoot, L"InprocServer32", 0, NULL, 0, KEY_SET_VALUE, 0, &hkServer, &dwDisposition) != 0)
|
|
|
|
{
|
|
|
|
RegCloseKey(hkRoot);
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
_RegSetStringValueW(hkServer, NULL, szFilename);
|
|
|
|
_RegSetStringValueW(hkServer, L"ThreadingModel", L"Both");
|
|
|
|
|
|
|
|
RegCloseKey(hkServer);
|
|
|
|
RegCloseKey(hkRoot);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT UnregisterComponent(REFGUID clsid)
|
|
|
|
{
|
|
|
|
WCHAR szClsid[MAX_PATH];
|
|
|
|
WCHAR szRoot[MAX_PATH];
|
|
|
|
HKEY hkRoot;
|
|
|
|
|
|
|
|
if (!StringFromGUID2(clsid, szClsid, _countof(szClsid)))
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
HRESULT hr = StringCchPrintfW(szRoot, 0x104u, L"CLSID\\%s", szClsid);
|
|
|
|
if (FAILED(hr))
|
|
|
|
return hr;
|
|
|
|
|
|
|
|
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szRoot, 0, KEY_WRITE, &hkRoot) != 0)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
RegDeleteKeyW(hkRoot, L"InprocServer32");
|
|
|
|
RegCloseKey(hkRoot);
|
|
|
|
|
|
|
|
RegDeleteKeyW(HKEY_CLASSES_ROOT, szRoot);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2014-02-04 12:11:51 +00:00
|
|
|
STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
|
|
|
|
{
|
|
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
|
|
{
|
2016-06-04 22:50:33 +00:00
|
|
|
shell32_hInstance = hInstance;
|
2014-12-20 16:04:45 +00:00
|
|
|
|
2014-02-04 12:11:51 +00:00
|
|
|
gModule.Init(NULL, hInstance, NULL);
|
2014-03-26 11:33:52 +00:00
|
|
|
DisableThreadLibraryCalls(hInstance);
|
2014-02-04 12:11:51 +00:00
|
|
|
}
|
|
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
|
|
{
|
2016-06-04 22:50:33 +00:00
|
|
|
shell32_hInstance = NULL;
|
2014-02-04 12:11:51 +00:00
|
|
|
gModule.Term();
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
2014-12-20 16:04:45 +00:00
|
|
|
|
|
|
|
HRESULT
|
|
|
|
WINAPI
|
|
|
|
DllCanUnloadNow(void)
|
|
|
|
{
|
|
|
|
gModule.DllCanUnloadNow();
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDAPI
|
|
|
|
DllRegisterServer(void)
|
|
|
|
{
|
2017-10-16 20:56:34 +00:00
|
|
|
#if 0
|
2014-12-20 16:04:45 +00:00
|
|
|
RegisterComponent(CLSID_StartMenu, L"Shell Start Menu");
|
|
|
|
RegisterComponent(CLSID_MenuDeskBar, L"Shell Menu Desk Bar");
|
|
|
|
RegisterComponent(CLSID_MenuBand, L"Shell Menu Band");
|
|
|
|
RegisterComponent(CLSID_MenuBandSite, L"Shell Menu Band Site");
|
|
|
|
RegisterComponent(CLSID_MergedFolder, L"Merged Shell Folder");
|
2014-12-24 17:00:53 +00:00
|
|
|
RegisterComponent(CLSID_RebarBandSite, L"Shell Rebar Band Site");
|
2017-10-16 20:56:34 +00:00
|
|
|
#endif
|
|
|
|
RegisterComponent(CLSID_QuickLaunchBand, L"Quick Launch");
|
|
|
|
RegisterComCat();
|
2014-12-20 16:04:45 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
STDAPI
|
|
|
|
DllUnregisterServer(void)
|
|
|
|
{
|
2017-10-16 20:56:34 +00:00
|
|
|
#if 0
|
2014-12-20 16:04:45 +00:00
|
|
|
UnregisterComponent(CLSID_StartMenu);
|
|
|
|
UnregisterComponent(CLSID_MenuDeskBar);
|
|
|
|
UnregisterComponent(CLSID_MenuBand);
|
|
|
|
UnregisterComponent(CLSID_MenuBandSite);
|
|
|
|
UnregisterComponent(CLSID_MergedFolder);
|
2014-12-24 17:00:53 +00:00
|
|
|
UnregisterComponent(CLSID_RebarBandSite);
|
2017-10-16 20:56:34 +00:00
|
|
|
#endif
|
|
|
|
UnregisterComponent(CLSID_QuickLaunchBand);
|
|
|
|
UnregisterComCat();
|
2014-12-20 16:04:45 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
class CRShellClassFactory :
|
|
|
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
|
|
public IClassFactory
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
CLSID m_Clsid;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CRShellClassFactory() {}
|
|
|
|
virtual ~CRShellClassFactory() {}
|
|
|
|
|
|
|
|
HRESULT Initialize(REFGUID clsid)
|
|
|
|
{
|
|
|
|
m_Clsid = clsid;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* IClassFactory */
|
|
|
|
virtual HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
|
|
|
|
{
|
|
|
|
*ppvObject = NULL;
|
|
|
|
|
|
|
|
if (IsEqualCLSID(m_Clsid, CLSID_StartMenu))
|
2017-06-19 14:27:51 +00:00
|
|
|
return RSHELL_CStartMenu_CreateInstance(riid, ppvObject);
|
2014-12-20 16:04:45 +00:00
|
|
|
|
|
|
|
if (IsEqualCLSID(m_Clsid, CLSID_MenuDeskBar))
|
2017-06-19 14:27:51 +00:00
|
|
|
return RSHELL_CMenuDeskBar_CreateInstance(riid, ppvObject);
|
2014-12-20 16:04:45 +00:00
|
|
|
|
|
|
|
if (IsEqualCLSID(m_Clsid, CLSID_MenuBand))
|
2017-06-19 14:27:51 +00:00
|
|
|
return RSHELL_CMenuBand_CreateInstance(riid, ppvObject);
|
2014-12-20 16:04:45 +00:00
|
|
|
|
|
|
|
if (IsEqualCLSID(m_Clsid, CLSID_MenuBandSite))
|
2017-06-19 14:27:51 +00:00
|
|
|
return RSHELL_CMenuSite_CreateInstance(riid, ppvObject);
|
2014-12-20 16:04:45 +00:00
|
|
|
|
|
|
|
if (IsEqualCLSID(m_Clsid, CLSID_MergedFolder))
|
2017-06-19 14:27:51 +00:00
|
|
|
return RSHELL_CMergedFolder_CreateInstance(riid, ppvObject);
|
2014-12-20 16:04:45 +00:00
|
|
|
|
2017-10-16 20:56:34 +00:00
|
|
|
if (IsEqualCLSID(m_Clsid, CLSID_QuickLaunchBand))
|
|
|
|
return ShellObjectCreator<CQuickLaunchBand>(riid, ppvObject);
|
|
|
|
|
2014-12-20 16:04:45 +00:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual HRESULT WINAPI LockServer(BOOL fLock)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
BEGIN_COM_MAP(CRShellClassFactory)
|
|
|
|
COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory)
|
|
|
|
END_COM_MAP()
|
|
|
|
};
|
|
|
|
|
|
|
|
STDAPI
|
|
|
|
DllGetClassObject(
|
|
|
|
REFCLSID rclsid,
|
|
|
|
REFIID riid,
|
|
|
|
LPVOID *ppv)
|
|
|
|
{
|
|
|
|
if (!ppv)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
*ppv = NULL;
|
|
|
|
|
|
|
|
return ShellObjectCreatorInit<CRShellClassFactory>(rclsid, riid, ppv);
|
|
|
|
}
|