Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> writes:
+static inline WCHAR *heap_attrdupAtoW(const char *str) +{ + WCHAR *ret = NULL; + + if (str) + { + DWORD size = 0, len; + const char *p; + WCHAR *current; + + for (p = str; *p; p += lstrlenA(p) + 1) + { + len = MultiByteToWideChar(CP_ACP, 0, p, -1, NULL, 0); + size += len; + } + + current = ret = heap_alloc_zero( (size+1)*sizeof(WCHAR)); + for (p = str; *p; p += lstrlenA(p) + 1) + { + len = MultiByteToWideChar(CP_ACP, 0, p, -1, current, size); + current += len; + }
There's no reason to convert strings one at a time, you can convert the entire data in one call.
+static BOOL call_ConfigDSN(HANDLE mod, HWND hwnd, WORD request, const char *driverA, const char *attributesA, const WCHAR *driverW, const WCHAR *attributesW) +{ + BOOL (WINAPI *pConfigDSN)(HWND hwnd, WORD request, const char *driver, const char *attr); + BOOL (WINAPI *pConfigDSNW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *attr); + BOOL ret = FALSE; + + TRACE("%p, %p, %d, %p, %p, %p %p\n", mod, hwnd, request, driverA, attributesA, driverW, attributesW); + + pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN"); + pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW"); + + if (pConfigDSNW) + { + const WCHAR *attr = attributesW; + if(!attr) + attr = heap_attrdupAtoW(attributesA); + + TRACE("Calling ConfigDSNW (%p)\n", pConfigDSNW); + + ret = pConfigDSNW(hwnd, request, driverW, attr); + + if(attr != attributesW) + heap_free((WCHAR *)attr); + } + else if (pConfigDSN) + { + TRACE("Calling pConfigDSN (%p)\n", pConfigDSN); + ret = pConfigDSN(hwnd, request, driverA, attributesA); + } + else + ERR("Neither ConfigDSN or ConfigDSNW found.\n"); + + if (!ret) + push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed); + + return ret; +}
This helper function is ugly, I expect the code would look better without it, doing things directly in the corresponding entry points. -- Alexandre Julliard julliard(a)winehq.org