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
);
66 DWORD WINAPI
WinList_Init(void)
68 /* do something here (perhaps we may want to add our own implementation fo win8) */
72 void *operator new (size_t, void *buf
)
77 class CRShellModule
: public CComModule
82 CRShellModule gModule
;
83 CAtlWinModule gWinModule
;
85 HINSTANCE shell32_hInstance
= NULL
;
87 static LSTATUS
inline _RegSetStringValueW(HKEY hKey
, LPCWSTR lpValueName
, LPCWSTR lpStringData
)
89 DWORD dwStringDataLen
= lstrlenW(lpStringData
);
91 return RegSetValueExW(hKey
, lpValueName
, 0, REG_SZ
, (BYTE
*) lpStringData
, 2 * (dwStringDataLen
+ 1));
94 static HRESULT
RegisterComponent(REFGUID clsid
, LPCWSTR szDisplayName
)
96 WCHAR szFilename
[MAX_PATH
];
97 WCHAR szClsid
[MAX_PATH
];
98 WCHAR szRoot
[MAX_PATH
];
100 if (!StringFromGUID2(clsid
, szClsid
, _countof(szClsid
)))
103 if (!GetModuleFileNameW(shell32_hInstance
, szFilename
, _countof(szFilename
)))
106 HRESULT hr
= StringCchPrintfW(szRoot
, 0x104u
, L
"CLSID\\%s", szClsid
);
112 if (RegCreateKeyExW(HKEY_CLASSES_ROOT
, szRoot
, 0, NULL
, 0, KEY_WRITE
, 0, &hkRoot
, &dwDisposition
) != 0)
117 _RegSetStringValueW(hkRoot
, NULL
, szDisplayName
);
119 if (RegCreateKeyExW(hkRoot
, L
"InprocServer32", 0, NULL
, 0, KEY_SET_VALUE
, 0, &hkServer
, &dwDisposition
) != 0)
125 _RegSetStringValueW(hkServer
, NULL
, szFilename
);
126 _RegSetStringValueW(hkServer
, L
"ThreadingModel", L
"Both");
128 RegCloseKey(hkServer
);
133 static HRESULT
UnregisterComponent(REFGUID clsid
)
135 WCHAR szClsid
[MAX_PATH
];
136 WCHAR szRoot
[MAX_PATH
];
139 if (!StringFromGUID2(clsid
, szClsid
, _countof(szClsid
)))
142 HRESULT hr
= StringCchPrintfW(szRoot
, 0x104u
, L
"CLSID\\%s", szClsid
);
146 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szRoot
, 0, KEY_WRITE
, &hkRoot
) != 0)
149 RegDeleteKeyW(hkRoot
, L
"InprocServer32");
152 RegDeleteKeyW(HKEY_CLASSES_ROOT
, szRoot
);
157 STDAPI_(BOOL
) DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID fImpLoad
)
159 if (dwReason
== DLL_PROCESS_ATTACH
)
161 shell32_hInstance
= hInstance
;
163 gModule
.Init(NULL
, hInstance
, NULL
);
164 DisableThreadLibraryCalls(hInstance
);
166 else if (dwReason
== DLL_PROCESS_DETACH
)
168 shell32_hInstance
= NULL
;
176 DllCanUnloadNow(void)
178 gModule
.DllCanUnloadNow();
183 DllRegisterServer(void)
185 RegisterComponent(CLSID_StartMenu
, L
"Shell Start Menu");
186 RegisterComponent(CLSID_MenuDeskBar
, L
"Shell Menu Desk Bar");
187 RegisterComponent(CLSID_MenuBand
, L
"Shell Menu Band");
188 RegisterComponent(CLSID_MenuBandSite
, L
"Shell Menu Band Site");
189 RegisterComponent(CLSID_MergedFolder
, L
"Merged Shell Folder");
190 RegisterComponent(CLSID_RebarBandSite
, L
"Shell Rebar Band Site");
195 DllUnregisterServer(void)
197 UnregisterComponent(CLSID_StartMenu
);
198 UnregisterComponent(CLSID_MenuDeskBar
);
199 UnregisterComponent(CLSID_MenuBand
);
200 UnregisterComponent(CLSID_MenuBandSite
);
201 UnregisterComponent(CLSID_MergedFolder
);
202 UnregisterComponent(CLSID_RebarBandSite
);
206 class CRShellClassFactory
:
207 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
214 CRShellClassFactory() {}
215 virtual ~CRShellClassFactory() {}
217 HRESULT
Initialize(REFGUID clsid
)
224 virtual HRESULT WINAPI
CreateInstance(LPUNKNOWN pUnkOuter
, REFIID riid
, LPVOID
*ppvObject
)
228 if (IsEqualCLSID(m_Clsid
, CLSID_StartMenu
))
229 return CStartMenu_Constructor(riid
, ppvObject
);
231 if (IsEqualCLSID(m_Clsid
, CLSID_MenuDeskBar
))
232 return CMenuDeskBar_Constructor(riid
, ppvObject
);
234 if (IsEqualCLSID(m_Clsid
, CLSID_MenuBand
))
235 return CMenuBand_Constructor(riid
, ppvObject
);
237 if (IsEqualCLSID(m_Clsid
, CLSID_MenuBandSite
))
238 return CMenuSite_Constructor(riid
, ppvObject
);
240 if (IsEqualCLSID(m_Clsid
, CLSID_MergedFolder
))
241 return CMergedFolder_Constructor(riid
, ppvObject
);
243 return E_NOINTERFACE
;
246 virtual HRESULT WINAPI
LockServer(BOOL fLock
)
251 BEGIN_COM_MAP(CRShellClassFactory
)
252 COM_INTERFACE_ENTRY_IID(IID_IClassFactory
, IClassFactory
)
267 return ShellObjectCreatorInit
<CRShellClassFactory
>(rclsid
, riid
, ppv
);