diff --git a/patches/oledb32-mode-property/0001-oledb32-Support-Multiple-values-when-parsing-the-pro.patch b/patches/oledb32-mode-property/0001-oledb32-Support-Multiple-values-when-parsing-the-pro.patch new file mode 100644 index 00000000..c48b8567 --- /dev/null +++ b/patches/oledb32-mode-property/0001-oledb32-Support-Multiple-values-when-parsing-the-pro.patch @@ -0,0 +1,102 @@ +From a954250ce33000b242124b933e1607566782dade Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 8 Jun 2024 16:26:54 +1000 +Subject: [PATCH] oledb32: Support Multiple values when parsing the property + Mode. + +The "Mode" can be a mix of any of the flags. +--- + dlls/oledb32/datainit.c | 40 +++++++++++++++++++++++++++++------ + dlls/oledb32/tests/database.c | 14 ++++++++++++ + 2 files changed, 48 insertions(+), 6 deletions(-) + +diff --git a/dlls/oledb32/datainit.c b/dlls/oledb32/datainit.c +index 38ed5ce0e53..1c0a531ab26 100644 +--- a/dlls/oledb32/datainit.c ++++ b/dlls/oledb32/datainit.c +@@ -335,16 +335,44 @@ static HRESULT convert_dbproperty_mode(const WCHAR *src, VARIANT *dest) + { L"Write", DB_MODE_WRITE }, + }; + struct mode_propval *prop; ++ WCHAR mode[64]; ++ WCHAR *pos = NULL; ++ const WCHAR *lastpos = src; + +- if ((prop = bsearch(src, mode_propvals, ARRAY_SIZE(mode_propvals), +- sizeof(struct mode_propval), dbmodeprop_compare))) ++ V_VT(dest) = VT_I4; ++ V_I4(dest) = 0; ++ ++ pos = wcsstr(src, L"|"); ++ while (pos != NULL) + { +- V_VT(dest) = VT_I4; +- V_I4(dest) = prop->value; +- TRACE("%s = %#lx\n", debugstr_w(src), prop->value); +- return S_OK; ++ lstrcpynW(mode, lastpos, pos - lastpos + 1); ++ ++ if (!(prop = bsearch(mode, mode_propvals, ARRAY_SIZE(mode_propvals), ++ sizeof(struct mode_propval), dbmodeprop_compare))) ++ goto done; ++ ++ V_I4(dest) |= prop->value; ++ ++ lastpos = pos + 1; ++ pos = wcsstr(lastpos, L"|"); + } + ++ if (lastpos) ++ { ++ lstrcpyW(mode, lastpos); ++ if (!(prop = bsearch(mode, mode_propvals, ARRAY_SIZE(mode_propvals), ++ sizeof(struct mode_propval), dbmodeprop_compare))) ++ goto done; ++ ++ V_I4(dest) |= prop->value; ++ } ++ ++ TRACE("%s = %#lx\n", debugstr_w(src), V_I4(dest)); ++ return S_OK; ++ ++done: ++ FIXME("Failed to parse Mode (%s)\n", debugstr_w(src)); ++ + return E_FAIL; + } + +diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c +index 6296ecfe1ef..bcee13017a7 100644 +--- a/dlls/oledb32/tests/database.c ++++ b/dlls/oledb32/tests/database.c +@@ -557,6 +557,8 @@ static void test_initializationstring(void) + static const WCHAR *initstring_mode = L"Provider=MSDASQL.1;Data Source=dummy;Mode=invalid"; + static const WCHAR *initstring_mode2 = L"Provider=MSDASQL.1;Data Source=dummy;Mode=WriteRead"; + static const WCHAR *initstring_mode3 = L"Provider=MSDASQL.1;Data Source=dummy;Mode=ReadWRITE"; ++ static const WCHAR *initstring_mode4 = L"Provider=MSDASQL.1;Data Source=dummy;Mode=ReadWrite|Share Deny None"; ++ static const WCHAR *initstring_mode5 = L"Provider=MSDASQL.1;Data Source=dummy;Mode=ReadWrite|Share Deny None|Share Exclusive"; + static const WCHAR *initstring_quote_semicolon = L"Provider=MSDASQL.1;" + "Data Source=dummy;" + "Extended Properties=\"ConnectTo=11.0;Cell Error Mode=TextValue;Optimize Response=3;\""; +@@ -625,6 +627,18 @@ static void test_initializationstring(void) + &IID_IDBInitialize, (IUnknown **)&dbinit); + ok(hr == S_OK, "got 0x%08lx\n", hr); + IDBInitialize_Release(dbinit); ++ ++ dbinit = NULL; ++ hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode4, ++ &IID_IDBInitialize, (IUnknown **)&dbinit); ++ ok(hr == S_OK, "got 0x%08lx\n", hr); ++ IDBInitialize_Release(dbinit); ++ ++ dbinit = NULL; ++ hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode5, ++ &IID_IDBInitialize, (IUnknown **)&dbinit); ++ ok(hr == S_OK, "got 0x%08lx\n", hr); ++ IDBInitialize_Release(dbinit); + } + else + ok(dbinit == NULL, "got %p\n", dbinit); +-- +2.43.0 + diff --git a/patches/oledb32-mode-property/definition b/patches/oledb32-mode-property/definition new file mode 100644 index 00000000..2006f802 --- /dev/null +++ b/patches/oledb32-mode-property/definition @@ -0,0 +1,6 @@ +Fixes: [7955] oledb32: Mode can have multiple values as a string + +# Found while testing S-Hoai application. + +#PR: https://gitlab.winehq.org/wine/wine/-/merge_requests/5817 +