Synchronize with trunk r58528.
[reactos.git] / dll / win32 / sti / sti_main.c
1 /*
2 * Copyright (C) 2002 Aric Stewart for CodeWeavers
3 * Copyright (C) 2009 Damjan Jovanovic
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #define WIN32_NO_STATUS
21 #define _INC_WINDOWS
22 #define COM_NO_WINDOWS_H
23
24 #include <stdarg.h>
25
26 #define COBJMACROS
27
28 #include <windef.h>
29 #include <winbase.h>
30 //#include "winreg.h"
31 //#include "winerror.h"
32 //#include "objbase.h"
33 #include <initguid.h>
34 //#include "wia_lh.h"
35 #include <sti.h>
36
37 #include <wine/debug.h>
38
39 WINE_DEFAULT_DEBUG_CHANNEL(sti);
40
41 extern HRESULT WINAPI STI_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
42 extern BOOL WINAPI STI_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
43 extern HRESULT WINAPI STI_DllRegisterServer(void) DECLSPEC_HIDDEN;
44 extern HRESULT WINAPI STI_DllUnregisterServer(void) DECLSPEC_HIDDEN;
45
46 typedef HRESULT (*fnCreateInstance)(REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj);
47
48 typedef struct
49 {
50 IClassFactory IClassFactory_iface;
51 fnCreateInstance pfnCreateInstance;
52 } sti_cf;
53
54 static inline sti_cf *impl_from_IClassFactory( IClassFactory *iface )
55 {
56 return CONTAINING_RECORD(iface, sti_cf, IClassFactory_iface);
57 }
58
59 static HRESULT sti_create( REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj )
60 {
61 if (pUnkOuter != NULL && !IsEqualIID(riid, &IID_IUnknown))
62 return CLASS_E_NOAGGREGATION;
63
64 if (IsEqualGUID(riid, &IID_IUnknown))
65 return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, pUnkOuter);
66 else if (IsEqualGUID(riid, &IID_IStillImageW))
67 return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, NULL);
68 else if (IsEqualGUID(riid, &IID_IStillImageA))
69 return StiCreateInstanceA(GetCurrentProcess(), STI_VERSION_REAL, (PSTIA*) ppObj, NULL);
70 else
71 {
72 FIXME("no interface %s\n", debugstr_guid(riid));
73 return E_NOINTERFACE;
74 }
75 }
76
77 static HRESULT WINAPI sti_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj )
78 {
79 if (IsEqualGUID(riid, &IID_IUnknown) ||
80 IsEqualGUID(riid, &IID_IClassFactory))
81 {
82 IClassFactory_AddRef( iface );
83 *ppobj = iface;
84 return S_OK;
85 }
86 FIXME("interface %s not implemented\n", debugstr_guid(riid));
87 return E_NOINTERFACE;
88 }
89
90 static ULONG WINAPI sti_cf_AddRef( IClassFactory *iface )
91 {
92 return 2;
93 }
94
95 static ULONG WINAPI sti_cf_Release( IClassFactory *iface )
96 {
97 return 1;
98 }
99
100 static HRESULT WINAPI sti_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter,
101 REFIID riid, LPVOID *ppobj )
102 {
103 sti_cf *This = impl_from_IClassFactory( iface );
104 HRESULT r;
105 IUnknown *punk;
106
107 TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj);
108
109 *ppobj = NULL;
110
111 r = This->pfnCreateInstance( riid, pOuter, (LPVOID *)&punk );
112 if (FAILED(r))
113 return r;
114
115 r = IUnknown_QueryInterface( punk, riid, ppobj );
116 if (FAILED(r))
117 return r;
118
119 IUnknown_Release( punk );
120 return r;
121 }
122
123 static HRESULT WINAPI sti_cf_LockServer( IClassFactory *iface, BOOL dolock )
124 {
125 FIXME("(%p)->(%d)\n", iface, dolock);
126 return S_OK;
127 }
128
129 static const struct IClassFactoryVtbl sti_cf_vtbl =
130 {
131 sti_cf_QueryInterface,
132 sti_cf_AddRef,
133 sti_cf_Release,
134 sti_cf_CreateInstance,
135 sti_cf_LockServer
136 };
137
138 static sti_cf the_sti_cf = { { &sti_cf_vtbl }, sti_create };
139
140 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
141 {
142 TRACE("(0x%p, %d, %p)\n",hInstDLL,fdwReason,lpvReserved);
143
144 if (fdwReason == DLL_WINE_PREATTACH)
145 return FALSE;
146 return STI_DllMain(hInstDLL, fdwReason, lpvReserved);
147 }
148
149 /******************************************************************************
150 * DllGetClassObject (STI.@)
151 */
152 HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
153 {
154 IClassFactory *cf = NULL;
155
156 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
157
158 if (IsEqualGUID( rclsid, &CLSID_Sti ))
159 {
160 cf = &the_sti_cf.IClassFactory_iface;
161 }
162
163 if (cf)
164 return IClassFactory_QueryInterface( cf, iid, ppv );
165 return STI_DllGetClassObject( rclsid, iid, ppv );
166 }
167
168 /******************************************************************************
169 * DllCanUnloadNow (STI.@)
170 */
171 HRESULT WINAPI DllCanUnloadNow( void )
172 {
173 return S_FALSE;
174 }
175
176 /***********************************************************************
177 * DllRegisterServer (STI.@)
178 */
179 HRESULT WINAPI DllRegisterServer(void)
180 {
181 return STI_DllRegisterServer();
182 }
183
184 /***********************************************************************
185 * DllUnRegisterServer (STI.@)
186 */
187 HRESULT WINAPI DllUnregisterServer(void)
188 {
189 return STI_DllUnregisterServer();
190 }