ole32: Don't register interfaces that belong to actxprxy.
[wine] / dlls / oledb32 / convert.c
1 /* OLE DB Conversion library
2  *
3  * Copyright 2009 Huw Davies
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 #include <stdarg.h>
21
22 #define COBJMACROS
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "msdadc.h"
30 #include "oledberr.h"
31
32 #include "oledb_private.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(oledb);
37
38 typedef struct
39 {
40     const struct IDataConvertVtbl *lpVtbl;
41     const struct IDCInfoVtbl *lpDCInfoVtbl;
42
43     LONG ref;
44
45     UINT version; /* Set by IDCInfo_SetInfo */
46 } convert;
47
48 static inline convert *impl_from_IDataConvert(IDataConvert *iface)
49 {
50     return (convert *)((char*)iface - FIELD_OFFSET(convert, lpVtbl));
51 }
52
53 static inline convert *impl_from_IDCInfo(IDCInfo *iface)
54 {
55     return (convert *)((char*)iface - FIELD_OFFSET(convert, lpDCInfoVtbl));
56 }
57
58 static HRESULT WINAPI convert_QueryInterface(IDataConvert* iface,
59                                              REFIID riid,
60                                              void **obj)
61 {
62     convert *This = impl_from_IDataConvert(iface);
63     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
64
65     *obj = NULL;
66
67     if(IsEqualIID(riid, &IID_IUnknown) ||
68        IsEqualIID(riid, &IID_IDataConvert))
69     {
70         *obj = iface;
71     }
72     else if(IsEqualIID(riid, &IID_IDCInfo))
73     {
74         *obj = &This->lpDCInfoVtbl;
75     }
76     else
77     {
78         FIXME("interface %s not implemented\n", debugstr_guid(riid));
79         return E_NOINTERFACE;
80     }
81
82     IDataConvert_AddRef(iface);
83     return S_OK;
84 }
85
86
87 static ULONG WINAPI convert_AddRef(IDataConvert* iface)
88 {
89     convert *This = impl_from_IDataConvert(iface);
90     TRACE("(%p)\n", This);
91
92     return InterlockedIncrement(&This->ref);
93 }
94
95
96 static ULONG WINAPI convert_Release(IDataConvert* iface)
97 {
98     convert *This = impl_from_IDataConvert(iface);
99     LONG ref;
100
101     TRACE("(%p)\n", This);
102
103     ref = InterlockedDecrement(&This->ref);
104     if(ref == 0)
105     {
106         HeapFree(GetProcessHeap(), 0, This);
107     }
108
109     return ref;
110 }
111
112 static HRESULT WINAPI convert_DataConvert(IDataConvert* iface,
113                                           DBTYPE wSrcType, DBTYPE wDstType,
114                                           DBLENGTH cbSrcLength, DBLENGTH *pcbDstLength,
115                                           void *pSrc, void *pDst,
116                                           DBLENGTH cbDstMaxLength,
117                                           DBSTATUS dbsSrcStatus, DBSTATUS *pdbsDstStatus,
118                                           BYTE bPrecision, BYTE bScale,
119                                           DBDATACONVERT dwFlags)
120 {
121     convert *This = impl_from_IDataConvert(iface);
122     FIXME("(%p)->(%d, %d, %d, %p, %p, %p, %d, %d, %p, %d, %d, %x): stub\n", This,
123           wSrcType, wDstType, cbSrcLength, pcbDstLength, pSrc, pDst, cbDstMaxLength,
124           dbsSrcStatus, pdbsDstStatus, bPrecision, bScale, dwFlags);
125
126     return E_NOTIMPL;
127 }
128
129 static HRESULT WINAPI convert_CanConvert(IDataConvert* iface,
130                                          DBTYPE wSrcType, DBTYPE wDstType)
131 {
132     convert *This = impl_from_IDataConvert(iface);
133     FIXME("(%p)->(%d, %d): stub\n", This, wSrcType, wDstType);
134
135     return E_NOTIMPL;
136 }
137
138 static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface,
139                                                 DBTYPE wSrcType, DBTYPE wDstType,
140                                                 DBLENGTH *pcbSrcLength, DBLENGTH *pcbDstLength,
141                                                 void *pSrc)
142 {
143     convert *This = impl_from_IDataConvert(iface);
144     FIXME("(%p)->(%d, %d, %p, %p, %p): stub\n", This, wSrcType, wDstType, pcbSrcLength, pcbDstLength, pSrc);
145
146     return E_NOTIMPL;
147 }
148
149 static const struct IDataConvertVtbl convert_vtbl =
150 {
151     convert_QueryInterface,
152     convert_AddRef,
153     convert_Release,
154     convert_DataConvert,
155     convert_CanConvert,
156     convert_GetConversionSize
157 };
158
159 static HRESULT WINAPI dcinfo_QueryInterface(IDCInfo* iface, REFIID riid, void **obj)
160 {
161     convert *This = impl_from_IDCInfo(iface);
162
163     return IDataConvert_QueryInterface((IDataConvert *)This, riid, obj);
164 }
165
166 static ULONG WINAPI dcinfo_AddRef(IDCInfo* iface)
167 {
168     convert *This = impl_from_IDCInfo(iface);
169
170     return IDataConvert_AddRef((IDataConvert *)This);
171 }
172
173 static ULONG WINAPI dcinfo_Release(IDCInfo* iface)
174 {
175     convert *This = impl_from_IDCInfo(iface);
176
177     return IDataConvert_Release((IDataConvert *)This);
178 }
179
180 static HRESULT WINAPI dcinfo_GetInfo(IDCInfo *iface, ULONG num, DCINFOTYPE types[], DCINFO **info_ptr)
181 {
182     convert *This = impl_from_IDCInfo(iface);
183     ULONG i;
184     DCINFO *infos;
185
186     TRACE("(%p)->(%d, %p, %p)\n", This, num, types, info_ptr);
187
188     *info_ptr = infos = CoTaskMemAlloc(num * sizeof(*infos));
189     if(!infos) return E_OUTOFMEMORY;
190
191     for(i = 0; i < num; i++)
192     {
193         infos[i].eInfoType = types[i];
194         VariantInit(&infos[i].vData);
195
196         switch(types[i])
197         {
198         case DCINFOTYPE_VERSION:
199             V_VT(&infos[i].vData) = VT_UI4;
200             V_UI4(&infos[i].vData) = This->version;
201             break;
202         }
203     }
204
205     return S_OK;
206 }
207
208 static HRESULT WINAPI dcinfo_SetInfo(IDCInfo* iface, ULONG num, DCINFO info[])
209 {
210     convert *This = impl_from_IDCInfo(iface);
211     ULONG i;
212     HRESULT hr = S_OK;
213
214     TRACE("(%p)->(%d, %p)\n", This, num, info);
215
216     for(i = 0; i < num; i++)
217     {
218         switch(info[i].eInfoType)
219         {
220         case DCINFOTYPE_VERSION:
221             if(V_VT(&info[i].vData) != VT_UI4)
222             {
223                 FIXME("VERSION with vt %x\n", V_VT(&info[i].vData));
224                 hr = DB_S_ERRORSOCCURRED;
225                 break;
226             }
227             This->version = V_UI4(&info[i].vData);
228             break;
229
230         default:
231             FIXME("Unhandled info type %d (vt %x)\n", info[i].eInfoType, V_VT(&info[i].vData));
232         }
233     }
234     return hr;
235 }
236
237 static const struct IDCInfoVtbl dcinfo_vtbl =
238 {
239     dcinfo_QueryInterface,
240     dcinfo_AddRef,
241     dcinfo_Release,
242     dcinfo_GetInfo,
243     dcinfo_SetInfo
244 };
245
246 HRESULT create_oledb_convert(IUnknown *outer, void **obj)
247 {
248     convert *This;
249
250     TRACE("(%p, %p)\n", outer, obj);
251
252     *obj = NULL;
253
254     if(outer) return CLASS_E_NOAGGREGATION;
255
256     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
257     if(!This) return E_OUTOFMEMORY;
258
259     This->lpVtbl = &convert_vtbl;
260     This->lpDCInfoVtbl = &dcinfo_vtbl;
261     This->ref = 1;
262     This->version = 0x110;
263
264     *obj = &This->lpVtbl;
265
266     return S_OK;
267 }