From: Alistair Leslie-Hughes Subject: [PATCH] oledb32: Support Milliseconds when converting BSTR -> DBTIMESTAMP Message-Id: Date: Mon, 14 Oct 2019 03:49:57 +0000 Signed-off-by: Alistair Leslie-Hughes --- dlls/oledb32/convert.c | 30 ++++++++++++++++++++++++++++++ dlls/oledb32/tests/convert.c | 29 +++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/dlls/oledb32/convert.c b/dlls/oledb32/convert.c index a5bbdbc2456..c4ee59996a1 100644 --- a/dlls/oledb32/convert.c +++ b/dlls/oledb32/convert.c @@ -30,11 +30,25 @@ #include "oledb_private.h" +#include #include "wine/debug.h" #include "wine/heap.h" WINE_DEFAULT_DEBUG_CHANNEL(oledb); +static inline char *strdupWtoA( LPCWSTR str ) +{ + LPSTR ret = NULL; + DWORD len; + + if (!str) return ret; + len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + ret = heap_alloc( len ); + if (ret) + WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL ); + return ret; +} + typedef struct { IDataConvert IDataConvert_iface; @@ -566,6 +580,22 @@ static HRESULT WINAPI convert_DataConvert(IDataConvert* iface, d->second = st.wSecond; d->fraction = st.wMilliseconds * 1000000; } + else + { + char *buff = strdupWtoA(s); + static const char *format = "%d-%d-%d %d:%d:%d.%d"; + + if(sscanf( buff, format, &d->year, &d->month, &d->day, &d->hour, &d->minute, &d->second, &d->fraction) != 7) + { + hr = DISP_E_TYPEMISMATCH; + *dst_status = DBSTATUS_E_CANTCONVERTVALUE; + *dst_len = get_length(dst_type); + } + else + hr = S_OK; + + heap_free(buff); + } VariantClear(&var); } diff --git a/dlls/oledb32/tests/convert.c b/dlls/oledb32/tests/convert.c index 51fd2f7fa37..73c9430bfd3 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; -- 2.17.1