2 * Copyright (C) 2012 Alistair Leslie-Hughes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "oledb_private.h"
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(oledb
);
36 DEFINE_GUID(DBPROPSET_DBINIT
, 0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
38 typedef struct datainit
40 IDataInitialize IDataInitialize_iface
;
45 static inline datainit
*impl_from_IDataInitialize(IDataInitialize
*iface
)
47 return CONTAINING_RECORD(iface
, datainit
, IDataInitialize_iface
);
52 IDBInitialize IDBInitialize_iface
;
53 IDBProperties IDBProperties_iface
;
58 static inline dbinit
*impl_from_IDBInitialize(IDBInitialize
*iface
)
60 return CONTAINING_RECORD(iface
, dbinit
, IDBInitialize_iface
);
63 static inline dbinit
*impl_from_IDBProperties(IDBProperties
*iface
)
65 return CONTAINING_RECORD(iface
, dbinit
, IDBProperties_iface
);
68 static HRESULT WINAPI
dbprops_QueryInterface(IDBProperties
*iface
, REFIID riid
, void **ppvObject
)
70 dbinit
*This
= impl_from_IDBProperties(iface
);
72 return IDBInitialize_QueryInterface(&This
->IDBInitialize_iface
, riid
, ppvObject
);
75 static ULONG WINAPI
dbprops_AddRef(IDBProperties
*iface
)
77 dbinit
*This
= impl_from_IDBProperties(iface
);
79 return IDBInitialize_AddRef(&This
->IDBInitialize_iface
);
82 static ULONG WINAPI
dbprops_Release(IDBProperties
*iface
)
84 dbinit
*This
= impl_from_IDBProperties(iface
);
86 return IDBInitialize_Release(&This
->IDBInitialize_iface
);
89 static HRESULT WINAPI
dbprops_GetProperties(IDBProperties
*iface
, ULONG cPropertyIDSets
,
90 const DBPROPIDSET rgPropertyIDSets
[], ULONG
*pcPropertySets
, DBPROPSET
**prgPropertySets
)
92 dbinit
*This
= impl_from_IDBProperties(iface
);
94 FIXME("(%p)->(%d %p %p %p)\n", This
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
99 static HRESULT WINAPI
dbprops_GetPropertyInfo(IDBProperties
*iface
, ULONG cPropertyIDSets
,
100 const DBPROPIDSET rgPropertyIDSets
[], ULONG
*pcPropertyInfoSets
,
101 DBPROPINFOSET
**prgPropertyInfoSets
, OLECHAR
**ppDescBuffer
)
103 dbinit
*This
= impl_from_IDBProperties(iface
);
105 FIXME("(%p)->(%d %p %p %p %p)\n", This
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertyInfoSets
,
106 prgPropertyInfoSets
, ppDescBuffer
);
111 static HRESULT WINAPI
dbprops_SetProperties(IDBProperties
*iface
, ULONG cPropertySets
,
112 DBPROPSET rgPropertySets
[])
114 dbinit
*This
= impl_from_IDBProperties(iface
);
116 FIXME("(%p)->(%d %p)\n", This
, cPropertySets
, rgPropertySets
);
121 static const struct IDBPropertiesVtbl dbprops_vtbl
=
123 dbprops_QueryInterface
,
126 dbprops_GetProperties
,
127 dbprops_GetPropertyInfo
,
128 dbprops_SetProperties
131 static HRESULT WINAPI
dbinit_QueryInterface(IDBInitialize
*iface
, REFIID riid
, void **obj
)
133 dbinit
*This
= impl_from_IDBInitialize(iface
);
134 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
138 if(IsEqualIID(riid
, &IID_IUnknown
) ||
139 IsEqualIID(riid
, &IID_IDBInitialize
))
143 else if(IsEqualIID(riid
, &IID_IDBProperties
))
145 *obj
= &This
->IDBProperties_iface
;
149 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
150 return E_NOINTERFACE
;
153 IDBInitialize_AddRef(iface
);
157 static ULONG WINAPI
dbinit_AddRef(IDBInitialize
*iface
)
159 dbinit
*This
= impl_from_IDBInitialize(iface
);
160 TRACE("(%p)\n", This
);
162 return InterlockedIncrement(&This
->ref
);
165 static ULONG WINAPI
dbinit_Release(IDBInitialize
*iface
)
167 dbinit
*This
= impl_from_IDBInitialize(iface
);
170 TRACE("(%p)\n", This
);
172 ref
= InterlockedDecrement(&This
->ref
);
179 static HRESULT WINAPI
dbinit_Initialize(IDBInitialize
*iface
)
181 dbinit
*This
= impl_from_IDBInitialize(iface
);
183 FIXME("(%p) stub\n", This
);
188 static HRESULT WINAPI
dbinit_Uninitialize(IDBInitialize
*iface
)
190 dbinit
*This
= impl_from_IDBInitialize(iface
);
192 FIXME("(%p) stub\n", This
);
197 static const IDBInitializeVtbl dbinit_vtbl
=
199 dbinit_QueryInterface
,
206 static HRESULT
create_db_init(IUnknown
**obj
)
214 This
= heap_alloc(sizeof(*This
));
215 if(!This
) return E_OUTOFMEMORY
;
217 This
->IDBInitialize_iface
.lpVtbl
= &dbinit_vtbl
;
218 This
->IDBProperties_iface
.lpVtbl
= &dbprops_vtbl
;
221 *obj
= (IUnknown
*)&This
->IDBInitialize_iface
;
226 static HRESULT WINAPI
datainit_QueryInterface(IDataInitialize
*iface
, REFIID riid
, void **obj
)
228 datainit
*This
= impl_from_IDataInitialize(iface
);
229 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
233 if(IsEqualIID(riid
, &IID_IUnknown
) ||
234 IsEqualIID(riid
, &IID_IDataInitialize
))
236 *obj
= &This
->IDataInitialize_iface
;
240 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
241 return E_NOINTERFACE
;
244 IDataInitialize_AddRef(iface
);
248 static ULONG WINAPI
datainit_AddRef(IDataInitialize
*iface
)
250 datainit
*This
= impl_from_IDataInitialize(iface
);
251 TRACE("(%p)\n", This
);
253 return InterlockedIncrement(&This
->ref
);
256 static ULONG WINAPI
datainit_Release(IDataInitialize
*iface
)
258 datainit
*This
= impl_from_IDataInitialize(iface
);
261 TRACE("(%p)\n", This
);
263 ref
= InterlockedDecrement(&This
->ref
);
270 static void free_dbpropset(ULONG count
, DBPROPSET
*propset
)
274 for (i
= 0; i
< count
; i
++)
278 for (p
= 0; p
< propset
[i
].cProperties
; p
++)
279 VariantClear(&propset
[i
].rgProperties
[p
].vValue
);
281 CoTaskMemFree(propset
[i
].rgProperties
);
283 CoTaskMemFree(propset
);
289 DBPROPOPTIONS options
;
293 static const WCHAR asyncW
[] = {'A','s','y','n','c','h','r','o','n','o','u','s',' ','P','r','o','c','e','s','s','i','n','g',0};
294 static const WCHAR bindW
[] = {'B','i','n','d',' ','F','l','a','g','s',0};
295 static const WCHAR cacheW
[] = {'C','a','c','h','e',' ','A','u','t','h','e','n','i','c','a','t','i','o','n',0};
296 static const WCHAR conn_timeout
[] = {'C','o','n','n','e','c','t',' ','T','i','m','e','o','u','t',0};
297 static const WCHAR datasourceW
[] = {'D','a','t','a',' ','S','o','u','r','c','e',0};
298 static const WCHAR encryptW
[] = {'E','n','c','r','y','p','t',' ','P','a','s','s','w','o','r','d',0};
299 static const WCHAR extendedW
[] = {'E','x','t','e','n','d','e','d',' ','P','r','o','p','e','r','t','i','e','s',0};
300 static const WCHAR gen_timeout
[] = {'G','e','n','e','r','a','l',' ','T','i','m','e','o','u','t',0};
301 static const WCHAR impersonW
[] = {'I','m','p','e','r','s','o','n','a','t','i','o','n',' ','L','e','v','e','l',0};
302 static const WCHAR initcatW
[] = {'I','n','i','t','i','a','l',' ','C','a','t','a','l','o','g',0};
303 static const WCHAR integratedW
[] = {'I','n','t','e','g','r','a','t','e','d',' ','S','e','c','u','r','i','t','y',0};
304 static const WCHAR localeIDW
[] = {'L','o','c','a','l','e',' ','I','d','e','n','t','i','f','i','e','r',0};
305 static const WCHAR locationW
[] = {'L','o','c','a','t','i','o','n',0};
306 static const WCHAR lockownerW
[] = {'L','o','c','k',' ','O','w','n','e','r',0};
307 static const WCHAR maskpassW
[] = {'M','a','s','k',' ','P','a','s','s','w','o','r','d',0};
308 static const WCHAR modeW
[] = {'M','o','d','e',0};
309 static const WCHAR oledbservW
[] = {'O','L','E',' ','D','B',' ','S','e','r','v','i','c','i','e','s',0};
310 static const WCHAR passwordW
[] = {'P','a','s','s','w','o','r','d',0};
311 static const WCHAR persistW
[] = {'P','e','r','s','i','s','t',' ','S','e','c','u','r','i','t','y',' ','I','n','f','o',0};
312 static const WCHAR persistEncW
[] = {'P','e','r','s','i','s','t',' ','E','n','c','r','y','p','t','e','d',0};
313 static const WCHAR promptW
[] = {'P','r','o','m','p','t',0};
314 static const WCHAR protectW
[] = {'P','r','o','t','e','c','t','i','o','n',' ','l','e','v','e','l',0};
315 static const WCHAR useridW
[] = {'U','s','e','r',' ','I','D',0};
316 static const WCHAR winhandleW
[] = {'W','i','n','d','o','w',' ','H','a','n','d','l','e',0};
318 static const struct dbproperty dbproperties
[] = {
319 { asyncW
, DBPROP_INIT_ASYNCH
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
320 { bindW
, DBPROP_INIT_BINDFLAGS
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
321 { cacheW
, DBPROP_AUTH_CACHE_AUTHINFO
, DBPROPOPTIONS_OPTIONAL
, VT_BOOL
},
322 { conn_timeout
,DBPROP_INIT_TIMEOUT
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
323 { datasourceW
, DBPROP_INIT_DATASOURCE
, DBPROPOPTIONS_REQUIRED
, VT_BSTR
},
324 { extendedW
, DBPROP_INIT_PROVIDERSTRING
, DBPROPOPTIONS_REQUIRED
, VT_BSTR
},
325 { encryptW
, DBPROP_AUTH_ENCRYPT_PASSWORD
, DBPROPOPTIONS_REQUIRED
, VT_BOOL
},
326 { gen_timeout
, DBPROP_INIT_GENERALTIMEOUT
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
327 { impersonW
, DBPROP_INIT_IMPERSONATION_LEVEL
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
328 { initcatW
, DBPROP_CATALOGLOCATION
, DBPROPOPTIONS_OPTIONAL
, VT_BSTR
},
329 { integratedW
, DBPROP_AUTH_INTEGRATED
, DBPROPOPTIONS_OPTIONAL
, VT_BSTR
},
330 { localeIDW
, DBPROP_INIT_LCID
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
331 { locationW
, DBPROP_INIT_LOCATION
, DBPROPOPTIONS_OPTIONAL
, VT_BSTR
},
332 { lockownerW
, DBPROP_INIT_LOCKOWNER
, DBPROPOPTIONS_OPTIONAL
, VT_BSTR
},
333 { maskpassW
, DBPROP_AUTH_MASK_PASSWORD
, DBPROPOPTIONS_OPTIONAL
, VT_BOOL
},
334 { modeW
, DBPROP_INIT_MODE
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
335 { oledbservW
, DBPROP_INIT_OLEDBSERVICES
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
336 { passwordW
, DBPROP_AUTH_PASSWORD
, DBPROPOPTIONS_OPTIONAL
, VT_BSTR
},
337 { persistEncW
, DBPROP_AUTH_PERSIST_ENCRYPTED
, DBPROPOPTIONS_OPTIONAL
, VT_BOOL
},
338 { persistW
, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
, DBPROPOPTIONS_OPTIONAL
, VT_BOOL
},
339 { promptW
, DBPROP_INIT_PROMPT
, DBPROPOPTIONS_OPTIONAL
, VT_I2
},
340 { protectW
, DBPROP_INIT_PROTECTION_LEVEL
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
341 { useridW
, DBPROP_AUTH_USERID
, DBPROPOPTIONS_OPTIONAL
, VT_BSTR
},
343 { winhandleW
, DBPROP_INIT_HWND
, DBPROPOPTIONS_OPTIONAL
, VT_I4
},
345 { winhandleW
, DBPROP_INIT_HWND
, DBPROPOPTIONS_OPTIONAL
, VT_I8
},
350 static HRESULT
set_dbpropset(BSTR name
, BSTR value
, DBPROPSET
**propset
)
357 max
= sizeof(dbproperties
)/sizeof(struct dbproperty
) - 1;
365 r
= strcmpiW(dbproperties
[n
].name
, name
);
378 FIXME("unsupported property %s\n", debugstr_w(name
));
384 V_VT(&src
) = VT_BSTR
;
385 V_BSTR(&src
) = value
;
387 hr
= VariantChangeType(&dest
, &src
, 0, dbproperties
[n
].type
);
390 ERR("failed to init property %s value as type %d\n", debugstr_w(name
), dbproperties
[n
].type
);
394 *propset
= CoTaskMemAlloc(sizeof(DBPROPSET
));
398 return E_OUTOFMEMORY
;
401 (*propset
)->rgProperties
= CoTaskMemAlloc(sizeof(DBPROP
));
402 if (!(*propset
)->rgProperties
)
405 CoTaskMemFree(*propset
);
406 return E_OUTOFMEMORY
;
409 (*propset
)->cProperties
= 1;
410 (*propset
)->guidPropertySet
= DBPROPSET_DBINIT
;
411 (*propset
)->rgProperties
[0].dwPropertyID
= dbproperties
[n
].id
;
412 (*propset
)->rgProperties
[0].dwOptions
= dbproperties
[n
].options
;
413 (*propset
)->rgProperties
[0].dwStatus
= 0;
414 memset(&(*propset
)->rgProperties
[0].colid
, 0, sizeof(DBID
));
415 (*propset
)->rgProperties
[0].vValue
= dest
;
420 /*** IDataInitialize methods ***/
421 static HRESULT WINAPI
datainit_GetDataSource(IDataInitialize
*iface
, IUnknown
*outer
, DWORD clsctx
,
422 LPWSTR initstring
, REFIID riid
, IUnknown
**datasource
)
424 static const WCHAR providerW
[] = {'P','r','o','v','i','d','e','r','=',0};
425 static const WCHAR msdasqlW
[] = {'M','S','D','A','S','Q','L',0};
426 datainit
*This
= impl_from_IDataInitialize(iface
);
427 IDBProperties
*dbprops
;
433 TRACE("(%p)->(%p 0x%x %s %s %p)\n", This
, outer
, clsctx
, debugstr_w(initstring
), debugstr_guid(riid
), datasource
);
435 /* first get provider name */
436 provclsid
= IID_NULL
;
437 if (initstring
&& (prov
= strstrW(initstring
, providerW
)))
439 WCHAR
*start
, *progid
;
442 prov
+= sizeof(providerW
)/sizeof(WCHAR
)-1;
444 while (*prov
&& *prov
!= ';')
446 TRACE("got provider %s\n", debugstr_wn(start
, prov
-start
));
449 progid
= CoTaskMemAlloc((len
+1)*sizeof(WCHAR
));
450 if (!progid
) return E_OUTOFMEMORY
;
452 memcpy(progid
, start
, len
*sizeof(WCHAR
));
455 hr
= CLSIDFromProgID(progid
, &provclsid
);
456 CoTaskMemFree(progid
);
459 ERR("provider %s not registered\n", debugstr_wn(start
, prov
-start
));
465 hr
= CLSIDFromProgID(msdasqlW
, &provclsid
);
467 ERR("ODBC provider for OLE DB not registered\n");
470 /* check for provider mismatch if it was specified in init string */
471 if (*datasource
&& prov
)
473 DBPROPIDSET propidset
;
474 enum DBPROPENUM prop
;
478 hr
= IUnknown_QueryInterface(*datasource
, &IID_IDBProperties
, (void**)&dbprops
);
481 WARN("provider doesn't support IDBProperties\n");
485 prop
= DBPROP_INIT_DATASOURCE
;
486 propidset
.rgPropertyIDs
= &prop
;
487 propidset
.cPropertyIDs
= 1;
488 propidset
.guidPropertySet
= DBPROPSET_DBINIT
;
491 hr
= IDBProperties_GetProperties(dbprops
, 1, &propidset
, &count
, &propset
);
492 IDBProperties_Release(dbprops
);
495 WARN("GetProperties failed for datasource, 0x%08x\n", hr
);
499 TRACE("initial data source provider %s\n", debugstr_w(V_BSTR(&propset
->rgProperties
[0].vValue
)));
501 CLSIDFromProgID(V_BSTR(&propset
->rgProperties
[0].vValue
), &initprov
);
502 free_dbpropset(count
, propset
);
504 if (!IsEqualIID(&provclsid
, &initprov
)) return DB_E_MISMATCHEDPROVIDER
;
509 if (!IsEqualIID(&provclsid
, &IID_NULL
))
510 hr
= CoCreateInstance(&provclsid
, outer
, clsctx
, riid
, (void**)datasource
);
512 if (FAILED(hr
) && IsEqualIID(riid
, &IID_IDBInitialize
))
513 hr
= create_db_init(datasource
);
516 /* now set properties */
521 hr
= IUnknown_QueryInterface(*datasource
, &IID_IDBProperties
, (void**)&dbprops
);
524 WARN("provider doesn't support IDBProperties\n");
529 while (start
&& (eq
= strchrW(start
, '=')))
531 static const WCHAR providerW
[] = {'P','r','o','v','i','d','e','r',0};
532 WCHAR
*scol
= strchrW(eq
+1, ';');
535 name
= SysAllocStringLen(start
, eq
- start
);
536 /* skip equal sign to get value */
538 value
= SysAllocStringLen(eq
, scol
? scol
- eq
: -1);
540 /* skip semicolon if present */
544 if (!strcmpW(name
, providerW
))
547 SysFreeString(value
);
551 TRACE("property (name=%s, value=%s)\n", debugstr_w(name
), debugstr_w(value
));
553 hr
= set_dbpropset(name
, value
, &propset
);
555 SysFreeString(value
);
556 if (FAILED(hr
)) break;
558 hr
= IDBProperties_SetProperties(dbprops
, 1, propset
);
559 free_dbpropset(1, propset
);
560 TRACE("provider ret 0x%08x\n", hr
);
563 IDBProperties_Release(dbprops
);
569 /* returns character length of string representation */
570 static int get_propvalue_length(DBPROP
*prop
)
575 if (V_VT(&prop
->vValue
) == VT_BSTR
) return SysStringLen(V_BSTR(&prop
->vValue
));
578 hr
= VariantChangeType(&str
, &prop
->vValue
, 0, VT_BSTR
);
581 int len
= SysStringLen(V_BSTR(&str
));
589 static void write_propvalue_str(WCHAR
*str
, DBPROP
*prop
)
591 VARIANT
*v
= &prop
->vValue
;
595 if (V_VT(v
) == VT_BSTR
)
597 strcatW(str
, V_BSTR(v
));
602 hr
= VariantChangeType(&vstr
, v
, VARIANT_ALPHABOOL
, VT_BSTR
);
605 strcatW(str
, V_BSTR(&vstr
));
610 static WCHAR
*get_propinfo_descr(DBPROP
*prop
, DBPROPINFOSET
*propinfoset
)
614 for (i
= 0; i
< propinfoset
->cPropertyInfos
; i
++)
615 if (propinfoset
->rgPropertyInfos
[i
].dwPropertyID
== prop
->dwPropertyID
)
616 return propinfoset
->rgPropertyInfos
[i
].pwszDescription
;
621 static void free_dbpropinfoset(ULONG count
, DBPROPINFOSET
*propinfoset
)
625 for (i
= 0; i
< count
; i
++)
629 for (p
= 0; p
< propinfoset
[i
].cPropertyInfos
; p
++)
630 VariantClear(&propinfoset
[i
].rgPropertyInfos
[p
].vValues
);
632 CoTaskMemFree(propinfoset
[i
].rgPropertyInfos
);
634 CoTaskMemFree(propinfoset
);
637 static HRESULT WINAPI
datainit_GetInitializationString(IDataInitialize
*iface
, IUnknown
*datasource
,
638 boolean include_pass
, LPWSTR
*init_string
)
640 static const WCHAR provW
[] = {'P','r','o','v','i','d','e','r','=',0};
641 static const WCHAR colW
[] = {';',0};
642 datainit
*This
= impl_from_IDataInitialize(iface
);
643 DBPROPINFOSET
*propinfoset
;
644 IDBProperties
*props
;
645 DBPROPIDSET propidset
;
646 ULONG count
, infocount
;
647 WCHAR
*progid
, *desc
;
654 TRACE("(%p)->(%p %d %p)\n", This
, datasource
, include_pass
, init_string
);
656 /* IPersist support is mandatory for data sources */
657 hr
= IUnknown_QueryInterface(datasource
, &IID_IPersist
, (void**)&persist
);
658 if (FAILED(hr
)) return hr
;
660 memset(&clsid
, 0, sizeof(clsid
));
661 hr
= IPersist_GetClassID(persist
, &clsid
);
662 IPersist_Release(persist
);
663 if (FAILED(hr
)) return hr
;
666 ProgIDFromCLSID(&clsid
, &progid
);
667 TRACE("clsid=%s, progid=%s\n", debugstr_guid(&clsid
), debugstr_w(progid
));
669 /* now get initialization properties */
670 hr
= IUnknown_QueryInterface(datasource
, &IID_IDBProperties
, (void**)&props
);
673 WARN("IDBProperties not supported\n");
674 CoTaskMemFree(progid
);
678 propidset
.rgPropertyIDs
= NULL
;
679 propidset
.cPropertyIDs
= 0;
680 propidset
.guidPropertySet
= DBPROPSET_DBINIT
;
683 hr
= IDBProperties_GetProperties(props
, 1, &propidset
, &count
, &propset
);
686 WARN("failed to get data source properties, 0x%08x\n", hr
);
687 CoTaskMemFree(progid
);
692 IDBProperties_GetPropertyInfo(props
, 1, &propidset
, &infocount
, &propinfoset
, &desc
);
693 IDBProperties_Release(props
);
695 /* check if we need to skip password */
696 len
= strlenW(progid
) + strlenW(provW
) + 1; /* including ';' */
697 for (i
= 0; i
< count
; i
++)
699 WCHAR
*descr
= get_propinfo_descr(&propset
->rgProperties
[i
], propinfoset
);
702 /* include '=' and ';' */
703 len
+= strlenW(descr
) + 2;
704 len
+= get_propvalue_length(&propset
->rgProperties
[i
]);
707 if ((propset
->rgProperties
[i
].dwPropertyID
== DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
) &&
708 (V_BOOL(&propset
->rgProperties
[i
].vValue
) == VARIANT_FALSE
))
709 include_pass
= FALSE
;
712 len
*= sizeof(WCHAR
);
713 *init_string
= CoTaskMemAlloc(len
);
717 strcatW(*init_string
, provW
);
718 strcatW(*init_string
, progid
);
719 strcatW(*init_string
, colW
);
720 CoTaskMemFree(progid
);
722 for (i
= 0; i
< count
; i
++)
726 if (!include_pass
&& propset
->rgProperties
[i
].dwPropertyID
== DBPROP_AUTH_PASSWORD
) continue;
728 descr
= get_propinfo_descr(&propset
->rgProperties
[i
], propinfoset
);
731 static const WCHAR eqW
[] = {'=',0};
732 strcatW(*init_string
, descr
);
733 strcatW(*init_string
, eqW
);
734 write_propvalue_str(*init_string
, &propset
->rgProperties
[i
]);
735 strcatW(*init_string
, colW
);
739 free_dbpropset(count
, propset
);
740 free_dbpropinfoset(infocount
, propinfoset
);
744 TRACE("%s\n", debugstr_w(*init_string
));
748 static HRESULT WINAPI
datainit_CreateDBInstance(IDataInitialize
*iface
, REFCLSID provider
,
749 IUnknown
*outer
, DWORD clsctx
, LPWSTR reserved
, REFIID riid
,
750 IUnknown
**datasource
)
752 datainit
*This
= impl_from_IDataInitialize(iface
);
754 TRACE("(%p)->(%s %p 0x%08x %s %s %p)\n", This
, debugstr_guid(provider
), outer
, clsctx
, debugstr_w(reserved
),
755 debugstr_guid(riid
), datasource
);
757 return CoCreateInstance(provider
, outer
, clsctx
, riid
, (void**)datasource
);
760 static HRESULT WINAPI
datainit_RemoteCreateDBInstanceEx(IDataInitialize
*iface
, REFCLSID clsidProvider
,
761 IUnknown
*pUnkOuter
, DWORD dwClsCtx
, LPWSTR pwszReserved
, COSERVERINFO
*pServerInfo
,
762 DWORD cmq
, GUID
**rgpIID
, IUnknown
**rgpItf
, HRESULT
*rghr
)
764 datainit
*This
= impl_from_IDataInitialize(iface
);
766 FIXME("(%p)->()\n", This
);
771 static HRESULT WINAPI
datainit_LoadStringFromStorage(IDataInitialize
*iface
, LPWSTR pwszFileName
,
772 LPWSTR
*ppwszInitializationString
)
774 datainit
*This
= impl_from_IDataInitialize(iface
);
776 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(pwszFileName
), ppwszInitializationString
);
781 static HRESULT WINAPI
datainit_WriteStringToStorage(IDataInitialize
*iface
, LPWSTR pwszFileName
,
782 LPWSTR pwszInitializationString
, DWORD dwCreationDisposition
)
784 datainit
*This
= impl_from_IDataInitialize(iface
);
786 FIXME("(%p)->(%s %s %d)\n", This
, debugstr_w(pwszFileName
), debugstr_w(pwszInitializationString
), dwCreationDisposition
);
792 static const struct IDataInitializeVtbl datainit_vtbl
=
794 datainit_QueryInterface
,
797 datainit_GetDataSource
,
798 datainit_GetInitializationString
,
799 datainit_CreateDBInstance
,
800 datainit_RemoteCreateDBInstanceEx
,
801 datainit_LoadStringFromStorage
,
802 datainit_WriteStringToStorage
805 HRESULT
create_data_init(IUnknown
*outer
, void **obj
)
809 TRACE("(%p)\n", obj
);
811 if(outer
) return CLASS_E_NOAGGREGATION
;
815 This
= heap_alloc(sizeof(*This
));
816 if(!This
) return E_OUTOFMEMORY
;
818 This
->IDataInitialize_iface
.lpVtbl
= &datainit_vtbl
;
821 *obj
= &This
->IDataInitialize_iface
;