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/CMakeLists.txt?rev=65757&r1=65756&r2=65757&view=diff
==============================================================================
--- 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?rev=65757&r1=65756&r2=65757&view=diff
==============================================================================
--- 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.spec?rev=65757&r1=65756&r2=65757&view=diff
==============================================================================
--- 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);


Reply via email to