Author: dquintana
Date: Sat Dec 20 16:04:45 2014
New Revision: 65757
URL:
http://svn.reactos.org/svn/reactos?rev=65757&view=rev
Log:
[RSHELL]
* Make rshell.dll able to register its classes and support CoCreateInstance.
Modified:
trunk/reactos/base/shell/rshell/CMakeLists.txt
trunk/reactos/base/shell/rshell/misc.cpp
trunk/reactos/base/shell/rshell/rshell.spec
Modified: trunk/reactos/base/shell/rshell/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/rshell/CMakeLis…
==============================================================================
--- trunk/reactos/base/shell/rshell/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/shell/rshell/CMakeLists.txt [iso-8859-1] Sat Dec 20 16:04:45 2014
@@ -31,6 +31,7 @@
add_importlibs(rshell
uxtheme
shlwapi
+ advapi32
shell32
comctl32
gdi32
Modified: trunk/reactos/base/shell/rshell/misc.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/rshell/misc.cpp…
==============================================================================
--- trunk/reactos/base/shell/rshell/misc.cpp [iso-8859-1] (original)
+++ trunk/reactos/base/shell/rshell/misc.cpp [iso-8859-1] Sat Dec 20 16:04:45 2014
@@ -39,10 +39,84 @@
CRShellModule gModule;
CAtlWinModule gWinModule;
+HINSTANCE g_hRShell;
+
+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(g_hRShell, 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)
{
+ g_hRShell = hInstance;
+
/* HACK - the global constructors don't run, so I placement new them here */
new (&gModule) CRShellModule;
new (&gWinModule) CAtlWinModule;
@@ -58,3 +132,97 @@
}
return TRUE;
}
+
+HRESULT
+WINAPI
+DllCanUnloadNow(void)
+{
+ gModule.DllCanUnloadNow();
+ return S_FALSE;
+}
+
+STDAPI
+DllRegisterServer(void)
+{
+ 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");
+ return S_OK;
+}
+
+STDAPI
+DllUnregisterServer(void)
+{
+ UnregisterComponent(CLSID_StartMenu);
+ UnregisterComponent(CLSID_MenuDeskBar);
+ UnregisterComponent(CLSID_MenuBand);
+ UnregisterComponent(CLSID_MenuBandSite);
+ UnregisterComponent(CLSID_MergedFolder);
+ 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 CStartMenu_Constructor(riid, ppvObject);
+
+ if (IsEqualCLSID(m_Clsid, CLSID_MenuDeskBar))
+ return CMenuDeskBar_Constructor(riid, ppvObject);
+
+ if (IsEqualCLSID(m_Clsid, CLSID_MenuBand))
+ return CMenuBand_Constructor(riid, ppvObject);
+
+ if (IsEqualCLSID(m_Clsid, CLSID_MenuBandSite))
+ return CMenuSite_Constructor(riid, ppvObject);
+
+ if (IsEqualCLSID(m_Clsid, CLSID_MergedFolder))
+ return CMergedFolder_Constructor(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);
+}
Modified: trunk/reactos/base/shell/rshell/rshell.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/rshell/rshell.s…
==============================================================================
--- trunk/reactos/base/shell/rshell/rshell.spec [iso-8859-1] (original)
+++ trunk/reactos/base/shell/rshell/rshell.spec [iso-8859-1] Sat Dec 20 16:04:45 2014
@@ -1,3 +1,7 @@
+@ stdcall DllCanUnloadNow()
+@ stdcall DllGetClassObject(ptr ptr ptr)
+@ stdcall DllRegisterServer()
+@ stdcall DllUnregisterServer()
@ stdcall CStartMenu_Constructor(ptr ptr)
@ stdcall CMenuDeskBar_Constructor(ptr ptr);
@ stdcall CMenuSite_Constructor(ptr ptr);