Release 1.5.29.
[wine] / dlls / explorerframe / explorerframe_main.c
1 /*
2  * ExplorerFrame main functions
3  *
4  * Copyright 2010 David Hedberg
5  *
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.
10  *
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.
15  *
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 St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winreg.h"
32 #include "shlwapi.h"
33 #include "shobjidl.h"
34 #include "rpcproxy.h"
35
36 #include "wine/debug.h"
37
38 #include "explorerframe_main.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(explorerframe);
41
42 HINSTANCE explorerframe_hinstance;
43 LONG EFRAME_refCount = 0;
44
45 /*************************************************************************
46  *              DllMain (ExplorerFrame.@)
47  */
48 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
49 {
50     TRACE("%p, 0x%x, %p\n", hinst, fdwReason, fImpLoad);
51     switch (fdwReason)
52     {
53     case DLL_PROCESS_ATTACH:
54         DisableThreadLibraryCalls(hinst);
55         explorerframe_hinstance = hinst;
56         break;
57     }
58     return TRUE;
59 }
60
61 /*************************************************************************
62  *              DllCanUnloadNow (ExplorerFrame.@)
63  */
64 HRESULT WINAPI DllCanUnloadNow(void)
65 {
66     TRACE("refCount is %d\n", EFRAME_refCount);
67     return EFRAME_refCount ? S_FALSE : S_OK;
68 }
69
70 /*************************************************************************
71  *              DllGetVersion (ExplorerFrame.@)
72  */
73 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *info)
74 {
75     TRACE("%p\n", info);
76     if(info->cbSize == sizeof(DLLVERSIONINFO) ||
77        info->cbSize == sizeof(DLLVERSIONINFO2))
78     {
79         /* Windows 7 */
80         info->dwMajorVersion = 6;
81         info->dwMinorVersion = 1;
82         info->dwBuildNumber = 7600;
83         info->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
84         if(info->cbSize == sizeof(DLLVERSIONINFO2))
85         {
86             DLLVERSIONINFO2 *info2 = (DLLVERSIONINFO2*)info;
87             info2->dwFlags = 0;
88             info2->ullVersion = MAKEDLLVERULL(info->dwMajorVersion,
89                                               info->dwMinorVersion,
90                                               info->dwBuildNumber,
91                                               16385); /* "hotfix number" */
92         }
93         return S_OK;
94     }
95
96     WARN("wrong DLLVERSIONINFO size from app.\n");
97     return E_INVALIDARG;
98 }
99
100 /*************************************************************************
101  * Implement the ExplorerFrame class factory
102  */
103
104 typedef struct
105 {
106     IClassFactory IClassFactory_iface;
107     HRESULT (*cf)(IUnknown*, REFIID, void**);
108     LONG ref;
109 } IClassFactoryImpl;
110
111 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
112 {
113     return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
114 }
115
116 /*************************************************************************
117  * EFCF_QueryInterface
118  */
119 static HRESULT WINAPI EFCF_QueryInterface(IClassFactory* iface,
120                                           REFIID riid, void **ppobj)
121 {
122     TRACE("%p (%s %p)\n", iface, debugstr_guid(riid), ppobj);
123
124     if(!ppobj)
125         return E_POINTER;
126
127     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid))
128     {
129         *ppobj = iface;
130         IClassFactory_AddRef(iface);
131         return S_OK;
132     }
133
134     WARN("Interface not supported.\n");
135
136     *ppobj = NULL;
137     return E_NOINTERFACE;
138 }
139
140 /*************************************************************************
141  * EFCF_AddRef
142  */
143 static ULONG WINAPI EFCF_AddRef(IClassFactory *iface)
144 {
145     EFRAME_LockModule();
146
147     return 2; /* non-heap based object */
148 }
149
150 /*************************************************************************
151  * EFCF_Release
152  */
153 static ULONG WINAPI EFCF_Release(IClassFactory *iface)
154 {
155     EFRAME_UnlockModule();
156
157     return 1; /* non-heap based object */
158 }
159
160 /*************************************************************************
161  * EFCF_CreateInstance (IClassFactory)
162  */
163 static HRESULT WINAPI EFCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
164                                           REFIID riid, void **ppobj)
165 {
166     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
167     return This->cf(pOuter, riid, ppobj);
168 }
169
170 /*************************************************************************
171  * EFCF_LockServer (IClassFactory)
172  */
173 static HRESULT WINAPI EFCF_LockServer(IClassFactory *iface, BOOL dolock)
174 {
175     TRACE("%p (%d)\n", iface, dolock);
176
177     if (dolock)
178         EFRAME_LockModule();
179     else
180         EFRAME_UnlockModule();
181
182     return S_OK;
183 }
184
185 static const IClassFactoryVtbl EFCF_Vtbl =
186 {
187     EFCF_QueryInterface,
188     EFCF_AddRef,
189     EFCF_Release,
190     EFCF_CreateInstance,
191     EFCF_LockServer
192 };
193
194 /*************************************************************************
195  *              DllGetClassObject (ExplorerFrame.@)
196  */
197 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
198 {
199     static IClassFactoryImpl NSTCClassFactory = {{&EFCF_Vtbl}, NamespaceTreeControl_Constructor};
200     static IClassFactoryImpl TaskbarListFactory = {{&EFCF_Vtbl}, TaskbarList_Constructor};
201
202     TRACE("%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
203
204     if(IsEqualGUID(&CLSID_NamespaceTreeControl, rclsid))
205         return IClassFactory_QueryInterface(&NSTCClassFactory.IClassFactory_iface, riid, ppv);
206
207     if(IsEqualGUID(&CLSID_TaskbarList, rclsid))
208         return IClassFactory_QueryInterface(&TaskbarListFactory.IClassFactory_iface, riid, ppv);
209
210     return CLASS_E_CLASSNOTAVAILABLE;
211 }
212
213 /*************************************************************************
214  *          DllRegisterServer (ExplorerFrame.@)
215  */
216 HRESULT WINAPI DllRegisterServer(void)
217 {
218     return __wine_register_resources( explorerframe_hinstance );
219 }
220
221 /*************************************************************************
222  *          DllUnregisterServer (ExplorerFrame.@)
223  */
224 HRESULT WINAPI DllUnregisterServer(void)
225 {
226     return __wine_unregister_resources( explorerframe_hinstance );
227 }