reactos/base/shell/rshell/misc.cpp

277 lines
7 KiB
C++
Raw Normal View History

/*
* 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
*/
#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>
#include <CQuickLaunchBand.h>
#include <wine/debug.h>
extern "C"
{
extern HINSTANCE shell32_hInstance;
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);
}
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:
};
CRShellModule gModule;
CAtlWinModule gWinModule;
HINSTANCE shell32_hInstance = NULL;
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;
if (!GetModuleFileNameW(shell32_hInstance, szFilename, _countof(szFilename)))
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;
}
STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
shell32_hInstance = hInstance;
gModule.Init(NULL, hInstance, NULL);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
shell32_hInstance = NULL;
gModule.Term();
}
return TRUE;
}
HRESULT
WINAPI
DllCanUnloadNow(void)
{
gModule.DllCanUnloadNow();
return S_FALSE;
}
STDAPI
DllRegisterServer(void)
{
#if 0
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");
RegisterComponent(CLSID_RebarBandSite, L"Shell Rebar Band Site");
#endif
RegisterComponent(CLSID_QuickLaunchBand, L"Quick Launch");
RegisterComCat();
return S_OK;
}
STDAPI
DllUnregisterServer(void)
{
#if 0
UnregisterComponent(CLSID_StartMenu);
UnregisterComponent(CLSID_MenuDeskBar);
UnregisterComponent(CLSID_MenuBand);
UnregisterComponent(CLSID_MenuBandSite);
UnregisterComponent(CLSID_MergedFolder);
UnregisterComponent(CLSID_RebarBandSite);
#endif
UnregisterComponent(CLSID_QuickLaunchBand);
UnregisterComCat();
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))
return RSHELL_CStartMenu_CreateInstance(riid, ppvObject);
if (IsEqualCLSID(m_Clsid, CLSID_MenuDeskBar))
return RSHELL_CMenuDeskBar_CreateInstance(riid, ppvObject);
if (IsEqualCLSID(m_Clsid, CLSID_MenuBand))
return RSHELL_CMenuBand_CreateInstance(riid, ppvObject);
if (IsEqualCLSID(m_Clsid, CLSID_MenuBandSite))
return RSHELL_CMenuSite_CreateInstance(riid, ppvObject);
if (IsEqualCLSID(m_Clsid, CLSID_MergedFolder))
return RSHELL_CMergedFolder_CreateInstance(riid, ppvObject);
if (IsEqualCLSID(m_Clsid, CLSID_QuickLaunchBand))
return ShellObjectCreator<CQuickLaunchBand>(riid, ppvObject);
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);
}