Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/oledb32/convert.c | 30 ++++++++++++++++++++++++++++-- dlls/oledb32/tests/convert.c | 29 +++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/dlls/oledb32/convert.c b/dlls/oledb32/convert.c index a5bbdbc245..95fbb52943 100644 --- a/dlls/oledb32/convert.c +++ b/dlls/oledb32/convert.c @@ -546,13 +546,15 @@ static HRESULT WINAPI convert_DataConvert(IDataConvert* iface, case DBTYPE_DBTIMESTAMP: memcpy(d, src, sizeof(DBTIMESTAMP)); hr = S_OK; break; case DBTYPE_BSTR: { + BOOL doretry = TRUE; VARIANT var; + DWORD milliseconds = 0; BSTR s = *(WCHAR**)src;
VariantInit(&var); V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(s); - +retry: if ((hr = VariantChangeType(&var, &var, 0, VT_DATE)) == S_OK) { SYSTEMTIME st; @@ -564,7 +566,31 @@ static HRESULT WINAPI convert_DataConvert(IDataConvert* iface, d->hour = st.wHour; d->minute = st.wMinute; d->second = st.wSecond; - d->fraction = st.wMilliseconds * 1000000; + d->fraction = milliseconds; + } + else if(doretry) + { + /* Must be in the format 2013-05-14 02:04:12.017 */ + WCHAR *slash = wcschr(s, '-'); + WCHAR *pos = wcsrchr(s, '.'); + + doretry = FALSE; + + if(!pos || !slash) + { + hr = DISP_E_TYPEMISMATCH; + *dst_status = DBSTATUS_E_CANTCONVERTVALUE; + *dst_len = get_length(dst_type); + } + else + { + SysFreeString(V_BSTR(&var)); + V_BSTR(&var) = SysAllocStringLen(s, pos-s); + + milliseconds = wcstol(pos+1, NULL, 10); + + goto retry; + } }
VariantClear(&var); diff --git a/dlls/oledb32/tests/convert.c b/dlls/oledb32/tests/convert.c index 51fd2f7fa3..73c9430bfd 100644 --- a/dlls/oledb32/tests/convert.c +++ b/dlls/oledb32/tests/convert.c @@ -3919,8 +3919,12 @@ static void test_converttovar(void) static void test_converttotimestamp(void) { static const WCHAR strW[] = {'2','0','1','3','-','0','5','-','1','4',' ','0','2',':','0','4',':','1','2',0}; + static const WCHAR str1W[] = {'2','0','1','3','/','0','5','/','1','4',' ','0','2','.','0','4','.','1','2',0}; static const WCHAR strFullW[] = {'2','0','1','3','-','0','5','-','1','4',' ','0','2',':','0','4',':','1','2', '.','0','1','7','0','0','0','0','0','0',0}; + static const WCHAR strFull1W[] = {'2','0','1','3','/','0','5','/','1','4',' ','0','2',':','0','4',':','1','2', + '.','0','1','7',0}; + DBTIMESTAMP ts = {2013, 5, 14, 2, 4, 12, 0}; DBTIMESTAMP ts1 = {2013, 5, 14, 2, 4, 12, 17000000}; DATE date; @@ -3950,13 +3954,30 @@ static void test_converttotimestamp(void) ok(!memcmp(&ts, &dst, sizeof(ts)), "Wrong timestamp\n"); SysFreeString(bstr);
+ bstr = SysAllocString(str1W); + dst_len = 0x1234; + hr = IDataConvert_DataConvert(convert, DBTYPE_BSTR, DBTYPE_DBTIMESTAMP, 0, &dst_len, &bstr, &dst, sizeof(dst), 0, &dst_status, 0, 0, 0); + ok(hr == S_OK, "got %08x\n", hr); + ok(dst_status == DBSTATUS_S_OK, "got %08x\n", dst_status); + ok(dst_len == sizeof(dst), "got %ld\n", dst_len); + ok(!memcmp(&ts, &dst, sizeof(ts)), "Wrong timestamp\n"); + SysFreeString(bstr); + bstr = SysAllocString(strFullW); dst_len = 0x1234; hr = IDataConvert_DataConvert(convert, DBTYPE_BSTR, DBTYPE_DBTIMESTAMP, 0, &dst_len, &bstr, &dst, sizeof(dst), 0, &dst_status, 0, 0, 0); - todo_wine ok(hr == S_OK, "got %08x\n", hr); - todo_wine ok(dst_status == DBSTATUS_S_OK, "got %08x\n", dst_status); - todo_wine ok(dst_len == sizeof(dst), "got %ld\n", dst_len); - todo_wine ok(!memcmp(&ts1, &dst, sizeof(ts1)), "Wrong timestamp\n"); + ok(hr == S_OK, "got %08x\n", hr); + ok(dst_status == DBSTATUS_S_OK, "got %08x\n", dst_status); + ok(dst_len == sizeof(dst), "got %ld\n", dst_len); + ok(!memcmp(&ts1, &dst, sizeof(ts1)), "Wrong timestamp\n"); + SysFreeString(bstr); + + bstr = SysAllocString(strFull1W); + dst_len = 0x1234; + hr = IDataConvert_DataConvert(convert, DBTYPE_BSTR, DBTYPE_DBTIMESTAMP, 0, &dst_len, &bstr, &dst, sizeof(dst), 0, &dst_status, 0, 0, 0); + ok(hr == DISP_E_TYPEMISMATCH, "got %08x\n", hr); + ok(dst_status == DBSTATUS_E_CANTCONVERTVALUE, "got %08x\n", dst_status); + ok(dst_len == sizeof(dst), "got %ld\n", dst_len); SysFreeString(bstr);
V_VT(&var) = VT_NULL;