~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/oledb32/convert.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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 "winnls.h"
 29 #include "ole2.h"
 30 #include "msdadc.h"
 31 #include "oledberr.h"
 32 
 33 #include "oledb_private.h"
 34 
 35 #include "wine/debug.h"
 36 
 37 WINE_DEFAULT_DEBUG_CHANNEL(oledb);
 38 
 39 typedef struct
 40 {
 41     IDataConvert IDataConvert_iface;
 42     IDCInfo IDCInfo_iface;
 43 
 44     LONG ref;
 45 
 46     UINT version; /* Set by IDCInfo_SetInfo */
 47 } convert;
 48 
 49 static inline convert *impl_from_IDataConvert(IDataConvert *iface)
 50 {
 51     return CONTAINING_RECORD(iface, convert, IDataConvert_iface);
 52 }
 53 
 54 static inline convert *impl_from_IDCInfo(IDCInfo *iface)
 55 {
 56     return CONTAINING_RECORD(iface, convert, IDCInfo_iface);
 57 }
 58 
 59 static HRESULT WINAPI convert_QueryInterface(IDataConvert* iface,
 60                                              REFIID riid,
 61                                              void **obj)
 62 {
 63     convert *This = impl_from_IDataConvert(iface);
 64     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
 65 
 66     *obj = NULL;
 67 
 68     if(IsEqualIID(riid, &IID_IUnknown) ||
 69        IsEqualIID(riid, &IID_IDataConvert))
 70     {
 71         *obj = iface;
 72     }
 73     else if(IsEqualIID(riid, &IID_IDCInfo))
 74     {
 75         *obj = &This->IDCInfo_iface;
 76     }
 77     else
 78     {
 79         FIXME("interface %s not implemented\n", debugstr_guid(riid));
 80         return E_NOINTERFACE;
 81     }
 82 
 83     IDataConvert_AddRef(iface);
 84     return S_OK;
 85 }
 86 
 87 
 88 static ULONG WINAPI convert_AddRef(IDataConvert* iface)
 89 {
 90     convert *This = impl_from_IDataConvert(iface);
 91     TRACE("(%p)\n", This);
 92 
 93     return InterlockedIncrement(&This->ref);
 94 }
 95 
 96 
 97 static ULONG WINAPI convert_Release(IDataConvert* iface)
 98 {
 99     convert *This = impl_from_IDataConvert(iface);
100     LONG ref;
101 
102     TRACE("(%p)\n", This);
103 
104     ref = InterlockedDecrement(&This->ref);
105     if(ref == 0)
106     {
107         HeapFree(GetProcessHeap(), 0, This);
108     }
109 
110     return ref;
111 }
112 
113 static int get_length(DBTYPE type)
114 {
115     switch(type)
116     {
117     case DBTYPE_I1:
118     case DBTYPE_UI1:
119         return 1;
120     case DBTYPE_I2:
121     case DBTYPE_UI2:
122         return 2;
123     case DBTYPE_BOOL:
124         return sizeof(VARIANT_BOOL);
125     case DBTYPE_I4:
126     case DBTYPE_UI4:
127     case DBTYPE_R4:
128         return 4;
129     case DBTYPE_I8:
130     case DBTYPE_UI8:
131     case DBTYPE_R8:
132     case DBTYPE_DATE:
133         return 8;
134     case DBTYPE_DBTIMESTAMP:
135         return sizeof(DBTIMESTAMP);
136     case DBTYPE_CY:
137         return sizeof(CY);
138     case DBTYPE_BSTR:
139         return sizeof(BSTR);
140     case DBTYPE_FILETIME:
141         return sizeof(FILETIME);
142     case DBTYPE_GUID:
143         return sizeof(GUID);
144     case DBTYPE_WSTR:
145     case DBTYPE_STR:
146     case DBTYPE_BYREF | DBTYPE_WSTR:
147         return 0;
148     default:
149         FIXME("Unhandled type %04x\n", type);
150         return 0;
151     }
152 }
153 
154 static HRESULT WINAPI convert_DataConvert(IDataConvert* iface,
155                                           DBTYPE src_type, DBTYPE dst_type,
156                                           DBLENGTH src_len, DBLENGTH *dst_len,
157                                           void *src, void *dst,
158                                           DBLENGTH dst_max_len,
159                                           DBSTATUS src_status, DBSTATUS *dst_status,
160                                           BYTE precision, BYTE scale,
161                                           DBDATACONVERT flags)
162 {
163     convert *This = impl_from_IDataConvert(iface);
164     HRESULT hr;
165 
166     TRACE("(%p)->(%d, %d, %ld, %p, %p, %p, %ld, %d, %p, %d, %d, %x)\n", This,
167           src_type, dst_type, src_len, dst_len, src, dst, dst_max_len,
168           src_status, dst_status, precision, scale, flags);
169 
170     *dst_status = DBSTATUS_E_BADACCESSOR;
171 
172     if(IDataConvert_CanConvert(iface, src_type, dst_type) != S_OK)
173     {
174         return DB_E_UNSUPPORTEDCONVERSION;
175     }
176 
177     if(src_type == DBTYPE_STR)
178     {
179         BSTR b;
180         DWORD len;
181 
182         if(flags & DBDATACONVERT_LENGTHFROMNTS)
183             len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0) - 1;
184         else
185             len = MultiByteToWideChar(CP_ACP, 0, src, src_len, NULL, 0);
186         b = SysAllocStringLen(NULL, len);
187         if(!b) return E_OUTOFMEMORY;
188         if(flags & DBDATACONVERT_LENGTHFROMNTS)
189             MultiByteToWideChar(CP_ACP, 0, src, -1, b, len + 1);
190         else
191             MultiByteToWideChar(CP_ACP, 0, src, src_len, b, len);
192 
193         hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len,
194                                       &b, dst, dst_max_len, src_status, dst_status,
195                                       precision, scale, flags);
196 
197         SysFreeString(b);
198         return hr;
199     }
200 
201     if(src_type == DBTYPE_WSTR)
202     {
203         BSTR b;
204 
205         if(flags & DBDATACONVERT_LENGTHFROMNTS)
206             b = SysAllocString(src);
207         else
208             b = SysAllocStringLen(src, src_len / 2);
209         if(!b) return E_OUTOFMEMORY;
210         hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len,
211                                       &b, dst, dst_max_len, src_status, dst_status,
212                                       precision, scale, flags);
213         SysFreeString(b);
214         return hr;
215     }
216 
217     switch(dst_type)
218     {
219     case DBTYPE_I2:
220     {
221         signed short *d = dst;
222         VARIANT tmp;
223         switch(src_type)
224         {
225         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
226         case DBTYPE_I2:          *d = *(signed short*)src; hr = S_OK;            break;
227         case DBTYPE_I4:          hr = VarI2FromI4(*(signed int*)src, d);         break;
228         case DBTYPE_R4:          hr = VarI2FromR4(*(FLOAT*)src, d);              break;
229         case DBTYPE_R8:          hr = VarI2FromR8(*(double*)src, d);             break;
230         case DBTYPE_CY:          hr = VarI2FromCy(*(CY*)src, d);                 break;
231         case DBTYPE_DATE:        hr = VarI2FromDate(*(DATE*)src, d);             break;
232         case DBTYPE_BSTR:        hr = VarI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
233         case DBTYPE_BOOL:        hr = VarI2FromBool(*(VARIANT_BOOL*)src, d);     break;
234         case DBTYPE_DECIMAL:     hr = VarI2FromDec((DECIMAL*)src, d);            break;
235         case DBTYPE_I1:          hr = VarI2FromI1(*(signed char*)src, d);        break;
236         case DBTYPE_UI1:         hr = VarI2FromUI1(*(BYTE*)src, d);              break;
237         case DBTYPE_UI2:         hr = VarI2FromUI2(*(WORD*)src, d);              break;
238         case DBTYPE_UI4:         hr = VarI2FromUI4(*(DWORD*)src, d);             break;
239         case DBTYPE_I8:          hr = VarI2FromI8(*(LONGLONG*)src, d);           break;
240         case DBTYPE_UI8:         hr = VarI2FromUI8(*(ULONGLONG*)src, d);         break;
241         case DBTYPE_VARIANT:
242             VariantInit(&tmp);
243             if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_I2)) == S_OK)
244                 *d = V_I2(&tmp);
245             break;
246         default: FIXME("Unimplemented conversion %04x -> I2\n", src_type); return E_NOTIMPL;
247         }
248         break;
249     }
250 
251     case DBTYPE_I4:
252     {
253         signed int *d = dst;
254         VARIANT tmp;
255         switch(src_type)
256         {
257         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
258         case DBTYPE_I2:          hr = VarI4FromI2(*(signed short*)src, d);       break;
259         case DBTYPE_I4:          *d = *(signed int*)src; hr = S_OK;              break;
260         case DBTYPE_R4:          hr = VarI4FromR4(*(FLOAT*)src, d);              break;
261         case DBTYPE_R8:          hr = VarI4FromR8(*(double*)src, d);             break;
262         case DBTYPE_CY:          hr = VarI4FromCy(*(CY*)src, d);                 break;
263         case DBTYPE_DATE:        hr = VarI4FromDate(*(DATE*)src, d);             break;
264         case DBTYPE_BSTR:        hr = VarI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
265         case DBTYPE_BOOL:        hr = VarI4FromBool(*(VARIANT_BOOL*)src, d);     break;
266         case DBTYPE_DECIMAL:     hr = VarI4FromDec((DECIMAL*)src, d);            break;
267         case DBTYPE_I1:          hr = VarI4FromI1(*(signed char*)src, d);        break;
268         case DBTYPE_UI1:         hr = VarI4FromUI1(*(BYTE*)src, d);              break;
269         case DBTYPE_UI2:         hr = VarI4FromUI2(*(WORD*)src, d);              break;
270         case DBTYPE_UI4:         hr = VarI4FromUI4(*(DWORD*)src, d);             break;
271         case DBTYPE_I8:          hr = VarI4FromI8(*(LONGLONG*)src, d);           break;
272         case DBTYPE_UI8:         hr = VarI4FromUI8(*(ULONGLONG*)src, d);         break;
273         case DBTYPE_VARIANT:
274             VariantInit(&tmp);
275             if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_I4)) == S_OK)
276                 *d = V_I4(&tmp);
277             break;
278         default: FIXME("Unimplemented conversion %04x -> I4\n", src_type); return E_NOTIMPL;
279         }
280         break;
281     }
282 
283     case DBTYPE_R4:
284     {
285         FLOAT *d = dst;
286         switch(src_type)
287         {
288         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
289         case DBTYPE_I2:          hr = VarR4FromI2(*(signed short*)src, d);       break;
290         case DBTYPE_I4:          hr = VarR4FromI4(*(signed int*)src, d);         break;
291         case DBTYPE_R4:          *d = *(FLOAT*)src; hr = S_OK;                   break;
292         case DBTYPE_R8:          hr = VarR4FromR8(*(double*)src, d);             break;
293         case DBTYPE_CY:          hr = VarR4FromCy(*(CY*)src, d);                 break;
294         case DBTYPE_DATE:        hr = VarR4FromDate(*(DATE*)src, d);             break;
295         case DBTYPE_BSTR:        hr = VarR4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
296         case DBTYPE_BOOL:        hr = VarR4FromBool(*(VARIANT_BOOL*)src, d);     break;
297         case DBTYPE_DECIMAL:     hr = VarR4FromDec((DECIMAL*)src, d);            break;
298         case DBTYPE_I1:          hr = VarR4FromI1(*(signed char*)src, d);        break;
299         case DBTYPE_UI1:         hr = VarR4FromUI1(*(BYTE*)src, d);              break;
300         case DBTYPE_UI2:         hr = VarR4FromUI2(*(WORD*)src, d);              break;
301         case DBTYPE_UI4:         hr = VarR4FromUI4(*(DWORD*)src, d);             break;
302         case DBTYPE_I8:          hr = VarR4FromI8(*(LONGLONG*)src, d);           break;
303         case DBTYPE_UI8:         hr = VarR4FromUI8(*(ULONGLONG*)src, d);         break;
304         default: FIXME("Unimplemented conversion %04x -> R4\n", src_type); return E_NOTIMPL;
305         }
306         break;
307     }
308     case DBTYPE_R8:
309     {
310         DOUBLE *d=dst;
311         switch (src_type)
312         {
313         case DBTYPE_EMPTY:      *d = 0; hr = S_OK;                               break;
314         case DBTYPE_I1:          hr = VarR8FromI1(*(signed char*)src, d);        break;
315         case DBTYPE_I2:          hr = VarR8FromI2(*(signed short*)src, d);       break;
316         case DBTYPE_I4:          hr = VarR8FromI4(*(signed int*)src, d);         break;
317         case DBTYPE_I8:          hr = VarR8FromI8(*(LONGLONG*)src, d);           break;
318         case DBTYPE_UI1:         hr = VarR8FromUI1(*(BYTE*)src, d);              break;
319         case DBTYPE_UI2:         hr = VarR8FromUI2(*(WORD*)src, d);              break;
320         case DBTYPE_UI4:         hr = VarR8FromUI4(*(DWORD*)src, d);             break;
321         case DBTYPE_UI8:         hr = VarR8FromUI8(*(ULONGLONG*)src, d);         break;
322         case DBTYPE_R4:          hr = VarR8FromR4(*(FLOAT*)src, d);              break;
323         case DBTYPE_R8:          *d = *(DOUBLE*)src; hr = S_OK;                  break;
324         case DBTYPE_CY:          hr = VarR8FromCy(*(CY*)src, d);                 break;
325         case DBTYPE_DATE:        hr = VarR8FromDate(*(DATE*)src, d);             break;
326         case DBTYPE_BSTR:        hr = VarR8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
327         case DBTYPE_BOOL:        hr = VarR8FromBool(*(VARIANT_BOOL*)src, d);     break;
328         case DBTYPE_DECIMAL:     hr = VarR8FromDec((DECIMAL*)src, d);            break;
329         default: FIXME("Unimplemented conversion %04x -> R8\n", src_type); return E_NOTIMPL;
330         }
331         break;
332     }
333     case DBTYPE_BOOL:
334     {
335         VARIANT_BOOL *d=dst;
336         switch (src_type)
337         {
338         case DBTYPE_EMPTY:      *d = 0; hr = S_OK;                               break;
339         case DBTYPE_I1:          hr = VarBoolFromI1(*(signed char*)src, d);      break;
340         case DBTYPE_I2:          hr = VarBoolFromI2(*(signed short*)src, d);     break;
341         case DBTYPE_I4:          hr = VarBoolFromI4(*(signed int*)src, d);       break;
342         case DBTYPE_I8:          hr = VarBoolFromI8(*(LONGLONG*)src, d);         break;
343         case DBTYPE_UI1:         hr = VarBoolFromUI1(*(BYTE*)src, d);            break;
344         case DBTYPE_UI2:         hr = VarBoolFromUI2(*(WORD*)src, d);            break;
345         case DBTYPE_UI4:         hr = VarBoolFromUI4(*(DWORD*)src, d);           break;
346         case DBTYPE_UI8:         hr = VarBoolFromUI8(*(ULONGLONG*)src, d);       break;
347         case DBTYPE_R4:          hr = VarBoolFromR4(*(FLOAT*)src, d);            break;
348         case DBTYPE_R8:          hr = VarBoolFromR8(*(DOUBLE*)src, d);           break;
349         case DBTYPE_CY:          hr = VarBoolFromCy(*(CY*)src, d);               break;
350         case DBTYPE_DATE:        hr = VarBoolFromDate(*(DATE*)src, d);           break;
351         case DBTYPE_BSTR:        hr = VarBoolFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
352         case DBTYPE_BOOL:        *d = *(VARIANT_BOOL*)src; hr = S_OK;            break;
353         case DBTYPE_DECIMAL:     hr = VarBoolFromDec((DECIMAL*)src, d);          break;
354         default: FIXME("Unimplemented conversion %04x -> BOOL\n", src_type); return E_NOTIMPL;
355         }
356         break;
357     }
358     case DBTYPE_DATE:
359     {
360         DATE *d=dst;
361         switch (src_type)
362         {
363         case DBTYPE_EMPTY:      *d = 0; hr = S_OK;                               break;
364         case DBTYPE_I1:          hr = VarDateFromI1(*(signed char*)src, d);      break;
365         case DBTYPE_I2:          hr = VarDateFromI2(*(signed short*)src, d);     break;
366         case DBTYPE_I4:          hr = VarDateFromI4(*(signed int*)src, d);       break;
367         case DBTYPE_I8:          hr = VarDateFromI8(*(LONGLONG*)src, d);         break;
368         case DBTYPE_UI1:         hr = VarDateFromUI1(*(BYTE*)src, d);            break;
369         case DBTYPE_UI2:         hr = VarDateFromUI2(*(WORD*)src, d);            break;
370         case DBTYPE_UI4:         hr = VarDateFromUI4(*(DWORD*)src, d);           break;
371         case DBTYPE_UI8:         hr = VarDateFromUI8(*(ULONGLONG*)src, d);       break;
372         case DBTYPE_R4:          hr = VarDateFromR4(*(FLOAT*)src, d);            break;
373         case DBTYPE_R8:          hr = VarDateFromR8(*(DOUBLE*)src, d);           break;
374         case DBTYPE_CY:          hr = VarDateFromCy(*(CY*)src, d);               break;
375         case DBTYPE_DATE:       *d = *(DATE*)src;      hr = S_OK;                break;
376         case DBTYPE_BSTR:        hr = VarDateFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
377         case DBTYPE_BOOL:        hr = VarDateFromBool(*(VARIANT_BOOL*)src, d);   break;
378         case DBTYPE_DECIMAL:     hr = VarDateFromDec((DECIMAL*)src, d);          break;
379         case DBTYPE_DBTIMESTAMP:
380         {
381             SYSTEMTIME st;
382             DBTIMESTAMP *ts=(DBTIMESTAMP*)src;
383 
384             st.wYear = ts->year;
385             st.wMonth = ts->month;
386             st.wDay = ts->day;
387             st.wHour = ts->hour;
388             st.wMinute = ts->minute;
389             st.wSecond = ts->second;
390             st.wMilliseconds = ts->fraction/1000000;
391             hr = (SystemTimeToVariantTime(&st, d) ? S_OK : E_FAIL);
392             break;
393         }
394         default: FIXME("Unimplemented conversion %04x -> DATE\n", src_type); return E_NOTIMPL;
395         }
396         break;
397     }
398     case DBTYPE_DBTIMESTAMP:
399     {
400         DBTIMESTAMP *d=dst;
401         switch (src_type)
402         {
403         case DBTYPE_EMPTY:       memset(d, 0, sizeof(DBTIMESTAMP));    hr = S_OK; break;
404         case DBTYPE_DBTIMESTAMP: memcpy(d, src, sizeof(DBTIMESTAMP));  hr = S_OK; break;
405         case DBTYPE_DATE:
406         {
407             SYSTEMTIME st;
408             hr = (VariantTimeToSystemTime(*(double*)src, &st) ? S_OK : E_FAIL);
409             d->year = st.wYear;
410             d->month = st.wMonth;
411             d->day = st.wDay;
412             d->hour = st.wHour;
413             d->minute = st.wMinute;
414             d->second = st.wSecond;
415             d->fraction = st.wMilliseconds * 1000000;
416             break;
417         }
418         default: FIXME("Unimplemented conversion %04x -> DBTIMESTAMP\n", src_type); return E_NOTIMPL;
419         }
420         break;
421     }
422 
423     case DBTYPE_CY:
424     {
425         CY *d = dst;
426         switch(src_type)
427         {
428         case DBTYPE_EMPTY:       d->int64 = 0; hr = S_OK;                              break;
429         case DBTYPE_I2:          hr = VarCyFromI2(*(signed short*)src, d);       break;
430         case DBTYPE_I4:          hr = VarCyFromI4(*(signed int*)src, d);         break;
431         case DBTYPE_R4:          hr = VarCyFromR4(*(FLOAT*)src, d);              break;
432         case DBTYPE_R8:          hr = VarCyFromR8(*(double*)src, d);             break;
433         case DBTYPE_CY:          *d = *(CY*)src; hr = S_OK;                      break;
434         case DBTYPE_DATE:        hr = VarCyFromDate(*(DATE*)src, d);             break;
435         case DBTYPE_BSTR:        hr = VarCyFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
436         case DBTYPE_BOOL:        hr = VarCyFromBool(*(VARIANT_BOOL*)src, d);     break;
437         case DBTYPE_DECIMAL:     hr = VarCyFromDec((DECIMAL*)src, d);            break;
438         case DBTYPE_I1:          hr = VarCyFromI1(*(signed char*)src, d);        break;
439         case DBTYPE_UI1:         hr = VarCyFromUI1(*(BYTE*)src, d);              break;
440         case DBTYPE_UI2:         hr = VarCyFromUI2(*(WORD*)src, d);              break;
441         case DBTYPE_UI4:         hr = VarCyFromUI4(*(DWORD*)src, d);             break;
442         case DBTYPE_I8:          hr = VarCyFromI8(*(LONGLONG*)src, d);           break;
443         case DBTYPE_UI8:         hr = VarCyFromUI8(*(ULONGLONG*)src, d);         break;
444         default: FIXME("Unimplemented conversion %04x -> CY\n", src_type); return E_NOTIMPL;
445         }
446         break;
447     }
448 
449     case DBTYPE_BSTR:
450     {
451         BSTR *d = dst;
452         switch(src_type)
453         {
454         case DBTYPE_EMPTY:       *d = SysAllocStringLen(NULL, 0); hr = *d ? S_OK : E_OUTOFMEMORY;      break;
455         case DBTYPE_I2:          hr = VarBstrFromI2(*(signed short*)src, LOCALE_USER_DEFAULT, 0, d);   break;
456         case DBTYPE_I4:          hr = VarBstrFromI4(*(signed int*)src, LOCALE_USER_DEFAULT, 0, d);     break;
457         case DBTYPE_R4:          hr = VarBstrFromR4(*(FLOAT*)src, LOCALE_USER_DEFAULT, 0, d);          break;
458         case DBTYPE_R8:          hr = VarBstrFromR8(*(double*)src, LOCALE_USER_DEFAULT, 0, d);         break;
459         case DBTYPE_CY:          hr = VarBstrFromCy(*(CY*)src, LOCALE_USER_DEFAULT, 0, d);             break;
460         case DBTYPE_DATE:        hr = VarBstrFromDate(*(DATE*)src, LOCALE_USER_DEFAULT, 0, d);         break;
461         case DBTYPE_BSTR:        *d = SysAllocStringLen(*(BSTR*)src, SysStringLen(*(BSTR*)src)); hr = *d ? S_OK : E_OUTOFMEMORY;     break;
462         case DBTYPE_BOOL:        hr = VarBstrFromBool(*(VARIANT_BOOL*)src, LOCALE_USER_DEFAULT, 0, d); break;
463         case DBTYPE_DECIMAL:     hr = VarBstrFromDec((DECIMAL*)src, LOCALE_USER_DEFAULT, 0, d);        break;
464         case DBTYPE_I1:          hr = VarBstrFromI1(*(signed char*)src, LOCALE_USER_DEFAULT, 0, d);    break;
465         case DBTYPE_UI1:         hr = VarBstrFromUI1(*(BYTE*)src, LOCALE_USER_DEFAULT, 0, d);          break;
466         case DBTYPE_UI2:         hr = VarBstrFromUI2(*(WORD*)src, LOCALE_USER_DEFAULT, 0, d);          break;
467         case DBTYPE_UI4:         hr = VarBstrFromUI4(*(DWORD*)src, LOCALE_USER_DEFAULT, 0, d);         break;
468         case DBTYPE_I8:          hr = VarBstrFromI8(*(LONGLONG*)src, LOCALE_USER_DEFAULT, 0, d);       break;
469         case DBTYPE_UI8:         hr = VarBstrFromUI8(*(ULONGLONG*)src, LOCALE_USER_DEFAULT, 0, d);     break;
470         case DBTYPE_GUID:
471         {
472             WCHAR szBuff[39];
473             const GUID *id = (const GUID *)src;
474             WCHAR format[] = {
475                 '{','%','','8','X','-','%','','4','X','-','%','','4','X','-',
476                 '%','','2','X','%','','2','X','-',
477                 '%','','2','X','%','','2','X','%','','2','X','%','','2','X','%','','2','X','%','','2','X','}',0};
478             wsprintfW(szBuff, format,
479                 id->Data1, id->Data2, id->Data3,
480                 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
481                 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
482             *d = SysAllocString(szBuff);
483             hr = *d ? S_OK : E_OUTOFMEMORY;
484         }
485         break;
486         case DBTYPE_BYTES:
487         {
488             *d = SysAllocStringLen(NULL, 2 * src_len);
489             if (*d == NULL)
490                 hr = E_OUTOFMEMORY;
491             else
492             {
493                 const char hexchars[] = "0123456789ABCDEF";
494                 WCHAR *s = *d;
495                 unsigned char *p = src;
496                 while (src_len > 0)
497                 {
498                     *s++ = hexchars[(*p >> 4) & 0x0F];
499                     *s++ = hexchars[(*p)      & 0x0F];
500                     src_len--; p++;
501                 }
502                 hr = S_OK;
503             }
504         }
505         break;
506         default: FIXME("Unimplemented conversion %04x -> BSTR\n", src_type); return E_NOTIMPL;
507         }
508         break;
509     }
510 
511     case DBTYPE_UI1:
512     {
513         BYTE *d = dst;
514         switch(src_type)
515         {
516         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
517         case DBTYPE_I2:          hr = VarUI1FromI2(*(signed short*)src, d);      break;
518         case DBTYPE_I4:          hr = VarUI1FromI4(*(signed int*)src, d);        break;
519         case DBTYPE_R4:          hr = VarUI1FromR4(*(FLOAT*)src, d);             break;
520         case DBTYPE_R8:          hr = VarUI1FromR8(*(double*)src, d);            break;
521         case DBTYPE_CY:          hr = VarUI1FromCy(*(CY*)src, d);                break;
522         case DBTYPE_DATE:        hr = VarUI1FromDate(*(DATE*)src, d);            break;
523         case DBTYPE_BSTR:        hr = VarUI1FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
524         case DBTYPE_BOOL:        hr = VarUI1FromBool(*(VARIANT_BOOL*)src, d);    break;
525         case DBTYPE_DECIMAL:     hr = VarUI1FromDec((DECIMAL*)src, d);           break;
526         case DBTYPE_I1:          hr = VarUI1FromI1(*(signed char*)src, d);       break;
527         case DBTYPE_UI1:         *d = *(BYTE*)src; hr = S_OK;                    break;
528         case DBTYPE_UI2:         hr = VarUI1FromUI2(*(WORD*)src, d);             break;
529         case DBTYPE_UI4:         hr = VarUI1FromUI4(*(DWORD*)src, d);            break;
530         case DBTYPE_I8:          hr = VarUI1FromI8(*(LONGLONG*)src, d);          break;
531         case DBTYPE_UI8:         hr = VarUI1FromUI8(*(ULONGLONG*)src, d);        break;
532         default: FIXME("Unimplemented conversion %04x -> UI1\n", src_type); return E_NOTIMPL;
533         }
534         break;
535     }
536 
537     case DBTYPE_UI4:
538     {
539         DWORD *d = dst;
540         switch(src_type)
541         {
542         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
543         case DBTYPE_I2:          hr = VarUI4FromI2(*(signed short*)src, d);      break;
544         case DBTYPE_I4:          hr = VarUI4FromI4(*(signed int*)src, d);        break;
545         case DBTYPE_R4:          hr = VarUI4FromR4(*(FLOAT*)src, d);             break;
546         case DBTYPE_R8:          hr = VarUI4FromR8(*(double*)src, d);            break;
547         case DBTYPE_CY:          hr = VarUI4FromCy(*(CY*)src, d);                break;
548         case DBTYPE_DATE:        hr = VarUI4FromDate(*(DATE*)src, d);            break;
549         case DBTYPE_BSTR:        hr = VarUI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
550         case DBTYPE_BOOL:        hr = VarUI4FromBool(*(VARIANT_BOOL*)src, d);    break;
551         case DBTYPE_DECIMAL:     hr = VarUI4FromDec((DECIMAL*)src, d);           break;
552         case DBTYPE_I1:          hr = VarUI4FromI1(*(signed char*)src, d);       break;
553         case DBTYPE_UI1:         hr = VarUI4FromUI1(*(BYTE*)src, d);             break;
554         case DBTYPE_UI2:         hr = VarUI4FromUI2(*(WORD*)src, d);             break;
555         case DBTYPE_UI4:         *d = *(DWORD*)src; hr = S_OK;                   break;
556         case DBTYPE_I8:          hr = VarUI4FromI8(*(LONGLONG*)src, d);          break;
557         case DBTYPE_UI8:         hr = VarUI4FromUI8(*(ULONGLONG*)src, d);        break;
558         default: FIXME("Unimplemented conversion %04x -> UI4\n", src_type); return E_NOTIMPL;
559         }
560         break;
561     }
562 
563     case DBTYPE_UI8:
564     {
565         ULONGLONG *d = dst;
566         switch(src_type)
567         {
568         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
569         case DBTYPE_I2:          hr = VarUI8FromI2(*(signed short*)src, d);      break;
570         case DBTYPE_I4:          {LONGLONG s = *(signed int*)src; hr = VarUI8FromI8(s, d);        break;}
571         case DBTYPE_R4:          hr = VarUI8FromR4(*(FLOAT*)src, d);             break;
572         case DBTYPE_R8:          hr = VarUI8FromR8(*(double*)src, d);            break;
573         case DBTYPE_CY:          hr = VarUI8FromCy(*(CY*)src, d);                break;
574         case DBTYPE_DATE:        hr = VarUI8FromDate(*(DATE*)src, d);            break;
575         case DBTYPE_BSTR:        hr = VarUI8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
576         case DBTYPE_BOOL:        hr = VarUI8FromBool(*(VARIANT_BOOL*)src, d);    break;
577         case DBTYPE_DECIMAL:     hr = VarUI8FromDec((DECIMAL*)src, d);           break;
578         case DBTYPE_I1:          hr = VarUI8FromI1(*(signed char*)src, d);       break;
579         case DBTYPE_UI1:         hr = VarUI8FromUI1(*(BYTE*)src, d);             break;
580         case DBTYPE_UI2:         hr = VarUI8FromUI2(*(WORD*)src, d);             break;
581         case DBTYPE_UI4:         hr = VarUI8FromUI4(*(DWORD*)src, d);            break;
582         case DBTYPE_I8:          hr = VarUI8FromI8(*(LONGLONG*)src, d);          break;
583         case DBTYPE_UI8:         *d = *(ULONGLONG*)src; hr = S_OK;               break;
584         default: FIXME("Unimplemented conversion %04x -> UI8\n", src_type); return E_NOTIMPL;
585         }
586         break;
587     }
588 
589     case DBTYPE_FILETIME:
590     {
591         FILETIME *d = dst;
592         switch(src_type)
593         {
594         case DBTYPE_EMPTY:       d->dwLowDateTime = d->dwHighDateTime = 0; hr = S_OK;    break;
595         case DBTYPE_FILETIME:    *d = *(FILETIME*)src; hr = S_OK;                        break;
596         default: FIXME("Unimplemented conversion %04x -> FILETIME\n", src_type); return E_NOTIMPL;
597         }
598         break;
599     }
600 
601     case DBTYPE_GUID:
602     {
603         GUID *d = dst;
604         switch(src_type)
605         {
606         case DBTYPE_EMPTY:       *d = GUID_NULL; hr = S_OK; break;
607         case DBTYPE_GUID:        *d = *(GUID*)src; hr = S_OK; break;
608         default: FIXME("Unimplemented conversion %04x -> GUID\n", src_type); return E_NOTIMPL;
609         }
610         break;
611     }
612 
613     case DBTYPE_WSTR:
614     {
615         BSTR b;
616         DBLENGTH bstr_len;
617         INT bytes_to_copy;
618         hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
619                                       src, &b, sizeof(BSTR), src_status, dst_status,
620                                       precision, scale, flags);
621         if(hr != S_OK) return hr;
622         bstr_len = SysStringLen(b);
623         *dst_len = bstr_len * sizeof(WCHAR); /* Doesn't include size for '\0' */
624         *dst_status = DBSTATUS_S_OK;
625         bytes_to_copy = min(*dst_len + sizeof(WCHAR), dst_max_len);
626         if(dst)
627         {
628             if(bytes_to_copy >= sizeof(WCHAR))
629             {
630                 memcpy(dst, b, bytes_to_copy - sizeof(WCHAR));
631                 *((WCHAR*)dst + bytes_to_copy / sizeof(WCHAR) - 1) = 0;
632                 if(bytes_to_copy < *dst_len + sizeof(WCHAR))
633                     *dst_status = DBSTATUS_S_TRUNCATED;
634             }
635             else
636             {
637                 *dst_status = DBSTATUS_E_DATAOVERFLOW;
638                 hr = DB_E_ERRORSOCCURRED;
639             }
640         }
641         SysFreeString(b);
642         return hr;
643     }
644     case DBTYPE_STR:
645     {
646         BSTR b;
647         DBLENGTH bstr_len;
648         INT bytes_to_copy;
649         hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
650                                       src, &b, sizeof(BSTR), src_status, dst_status,
651                                       precision, scale, flags);
652         if(hr != S_OK) return hr;
653         bstr_len = SysStringLen(b);
654         *dst_len = bstr_len * sizeof(char); /* Doesn't include size for '\0' */
655         *dst_status = DBSTATUS_S_OK;
656         bytes_to_copy = min(*dst_len + sizeof(char), dst_max_len);
657         if(dst)
658         {
659             if(bytes_to_copy >= sizeof(char))
660             {
661                 WideCharToMultiByte(CP_ACP, 0, b, bytes_to_copy - sizeof(char), dst, dst_max_len, NULL, NULL);
662                 *((char *)dst + bytes_to_copy / sizeof(char) - 1) = 0;
663                 if(bytes_to_copy < *dst_len + sizeof(char))
664                     *dst_status = DBSTATUS_S_TRUNCATED;
665             }
666             else
667             {
668                 *dst_status = DBSTATUS_E_DATAOVERFLOW;
669                 hr = DB_E_ERRORSOCCURRED;
670             }
671         }
672         SysFreeString(b);
673         return hr;
674     }
675 
676     case DBTYPE_BYREF | DBTYPE_WSTR:
677     {
678         BSTR b;
679         WCHAR **d = dst;
680         DBLENGTH bstr_len;
681         hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
682                                       src, &b, sizeof(BSTR), src_status, dst_status,
683                                       precision, scale, flags);
684         if(hr != S_OK) return hr;
685 
686         bstr_len = SysStringLen(b) * sizeof(WCHAR);
687         *dst_len = bstr_len; /* Doesn't include size for '\0' */
688 
689         *d = CoTaskMemAlloc(bstr_len + sizeof(WCHAR));
690         if(*d) memcpy(*d, b, bstr_len + sizeof(WCHAR));
691         else hr = E_OUTOFMEMORY;
692         SysFreeString(b);
693         return hr;
694     }
695 
696     default:
697         FIXME("Unimplemented conversion %04x -> %04x\n", src_type, dst_type);
698         return E_NOTIMPL;
699 
700     }
701 
702     if(hr == DISP_E_OVERFLOW)
703     {
704         *dst_status = DBSTATUS_E_DATAOVERFLOW;
705         *dst_len = get_length(dst_type);
706         hr = DB_E_ERRORSOCCURRED;
707     }
708     else if(hr == S_OK)
709     {
710         *dst_status = DBSTATUS_S_OK;
711         *dst_len = get_length(dst_type);
712     }
713 
714     return hr;
715 }
716 
717 static inline WORD get_dbtype_class(DBTYPE type)
718 {
719     switch(type)
720     {
721     case DBTYPE_I2:
722     case DBTYPE_R4:
723     case DBTYPE_R8:
724     case DBTYPE_I1:
725     case DBTYPE_UI1:
726     case DBTYPE_UI2:
727         return DBTYPE_I2;
728 
729     case DBTYPE_I4:
730     case DBTYPE_UI4:
731         return DBTYPE_I4;
732 
733     case DBTYPE_I8:
734     case DBTYPE_UI8:
735         return DBTYPE_I8;
736 
737     case DBTYPE_BSTR:
738     case DBTYPE_STR:
739     case DBTYPE_WSTR:
740         return DBTYPE_BSTR;
741 
742     case DBTYPE_DBDATE:
743     case DBTYPE_DBTIME:
744     case DBTYPE_DBTIMESTAMP:
745         return DBTYPE_DBDATE;
746     }
747     return type;
748 }
749 
750 /* Many src types will convert to this group of dst types */
751 static inline BOOL common_class(WORD dst_class)
752 {
753     switch(dst_class)
754     {
755     case DBTYPE_EMPTY:
756     case DBTYPE_NULL:
757     case DBTYPE_I2:
758     case DBTYPE_I4:
759     case DBTYPE_BSTR:
760     case DBTYPE_BOOL:
761     case DBTYPE_VARIANT:
762     case DBTYPE_I8:
763     case DBTYPE_CY:
764     case DBTYPE_DECIMAL:
765     case DBTYPE_NUMERIC:
766         return TRUE;
767     }
768     return FALSE;
769 }
770 
771 static inline BOOL array_type(DBTYPE type)
772 {
773     return (type >= DBTYPE_I2 && type <= DBTYPE_UI4);
774 }
775 
776 static HRESULT WINAPI convert_CanConvert(IDataConvert* iface,
777                                          DBTYPE src_type, DBTYPE dst_type)
778 {
779     convert *This = impl_from_IDataConvert(iface);
780     DBTYPE src_base_type = src_type & 0x1ff;
781     DBTYPE dst_base_type = dst_type & 0x1ff;
782     WORD dst_class = get_dbtype_class(dst_base_type);
783 
784     TRACE("(%p)->(%d, %d)\n", This, src_type, dst_type);
785 
786     if(src_type & DBTYPE_VECTOR || dst_type & DBTYPE_VECTOR) return S_FALSE;
787 
788     if(src_type & DBTYPE_ARRAY)
789     {
790         if(!array_type(src_base_type)) return S_FALSE;
791         if(dst_type & DBTYPE_ARRAY)
792         {
793             if(src_type == dst_type) return S_OK;
794             return S_FALSE;
795         }
796         if(dst_type == DBTYPE_VARIANT) return S_OK;
797         return S_FALSE;
798     }
799 
800     if(dst_type & DBTYPE_ARRAY)
801     {
802         if(!array_type(dst_base_type)) return S_FALSE;
803         if(src_type == DBTYPE_IDISPATCH || src_type == DBTYPE_VARIANT) return S_OK;
804         return S_FALSE;
805     }
806 
807     if(dst_type & DBTYPE_BYREF)
808         if(dst_base_type != DBTYPE_BYTES && dst_base_type != DBTYPE_STR && dst_base_type != DBTYPE_WSTR)
809             return S_FALSE;
810 
811     switch(get_dbtype_class(src_base_type))
812     {
813     case DBTYPE_EMPTY:
814         if(common_class(dst_class)) return S_OK;
815         switch(dst_class)
816         {
817         case DBTYPE_DATE:
818         case DBTYPE_GUID:
819         case DBTYPE_FILETIME:
820             return S_OK;
821         default:
822             if(dst_base_type == DBTYPE_DBTIMESTAMP) return S_OK;
823             return S_FALSE;
824         }
825 
826     case DBTYPE_NULL:
827         switch(dst_base_type)
828         {
829         case DBTYPE_NULL:
830         case DBTYPE_VARIANT:
831         case DBTYPE_FILETIME: return S_OK;
832         default: return S_FALSE;
833         }
834 
835     case DBTYPE_I4:
836         if(dst_base_type == DBTYPE_BYTES) return S_OK;
837         /* fall through */
838     case DBTYPE_I2:
839         if(dst_base_type == DBTYPE_DATE) return S_OK;
840         /* fall through */
841     case DBTYPE_DECIMAL:
842         if(common_class(dst_class)) return S_OK;
843         if(dst_class == DBTYPE_DBDATE) return S_OK;
844         return S_FALSE;
845 
846     case DBTYPE_BOOL:
847         if(dst_base_type == DBTYPE_DATE) return S_OK;
848     case DBTYPE_NUMERIC:
849     case DBTYPE_CY:
850         if(common_class(dst_class)) return S_OK;
851         return S_FALSE;
852 
853     case DBTYPE_I8:
854         if(common_class(dst_class)) return S_OK;
855         switch(dst_base_type)
856         {
857         case DBTYPE_BYTES:
858         case DBTYPE_FILETIME: return S_OK;
859         default: return S_FALSE;
860         }
861 
862     case DBTYPE_DATE:
863         switch(dst_class)
864         {
865         case DBTYPE_EMPTY:
866         case DBTYPE_NULL:
867         case DBTYPE_I2:
868         case DBTYPE_I4:
869         case DBTYPE_BSTR:
870         case DBTYPE_BOOL:
871         case DBTYPE_VARIANT:
872         case DBTYPE_I8:
873         case DBTYPE_DATE:
874         case DBTYPE_DBDATE:
875         case DBTYPE_FILETIME:
876             return S_OK;
877         default: return S_FALSE;
878         }
879 
880     case DBTYPE_IDISPATCH:
881     case DBTYPE_VARIANT:
882         switch(dst_base_type)
883         {
884         case DBTYPE_IDISPATCH:
885         case DBTYPE_ERROR:
886         case DBTYPE_IUNKNOWN:
887             return S_OK;
888         }
889         /* fall through */
890     case DBTYPE_BSTR:
891         if(common_class(dst_class)) return S_OK;
892         switch(dst_class)
893         {
894         case DBTYPE_DATE:
895         case DBTYPE_GUID:
896         case DBTYPE_BYTES:
897         case DBTYPE_DBDATE:
898         case DBTYPE_FILETIME:
899             return S_OK;
900         default: return S_FALSE;
901         }
902 
903     case DBTYPE_ERROR:
904         switch(dst_base_type)
905         {
906         case DBTYPE_BSTR:
907         case DBTYPE_ERROR:
908         case DBTYPE_VARIANT:
909         case DBTYPE_WSTR:
910             return S_OK;
911         default: return S_FALSE;
912         }
913 
914     case DBTYPE_IUNKNOWN:
915         switch(dst_base_type)
916         {
917         case DBTYPE_EMPTY:
918         case DBTYPE_NULL:
919         case DBTYPE_IDISPATCH:
920         case DBTYPE_VARIANT:
921         case DBTYPE_IUNKNOWN:
922             return S_OK;
923         default: return S_FALSE;
924         }
925 
926     case DBTYPE_BYTES:
927         if(dst_class == DBTYPE_I4 || dst_class == DBTYPE_I8) return S_OK;
928         /* fall through */
929     case DBTYPE_GUID:
930         switch(dst_class)
931         {
932         case DBTYPE_EMPTY:
933         case DBTYPE_NULL:
934         case DBTYPE_BSTR:
935         case DBTYPE_VARIANT:
936         case DBTYPE_GUID:
937         case DBTYPE_BYTES:
938             return S_OK;
939         default: return S_FALSE;
940         }
941 
942     case DBTYPE_FILETIME:
943         if(dst_class == DBTYPE_I8) return S_OK;
944         /* fall through */
945     case DBTYPE_DBDATE:
946         switch(dst_class)
947         {
948         case DBTYPE_EMPTY:
949         case DBTYPE_NULL:
950         case DBTYPE_DATE:
951         case DBTYPE_BSTR:
952         case DBTYPE_VARIANT:
953         case DBTYPE_DBDATE:
954         case DBTYPE_FILETIME:
955             return S_OK;
956         default: return S_FALSE;
957         }
958 
959     }
960     return S_FALSE;
961 }
962 
963 static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface,
964                                                 DBTYPE wSrcType, DBTYPE wDstType,
965                                                 DBLENGTH *pcbSrcLength, DBLENGTH *pcbDstLength,
966                                                 void *pSrc)
967 {
968     convert *This = impl_from_IDataConvert(iface);
969     FIXME("(%p)->(%d, %d, %p, %p, %p): stub\n", This, wSrcType, wDstType, pcbSrcLength, pcbDstLength, pSrc);
970 
971     return E_NOTIMPL;
972 }
973 
974 static const struct IDataConvertVtbl convert_vtbl =
975 {
976     convert_QueryInterface,
977     convert_AddRef,
978     convert_Release,
979     convert_DataConvert,
980     convert_CanConvert,
981     convert_GetConversionSize
982 };
983 
984 static HRESULT WINAPI dcinfo_QueryInterface(IDCInfo* iface, REFIID riid, void **obj)
985 {
986     convert *This = impl_from_IDCInfo(iface);
987 
988     return IDataConvert_QueryInterface(&This->IDataConvert_iface, riid, obj);
989 }
990 
991 static ULONG WINAPI dcinfo_AddRef(IDCInfo* iface)
992 {
993     convert *This = impl_from_IDCInfo(iface);
994 
995     return IDataConvert_AddRef(&This->IDataConvert_iface);
996 }
997 
998 static ULONG WINAPI dcinfo_Release(IDCInfo* iface)
999 {
1000     convert *This = impl_from_IDCInfo(iface);
1001 
1002     return IDataConvert_Release(&This->IDataConvert_iface);
1003 }
1004 
1005 static HRESULT WINAPI dcinfo_GetInfo(IDCInfo *iface, ULONG num, DCINFOTYPE types[], DCINFO **info_ptr)
1006 {
1007     convert *This = impl_from_IDCInfo(iface);
1008     ULONG i;
1009     DCINFO *infos;
1010 
1011     TRACE("(%p)->(%d, %p, %p)\n", This, num, types, info_ptr);
1012 
1013     *info_ptr = infos = CoTaskMemAlloc(num * sizeof(*infos));
1014     if(!infos) return E_OUTOFMEMORY;
1015 
1016     for(i = 0; i < num; i++)
1017     {
1018         infos[i].eInfoType = types[i];
1019         VariantInit(&infos[i].vData);
1020 
1021         switch(types[i])
1022         {
1023         case DCINFOTYPE_VERSION:
1024             V_VT(&infos[i].vData) = VT_UI4;
1025             V_UI4(&infos[i].vData) = This->version;
1026             break;
1027         }
1028     }
1029 
1030     return S_OK;
1031 }
1032 
1033 static HRESULT WINAPI dcinfo_SetInfo(IDCInfo* iface, ULONG num, DCINFO info[])
1034 {
1035     convert *This = impl_from_IDCInfo(iface);
1036     ULONG i;
1037     HRESULT hr = S_OK;
1038 
1039     TRACE("(%p)->(%d, %p)\n", This, num, info);
1040 
1041     for(i = 0; i < num; i++)
1042     {
1043         switch(info[i].eInfoType)
1044         {
1045         case DCINFOTYPE_VERSION:
1046             if(V_VT(&info[i].vData) != VT_UI4)
1047             {
1048                 FIXME("VERSION with vt %x\n", V_VT(&info[i].vData));
1049                 hr = DB_S_ERRORSOCCURRED;
1050                 break;
1051             }
1052             This->version = V_UI4(&info[i].vData);
1053             break;
1054 
1055         default:
1056             FIXME("Unhandled info type %d (vt %x)\n", info[i].eInfoType, V_VT(&info[i].vData));
1057         }
1058     }
1059     return hr;
1060 }
1061 
1062 static const struct IDCInfoVtbl dcinfo_vtbl =
1063 {
1064     dcinfo_QueryInterface,
1065     dcinfo_AddRef,
1066     dcinfo_Release,
1067     dcinfo_GetInfo,
1068     dcinfo_SetInfo
1069 };
1070 
1071 HRESULT create_oledb_convert(IUnknown *outer, void **obj)
1072 {
1073     convert *This;
1074 
1075     TRACE("(%p, %p)\n", outer, obj);
1076 
1077     *obj = NULL;
1078 
1079     if(outer) return CLASS_E_NOAGGREGATION;
1080 
1081     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1082     if(!This) return E_OUTOFMEMORY;
1083 
1084     This->IDataConvert_iface.lpVtbl = &convert_vtbl;
1085     This->IDCInfo_iface.lpVtbl = &dcinfo_vtbl;
1086     This->ref = 1;
1087     This->version = 0x110;
1088 
1089     *obj = &This->IDataConvert_iface;
1090 
1091     return S_OK;
1092 }
1093 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.