4 * Copyright 2014 Giannis Adamopoulos
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #define WIN32_NO_STATUS
27 #define COM_NO_WINDOWS_H
39 #include <shlobj_undoc.h>
41 #include <shlguid_undoc.h>
48 #include <undocshell.h>
49 #include <undocuser.h>
51 #include <shellutils.h>
53 #include <CQuickLaunchBand.h>
55 #include <wine/debug.h>
59 extern HINSTANCE shell32_hInstance
;
61 HRESULT WINAPI
RSHELL_CStartMenu_CreateInstance(REFIID riid
, void **ppv
);
62 HRESULT WINAPI
RSHELL_CMenuDeskBar_CreateInstance(REFIID riid
, LPVOID
*ppv
);
63 HRESULT WINAPI
RSHELL_CMenuSite_CreateInstance(REFIID riid
, LPVOID
*ppv
);
64 HRESULT WINAPI
RSHELL_CMenuBand_CreateInstance(REFIID riid
, LPVOID
*ppv
);
65 HRESULT WINAPI
RSHELL_CMergedFolder_CreateInstance(REFIID riid
, LPVOID
*ppv
);
68 DWORD WINAPI
WinList_Init(void)
70 /* do something here (perhaps we may want to add our own implementation fo win8) */
74 class CRShellModule
: public CComModule
79 CRShellModule gModule
;
80 CAtlWinModule gWinModule
;
82 HINSTANCE shell32_hInstance
= NULL
;
84 static LSTATUS
inline _RegSetStringValueW(HKEY hKey
, LPCWSTR lpValueName
, LPCWSTR lpStringData
)
86 DWORD dwStringDataLen
= lstrlenW(lpStringData
);
88 return RegSetValueExW(hKey
, lpValueName
, 0, REG_SZ
, (BYTE
*) lpStringData
, 2 * (dwStringDataLen
+ 1));
91 static HRESULT
RegisterComponent(REFGUID clsid
, LPCWSTR szDisplayName
)
93 WCHAR szFilename
[MAX_PATH
];
94 WCHAR szClsid
[MAX_PATH
];
95 WCHAR szRoot
[MAX_PATH
];
97 if (!StringFromGUID2(clsid
, szClsid
, _countof(szClsid
)))
100 if (!GetModuleFileNameW(shell32_hInstance
, szFilename
, _countof(szFilename
)))
103 HRESULT hr
= StringCchPrintfW(szRoot
, 0x104u
, L
"CLSID\\%s", szClsid
);
109 if (RegCreateKeyExW(HKEY_CLASSES_ROOT
, szRoot
, 0, NULL
, 0, KEY_WRITE
, 0, &hkRoot
, &dwDisposition
) != 0)
114 _RegSetStringValueW(hkRoot
, NULL
, szDisplayName
);
116 if (RegCreateKeyExW(hkRoot
, L
"InprocServer32", 0, NULL
, 0, KEY_SET_VALUE
, 0, &hkServer
, &dwDisposition
) != 0)
122 _RegSetStringValueW(hkServer
, NULL
, szFilename
);
123 _RegSetStringValueW(hkServer
, L
"ThreadingModel", L
"Both");
125 RegCloseKey(hkServer
);
130 static HRESULT
UnregisterComponent(REFGUID clsid
)
132 WCHAR szClsid
[MAX_PATH
];
133 WCHAR szRoot
[MAX_PATH
];
136 if (!StringFromGUID2(clsid
, szClsid
, _countof(szClsid
)))
139 HRESULT hr
= StringCchPrintfW(szRoot
, 0x104u
, L
"CLSID\\%s", szClsid
);
143 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szRoot
, 0, KEY_WRITE
, &hkRoot
) != 0)
146 RegDeleteKeyW(hkRoot
, L
"InprocServer32");
149 RegDeleteKeyW(HKEY_CLASSES_ROOT
, szRoot
);
154 STDAPI_(BOOL
) DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID fImpLoad
)
156 if (dwReason
== DLL_PROCESS_ATTACH
)
158 shell32_hInstance
= hInstance
;
160 gModule
.Init(NULL
, hInstance
, NULL
);
161 DisableThreadLibraryCalls(hInstance
);
163 else if (dwReason
== DLL_PROCESS_DETACH
)
165 shell32_hInstance
= NULL
;
173 DllCanUnloadNow(void)
175 gModule
.DllCanUnloadNow();
180 DllRegisterServer(void)
183 RegisterComponent(CLSID_StartMenu
, L
"Shell Start Menu");
184 RegisterComponent(CLSID_MenuDeskBar
, L
"Shell Menu Desk Bar");
185 RegisterComponent(CLSID_MenuBand
, L
"Shell Menu Band");
186 RegisterComponent(CLSID_MenuBandSite
, L
"Shell Menu Band Site");
187 RegisterComponent(CLSID_MergedFolder
, L
"Merged Shell Folder");
188 RegisterComponent(CLSID_RebarBandSite
, L
"Shell Rebar Band Site");
190 RegisterComponent(CLSID_QuickLaunchBand
, L
"Quick Launch");
196 DllUnregisterServer(void)
199 UnregisterComponent(CLSID_StartMenu
);
200 UnregisterComponent(CLSID_MenuDeskBar
);
201 UnregisterComponent(CLSID_MenuBand
);
202 UnregisterComponent(CLSID_MenuBandSite
);
203 UnregisterComponent(CLSID_MergedFolder
);
204 UnregisterComponent(CLSID_RebarBandSite
);
206 UnregisterComponent(CLSID_QuickLaunchBand
);
211 class CRShellClassFactory
:
212 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
219 CRShellClassFactory() {}
220 virtual ~CRShellClassFactory() {}
222 HRESULT
Initialize(REFGUID clsid
)
229 virtual HRESULT WINAPI
CreateInstance(LPUNKNOWN pUnkOuter
, REFIID riid
, LPVOID
*ppvObject
)
233 if (IsEqualCLSID(m_Clsid
, CLSID_StartMenu
))
234 return RSHELL_CStartMenu_CreateInstance(riid
, ppvObject
);
236 if (IsEqualCLSID(m_Clsid
, CLSID_MenuDeskBar
))
237 return RSHELL_CMenuDeskBar_CreateInstance(riid
, ppvObject
);
239 if (IsEqualCLSID(m_Clsid
, CLSID_MenuBand
))
240 return RSHELL_CMenuBand_CreateInstance(riid
, ppvObject
);
242 if (IsEqualCLSID(m_Clsid
, CLSID_MenuBandSite
))
243 return RSHELL_CMenuSite_CreateInstance(riid
, ppvObject
);
245 if (IsEqualCLSID(m_Clsid
, CLSID_MergedFolder
))
246 return RSHELL_CMergedFolder_CreateInstance(riid
, ppvObject
);
248 if (IsEqualCLSID(m_Clsid
, CLSID_QuickLaunchBand
))
249 return ShellObjectCreator
<CQuickLaunchBand
>(riid
, ppvObject
);
251 return E_NOINTERFACE
;
254 virtual HRESULT WINAPI
LockServer(BOOL fLock
)
259 BEGIN_COM_MAP(CRShellClassFactory
)
260 COM_INTERFACE_ENTRY_IID(IID_IClassFactory
, IClassFactory
)
275 return ShellObjectCreatorInit
<CRShellClassFactory
>(rclsid
, riid
, ppv
);