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 <wine/debug.h>
57 extern HINSTANCE shell32_hInstance
;
59 HRESULT WINAPI
CStartMenu_Constructor(REFIID riid
, void **ppv
);
60 HRESULT WINAPI
CMenuDeskBar_Constructor(REFIID riid
, LPVOID
*ppv
);
61 HRESULT WINAPI
CMenuSite_Constructor(REFIID riid
, LPVOID
*ppv
);
62 HRESULT WINAPI
CMenuBand_Constructor(REFIID riid
, LPVOID
*ppv
);
63 HRESULT WINAPI
CMergedFolder_Constructor(REFIID riid
, LPVOID
*ppv
);
64 HRESULT WINAPI
CBandSite_CreateInstance(REFIID riid
, void **ppv
);
65 HRESULT WINAPI
CBandSiteMenu_CreateInstance(REFIID riid
, void **ppv
);
68 DWORD WINAPI
WinList_Init(void)
70 /* do something here (perhaps we may want to add our own implementation fo win8) */
74 void *operator new (size_t, void *buf
)
79 class CRShellModule
: public CComModule
84 CRShellModule gModule
;
85 CAtlWinModule gWinModule
;
87 HINSTANCE shell32_hInstance
= NULL
;
89 static LSTATUS
inline _RegSetStringValueW(HKEY hKey
, LPCWSTR lpValueName
, LPCWSTR lpStringData
)
91 DWORD dwStringDataLen
= lstrlenW(lpStringData
);
93 return RegSetValueExW(hKey
, lpValueName
, 0, REG_SZ
, (BYTE
*) lpStringData
, 2 * (dwStringDataLen
+ 1));
96 static HRESULT
RegisterComponent(REFGUID clsid
, LPCWSTR szDisplayName
)
98 WCHAR szFilename
[MAX_PATH
];
99 WCHAR szClsid
[MAX_PATH
];
100 WCHAR szRoot
[MAX_PATH
];
102 if (!StringFromGUID2(clsid
, szClsid
, _countof(szClsid
)))
105 if (!GetModuleFileNameW(shell32_hInstance
, szFilename
, _countof(szFilename
)))
108 HRESULT hr
= StringCchPrintfW(szRoot
, 0x104u
, L
"CLSID\\%s", szClsid
);
114 if (RegCreateKeyExW(HKEY_CLASSES_ROOT
, szRoot
, 0, NULL
, 0, KEY_WRITE
, 0, &hkRoot
, &dwDisposition
) != 0)
119 _RegSetStringValueW(hkRoot
, NULL
, szDisplayName
);
121 if (RegCreateKeyExW(hkRoot
, L
"InprocServer32", 0, NULL
, 0, KEY_SET_VALUE
, 0, &hkServer
, &dwDisposition
) != 0)
127 _RegSetStringValueW(hkServer
, NULL
, szFilename
);
128 _RegSetStringValueW(hkServer
, L
"ThreadingModel", L
"Both");
130 RegCloseKey(hkServer
);
135 static HRESULT
UnregisterComponent(REFGUID clsid
)
137 WCHAR szClsid
[MAX_PATH
];
138 WCHAR szRoot
[MAX_PATH
];
141 if (!StringFromGUID2(clsid
, szClsid
, _countof(szClsid
)))
144 HRESULT hr
= StringCchPrintfW(szRoot
, 0x104u
, L
"CLSID\\%s", szClsid
);
148 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szRoot
, 0, KEY_WRITE
, &hkRoot
) != 0)
151 RegDeleteKeyW(hkRoot
, L
"InprocServer32");
154 RegDeleteKeyW(HKEY_CLASSES_ROOT
, szRoot
);
159 STDAPI_(BOOL
) DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID fImpLoad
)
161 if (dwReason
== DLL_PROCESS_ATTACH
)
163 shell32_hInstance
= hInstance
;
165 gModule
.Init(NULL
, hInstance
, NULL
);
166 DisableThreadLibraryCalls(hInstance
);
168 else if (dwReason
== DLL_PROCESS_DETACH
)
170 shell32_hInstance
= NULL
;
178 DllCanUnloadNow(void)
180 gModule
.DllCanUnloadNow();
185 DllRegisterServer(void)
187 RegisterComponent(CLSID_StartMenu
, L
"Shell Start Menu");
188 RegisterComponent(CLSID_MenuDeskBar
, L
"Shell Menu Desk Bar");
189 RegisterComponent(CLSID_MenuBand
, L
"Shell Menu Band");
190 RegisterComponent(CLSID_MenuBandSite
, L
"Shell Menu Band Site");
191 RegisterComponent(CLSID_MergedFolder
, L
"Merged Shell Folder");
192 RegisterComponent(CLSID_RebarBandSite
, L
"Shell Rebar Band Site");
197 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
);
208 class CRShellClassFactory
:
209 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
216 CRShellClassFactory() {}
217 virtual ~CRShellClassFactory() {}
219 HRESULT
Initialize(REFGUID clsid
)
226 virtual HRESULT WINAPI
CreateInstance(LPUNKNOWN pUnkOuter
, REFIID riid
, LPVOID
*ppvObject
)
230 if (IsEqualCLSID(m_Clsid
, CLSID_StartMenu
))
231 return CStartMenu_Constructor(riid
, ppvObject
);
233 if (IsEqualCLSID(m_Clsid
, CLSID_MenuDeskBar
))
234 return CMenuDeskBar_Constructor(riid
, ppvObject
);
236 if (IsEqualCLSID(m_Clsid
, CLSID_MenuBand
))
237 return CMenuBand_Constructor(riid
, ppvObject
);
239 if (IsEqualCLSID(m_Clsid
, CLSID_MenuBandSite
))
240 return CMenuSite_Constructor(riid
, ppvObject
);
242 if (IsEqualCLSID(m_Clsid
, CLSID_MergedFolder
))
243 return CMergedFolder_Constructor(riid
, ppvObject
);
245 return E_NOINTERFACE
;
248 virtual HRESULT WINAPI
LockServer(BOOL fLock
)
253 BEGIN_COM_MAP(CRShellClassFactory
)
254 COM_INTERFACE_ENTRY_IID(IID_IClassFactory
, IClassFactory
)
269 return ShellObjectCreatorInit
<CRShellClassFactory
>(rclsid
, riid
, ppv
);