ReactOS  0.4.11-dev-465-g0e6bc23
odbccp32.c
Go to the documentation of this file.
1 /*
2  * Implementation of the ODBC driver installer
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2005 Hans Leidekker
6  * Copyright 2007 Bill Medland
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include <assert.h>
24 #include <stdarg.h>
25 
26 #define COBJMACROS
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winreg.h"
31 #include "winnls.h"
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
34 #include "wine/heap.h"
35 
36 #include "odbcinst.h"
37 
39 
40 /* Registry key names */
41 static const WCHAR drivers_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\','O','D','B','C',' ','D','r','i','v','e','r','s',0};
42 static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C',0};
43 static const WCHAR odbcini[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\',0};
44 static const WCHAR odbcdrivers[] = {'O','D','B','C',' ','D','r','i','v','e','r','s',0};
45 static const WCHAR odbctranslators[] = {'O','D','B','C',' ','T','r','a','n','s','l','a','t','o','r','s',0};
46 
47 /* This config mode is known to be process-wide.
48  * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet.
49  * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping.
50  */
52 
53 /* MSDN documentation suggests that the error subsystem handles errors 1 to 8
54  * only and experimentation (Windows 2000) shows that the errors are process-
55  * wide so go for the simple solution; static arrays.
56  */
57 static int num_errors;
58 static int error_code[8];
59 static const WCHAR *error_msg[8];
60 static const WCHAR odbc_error_general_err[] = {'G','e','n','e','r','a','l',' ','e','r','r','o','r',0};
61 static const WCHAR odbc_error_invalid_buff_len[] = {'I','n','v','a','l','i','d',' ','b','u','f','f','e','r',' ','l','e','n','g','t','h',0};
62 static const WCHAR odbc_error_component_not_found[] = {'C','o','m','p','o','n','e','n','t',' ','n','o','t',' ','f','o','u','n','d',0};
63 static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0};
64 static const WCHAR odbc_error_invalid_param_sequence[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','e','q','u','e','n','c','e',0};
65 static const WCHAR odbc_error_invalid_param_string[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','t','r','i','n','g',0};
66 static const WCHAR odbc_error_invalid_dsn[] = {'I','n','v','a','l','i','d',' ','D','S','N',0};
67 static const WCHAR odbc_error_load_lib_failed[] = {'L','o','a','d',' ','L','i','b','r','a','r','y',' ','F','a','i','l','e','d',0};
68 static const WCHAR odbc_error_request_failed[] = {'R','e','q','u','e','s','t',' ','F','a','i','l','e','d',0};
69 static const WCHAR odbc_error_invalid_keyword[] = {'I','n','v','a','l','i','d',' ','k','e','y','w','o','r','d',' ','v','a','l','u','e',0};
70 
71 /* Push an error onto the error stack, taking care of ranges etc. */
72 static void push_error(int code, LPCWSTR msg)
73 {
74  if (num_errors < sizeof error_code/sizeof error_code[0])
75  {
78  num_errors++;
79  }
80 }
81 
82 /* Clear the error stack */
83 static void clear_errors(void)
84 {
85  num_errors = 0;
86 }
87 
88 static inline WCHAR *heap_strdupAtoW(const char *str)
89 {
90  LPWSTR ret = NULL;
91 
92  if(str) {
93  DWORD len;
94 
95  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
96  ret = heap_alloc(len*sizeof(WCHAR));
97  if(ret)
98  MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
99  }
100 
101  return ret;
102 }
103 
104 
106 {
107  clear_errors();
108  FIXME( "( %d %d %p %p) : stub!\n", i, j, p1, p2);
109  return FALSE;
110 }
111 
113 {
114  LPCSTR p;
115  LPWSTR ret = NULL;
116  DWORD len;
117 
118  if (!str)
119  return ret;
120 
121  for (p = str; *p; p += lstrlenA(p) + 1)
122  ;
123 
124  len = MultiByteToWideChar(CP_ACP, 0, str, p - str, NULL, 0 );
125  ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
126  MultiByteToWideChar(CP_ACP, 0, str, p - str, ret, len );
127  ret[len] = 0;
128 
129  return ret;
130 }
131 
133 {
134  DWORD len;
135  LPWSTR ret = NULL;
136 
137  if (!str)
138  return ret;
139 
140  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0 );
141  ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
142  MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len );
143 
144  return ret;
145 }
146 
147 /* Convert the wide string or zero-length-terminated list of wide strings to a
148  * narrow string or zero-length-terminated list of narrow strings.
149  * Do not try to emulate windows undocumented excesses (e.g. adding a third \0
150  * to a list)
151  * Arguments
152  * mode Indicates the sort of string.
153  * 1 denotes that the buffers contain strings terminated by a single nul
154  * character
155  * 2 denotes that the buffers contain zero-length-terminated lists
156  * (frequently erroneously referred to as double-null-terminated)
157  * buffer The narrow-character buffer into which to place the result. This
158  * must be a non-null pointer to the first element of a buffer whose
159  * length is passed in buffer_length.
160  * str The wide-character buffer containing the string or list of strings to
161  * be converted. str_length defines how many wide characters in the
162  * buffer are to be converted, including all desired terminating nul
163  * characters.
164  * str_length Effective length of str
165  * buffer_length Length of buffer
166  * returned_length A pointer to a variable that will receive the number of
167  * narrow characters placed into the buffer. This pointer
168  * may be NULL.
169  */
170 static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
171 {
172  LPSTR pbuf; /* allows us to allocate a temporary buffer only if needed */
173  int len; /* Length of the converted list */
174  BOOL success = FALSE;
175  assert(mode == 1 || mode == 2);
176  assert(buffer_length);
177  len = WideCharToMultiByte(CP_ACP, 0, str, str_length, 0, 0, NULL, NULL);
178  if (len > 0)
179  {
180  if (len > buffer_length)
181  {
182  pbuf = HeapAlloc(GetProcessHeap(), 0, len);
183  }
184  else
185  {
186  pbuf = buffer;
187  }
188  len = WideCharToMultiByte(CP_ACP, 0, str, str_length, pbuf, len, NULL, NULL);
189  if (len > 0)
190  {
191  if (pbuf != buffer)
192  {
193  if (buffer_length > (mode - 1))
194  {
195  memcpy (buffer, pbuf, buffer_length-mode);
196  *(buffer+buffer_length-mode) = '\0';
197  }
198  *(buffer+buffer_length-1) = '\0';
199  }
200  if (returned_length)
201  {
202  *returned_length = pbuf == buffer ? len : buffer_length;
203  }
204  success = TRUE;
205  }
206  else
207  {
208  ERR("transferring wide to narrow\n");
209  }
210  if (pbuf != buffer)
211  {
212  HeapFree(GetProcessHeap(), 0, pbuf);
213  }
214  }
215  else
216  {
217  ERR("measuring wide to narrow\n");
218  }
219  return success;
220 }
221 
223  LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
224 {
225  LPCWSTR p;
226 
227  clear_errors();
228  FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_w(lpszDriver),
229  debugstr_w(lpszAttributes));
230 
231  for (p = lpszAttributes; *p; p += lstrlenW(p) + 1)
232  FIXME("%s\n", debugstr_w(p));
233 
234  return TRUE;
235 }
236 
238  LPCSTR lpszDriver, LPCSTR lpszAttributes)
239 {
240  FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_a(lpszDriver),
241  debugstr_a(lpszAttributes));
242  clear_errors();
243  return TRUE;
244 }
245 
247 {
248  static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
249  long ret;
250  HMODULE hmod;
251  WCHAR *filename = NULL;
252  DWORD size = 0, type;
253  HKEY hkey;
254 
255  if ((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey)) == ERROR_SUCCESS)
256  {
257  HKEY hkeydriver;
258 
259  if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
260  {
261  ret = RegGetValueW(hkeydriver, NULL, reg_driver, RRF_RT_REG_SZ, &type, NULL, &size);
262  if(ret == ERROR_MORE_DATA)
263  {
264  filename = HeapAlloc(GetProcessHeap(), 0, size);
265  if(!filename)
266  {
267  RegCloseKey(hkeydriver);
268  RegCloseKey(hkey);
270 
271  return NULL;
272  }
273  ret = RegGetValueW(hkeydriver, NULL, driver, RRF_RT_REG_SZ, &type, filename, &size);
274  }
275 
276  RegCloseKey(hkeydriver);
277  }
278 
279  RegCloseKey(hkey);
280  }
281 
282  if(ret != ERROR_SUCCESS)
283  {
284  HeapFree(GetProcessHeap(), 0, filename);
286  return NULL;
287  }
288 
289  hmod = LoadLibraryW(filename);
290  HeapFree(GetProcessHeap(), 0, filename);
291 
292  if(!hmod)
294 
295  return hmod;
296 }
297 
299 {
300  long ret;
301  HKEY hkey, hkeydriver;
302  WCHAR *name = NULL;
303 
304  if(!args)
305  return FALSE;
306 
307  if((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey)) == ERROR_SUCCESS)
308  {
309  if((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
310  {
311  WCHAR *divider, *value;
312 
313  name = heap_alloc( (strlenW(args) + 1) * sizeof(WCHAR));
314  if(!name)
315  {
317  goto fail;
318  }
319  lstrcpyW(name, args);
320 
321  divider = strchrW(name,'=');
322  if(!divider)
323  {
325  goto fail;
326  }
327 
328  value = divider + 1;
329  *divider = '\0';
330 
331  TRACE("Write pair: %s = %s\n", debugstr_w(name), debugstr_w(value));
332  if(RegSetValueExW(hkeydriver, name, 0, REG_SZ, (BYTE*)value,
333  (strlenW(value)+1) * sizeof(WCHAR)) != ERROR_SUCCESS)
334  ERR("Failed to write registry installed key\n");
335  heap_free(name);
336 
337  RegCloseKey(hkeydriver);
338  }
339 
340  RegCloseKey(hkey);
341  }
342 
343  if(ret != ERROR_SUCCESS)
345 
346  return ret == ERROR_SUCCESS;
347 
348 fail:
349  RegCloseKey(hkeydriver);
350  RegCloseKey(hkey);
351  heap_free(name);
352 
353  return FALSE;
354 }
355 
357  LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
358 {
359  BOOL (WINAPI *pConfigDriverW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *args, const WCHAR *msg, WORD msgmax, WORD *msgout);
360  HMODULE hmod;
361  BOOL funcret = FALSE;
362 
363  clear_errors();
364  TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_w(driver),
365  debugstr_w(args), msg, msgmax, msgout);
366 
367  if(request == ODBC_CONFIG_DRIVER)
368  {
369  return write_config_value(driver, args);
370  }
371 
372  hmod = load_config_driver(driver);
373  if(!hmod)
374  return FALSE;
375 
376  pConfigDriverW = (void*)GetProcAddress(hmod, "ConfigDriverW");
377  if(pConfigDriverW)
378  funcret = pConfigDriverW(hwnd, request, driver, args, msg, msgmax, msgout);
379 
380  if(!funcret)
382 
383  FreeLibrary(hmod);
384 
385  return funcret;
386 }
387 
389  LPCSTR args, LPSTR msg, WORD msgmax, WORD *msgout)
390 {
391  BOOL (WINAPI *pConfigDriverA)(HWND hwnd, WORD request, const char *driver, const char *args, const char *msg, WORD msgmax, WORD *msgout);
392  HMODULE hmod;
393  WCHAR *driverW;
394  BOOL funcret = FALSE;
395 
396  clear_errors();
397  TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_a(driver),
398  debugstr_a(args), msg, msgmax, msgout);
399 
400  driverW = heap_strdupAtoW(driver);
401  if(!driverW)
402  {
404  return FALSE;
405  }
406  if(request == ODBC_CONFIG_DRIVER)
407  {
408  BOOL ret = FALSE;
409  WCHAR *argsW = heap_strdupAtoW(args);
410  if(argsW)
411  {
412  ret = write_config_value(driverW, argsW);
413  HeapFree(GetProcessHeap(), 0, argsW);
414  }
415  else
416  {
418  }
419 
420  HeapFree(GetProcessHeap(), 0, driverW);
421 
422  return ret;
423  }
424 
425  hmod = load_config_driver(driverW);
426  HeapFree(GetProcessHeap(), 0, driverW);
427  if(!hmod)
428  return FALSE;
429 
430  pConfigDriverA = (void*)GetProcAddress(hmod, "ConfigDriver");
431  if(pConfigDriverA)
432  funcret = pConfigDriverA(hwnd, request, driver, args, msg, msgmax, msgout);
433 
434  if(!funcret)
436 
437  FreeLibrary(hmod);
438 
439  return funcret;
440 }
441 
443 {
444  clear_errors();
445  FIXME("%p %s\n", hwnd, debugstr_w(lpszDS));
447  return FALSE;
448 }
449 
451 {
452  clear_errors();
453  FIXME("%p %s\n", hwnd, debugstr_a(lpszDS));
455  return FALSE;
456 }
457 
459  WORD cbBufMax, WORD *pcbBufOut)
460 {
461  clear_errors();
462  FIXME("%s %p %d %p\n", debugstr_w(lpszInfFile), lpszBuf, cbBufMax, pcbBufOut);
464  return FALSE;
465 }
466 
468  WORD cbBufMax, WORD *pcbBufOut)
469 {
470  clear_errors();
471  FIXME("%s %p %d %p\n", debugstr_a(lpszInfFile), lpszBuf, cbBufMax, pcbBufOut);
473  return FALSE;
474 }
475 
477 {
478  clear_errors();
479  TRACE("%p\n", pwConfigMode);
480  if (pwConfigMode)
481  *pwConfigMode = config_mode;
482  return TRUE;
483 }
484 
486 {
487  WORD written = 0;
488  DWORD index = 0;
489  BOOL ret = TRUE;
490  DWORD valuelen;
491  WCHAR *value;
492  HKEY drivers;
493  DWORD len;
494  LONG res;
495 
496  clear_errors();
497 
498  TRACE("%p %d %p\n", buf, size, sizeout);
499 
500  if (!buf || !size)
501  {
503  return FALSE;
504  }
505 
507  if (res)
508  {
510  return FALSE;
511  }
512 
513  valuelen = 256;
514  value = heap_alloc(valuelen * sizeof(WCHAR));
515 
516  size--;
517 
518  while (1)
519  {
520  len = valuelen;
521  res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL);
522  while (res == ERROR_MORE_DATA)
523  {
524  value = heap_realloc(value, ++len * sizeof(WCHAR));
525  res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL);
526  }
527  if (res == ERROR_SUCCESS)
528  {
529  lstrcpynW(buf + written, value, size - written);
530  written += min(len + 1, size - written);
531  }
532  else if (res == ERROR_NO_MORE_ITEMS)
533  break;
534  else
535  {
537  ret = FALSE;
538  break;
539  }
540  index++;
541  }
542 
543  buf[written++] = 0;
544 
545  heap_free(value);
546  RegCloseKey(drivers);
547  if (sizeout)
548  *sizeout = written;
549  return ret;
550 }
551 
553 {
554  WORD written;
555  WCHAR *wbuf;
556  BOOL ret;
557 
558  TRACE("%p %d %p\n", buf, size, sizeout);
559 
560  if (!buf || !size)
561  {
563  return FALSE;
564  }
565 
566  wbuf = heap_alloc(size * sizeof(WCHAR));
567  if (!wbuf)
568  {
570  return FALSE;
571  }
572 
573  ret = SQLGetInstalledDriversW(wbuf, size, &written);
574  if (!ret)
575  return FALSE;
576 
577  *sizeout = WideCharToMultiByte(CP_ACP, 0, wbuf, written, NULL, 0, NULL, NULL);
578  WideCharToMultiByte(CP_ACP, 0, wbuf, written, buf, size, NULL, NULL);
579 
580  heap_free(wbuf);
581  return TRUE;
582 }
583 
585 {
586  HKEY hkey, hkeyfilename, hkeysection;
587  LONG ret;
588 
589  if (RegOpenKeyW(HKEY_CURRENT_USER, odbcW, &hkey))
590  return NULL;
591 
592  ret = RegOpenKeyW(hkey, filename, &hkeyfilename);
593  RegCloseKey(hkey);
594  if (ret)
595  return NULL;
596 
597  ret = RegOpenKeyW(hkeyfilename, section, &hkeysection);
598  RegCloseKey(hkeyfilename);
599 
600  return ret ? NULL : hkeysection;
601 }
602 
604  LPCWSTR defvalue, LPWSTR buff, int buff_len, LPCWSTR filename)
605 {
606  BOOL usedefault = TRUE;
607  HKEY sectionkey;
608  LONG ret = 0;
609 
610  TRACE("%s %s %s %p %d %s\n", debugstr_w(section), debugstr_w(entry),
611  debugstr_w(defvalue), buff, buff_len, debugstr_w(filename));
612 
613  clear_errors();
614 
615  if (buff_len <= 0 || !section)
616  return 0;
617 
618  if(buff)
619  buff[0] = 0;
620 
621  if (!defvalue || !buff)
622  return 0;
623 
624  sectionkey = get_privateprofile_sectionkey(section, filename);
625  if (sectionkey)
626  {
627  DWORD type, size;
628 
629  if (entry)
630  {
631  size = buff_len * sizeof(*buff);
632  if (RegGetValueW(sectionkey, NULL, entry, RRF_RT_REG_SZ, &type, buff, &size) == ERROR_SUCCESS)
633  {
634  usedefault = FALSE;
635  ret = (size / sizeof(*buff)) - 1;
636  }
637  }
638  else
639  {
641  DWORD index = 0;
642  DWORD namelen;
643 
644  usedefault = FALSE;
645 
646  memset(buff, 0, buff_len);
647 
648  namelen = sizeof(name);
649  while (RegEnumValueW(sectionkey, index, name, &namelen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
650  {
651  if ((ret + namelen+1) > buff_len)
652  break;
653 
654  lstrcpyW(buff+ret, name);
655  ret += namelen+1;
656  namelen = sizeof(name);
657  index++;
658  }
659  }
660 
661  RegCloseKey(sectionkey);
662  }
663  else
664  usedefault = entry != NULL;
665 
666  if (usedefault)
667  {
668  lstrcpynW(buff, defvalue, buff_len);
669  ret = lstrlenW(buff);
670  }
671 
672  return ret;
673 }
674 
676  LPCSTR defvalue, LPSTR buff, int buff_len, LPCSTR filename)
677 {
678  WCHAR *sectionW, *filenameW;
679  BOOL usedefault = TRUE;
680  HKEY sectionkey;
681  LONG ret = 0;
682 
683  TRACE("%s %s %s %p %d %s\n", debugstr_a(section), debugstr_a(entry),
684  debugstr_a(defvalue), buff, buff_len, debugstr_a(filename));
685 
686  clear_errors();
687 
688  if (buff_len <= 0)
689  return 0;
690 
691  if (buff)
692  buff[0] = 0;
693 
694  if (!section || !defvalue || !buff)
695  return 0;
696 
697  sectionW = heap_strdupAtoW(section);
698  filenameW = heap_strdupAtoW(filename);
699 
700  sectionkey = get_privateprofile_sectionkey(sectionW, filenameW);
701 
702  heap_free(sectionW);
703  heap_free(filenameW);
704 
705  if (sectionkey)
706  {
707  DWORD type, size;
708 
709  if (entry)
710  {
711  size = buff_len * sizeof(*buff);
712  if (RegGetValueA(sectionkey, NULL, entry, RRF_RT_REG_SZ, &type, buff, &size) == ERROR_SUCCESS)
713  {
714  usedefault = FALSE;
715  ret = (size / sizeof(*buff)) - 1;
716  }
717  }
718  else
719  {
720  char name[MAX_PATH] = {0};
721  DWORD index = 0;
722  DWORD namelen;
723 
724  usedefault = FALSE;
725 
726  memset(buff, 0, buff_len);
727 
728  namelen = sizeof(name);
729  while (RegEnumValueA(sectionkey, index, name, &namelen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
730  {
731  if ((ret + namelen+1) > buff_len)
732  break;
733 
734  lstrcpyA(buff+ret, name);
735 
736  ret += namelen+1;
737  namelen = sizeof(name);
738  index++;
739  }
740  }
741 
742  RegCloseKey(sectionkey);
743  }
744  else
745  usedefault = entry != NULL;
746 
747  if (usedefault)
748  {
749  lstrcpynA(buff, defvalue, buff_len);
750  ret = strlen(buff);
751  }
752 
753  return ret;
754 }
755 
757  WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax,
758  WORD *pcbPathOut, DWORD *pvOption)
759 {
760  clear_errors();
761  FIXME("%p %s %d %p %p %d %p %p\n", hwndParent, debugstr_w(lpszName), cbNameMax,
762  pcbNameOut, lpszPath, cbPathMax, pcbPathOut, pvOption);
764  return FALSE;
765 }
766 
768  WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax,
769  WORD *pcbPathOut, DWORD *pvOption)
770 {
771  clear_errors();
772  FIXME("%p %s %d %p %p %d %p %p\n", hwndParent, debugstr_a(lpszName), cbNameMax,
773  pcbNameOut, lpszPath, cbPathMax, pcbPathOut, pvOption);
775  return FALSE;
776 }
777 
778 BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver,
779  LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
780 {
781  DWORD usage;
782 
783  clear_errors();
784  TRACE("%s %s %p %d %p\n", debugstr_w(lpszInfFile),
785  debugstr_w(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
786 
787  if (lpszInfFile)
788  return FALSE;
789 
790  return SQLInstallDriverExW(lpszDriver, NULL, lpszPath, cbPathMax,
791  pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
792 }
793 
794 BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver,
795  LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
796 {
797  DWORD usage;
798 
799  clear_errors();
800  TRACE("%s %s %p %d %p\n", debugstr_a(lpszInfFile),
801  debugstr_a(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
802 
803  if (lpszInfFile)
804  return FALSE;
805 
806  return SQLInstallDriverEx(lpszDriver, NULL, lpszPath, cbPathMax,
807  pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
808 }
809 
810 static void write_registry_values(const WCHAR *regkey, const WCHAR *driver, const WCHAR *path_in, WCHAR *path,
811  DWORD *usage_count)
812 {
813  static const WCHAR installed[] = {'I','n','s','t','a','l','l','e','d',0};
814  static const WCHAR slash[] = {'\\', 0};
815  static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
816  static const WCHAR setupW[] = {'S','e','t','u','p',0};
817  static const WCHAR translator[] = {'T','r','a','n','s','l','a','t','o','r',0};
818  HKEY hkey, hkeydriver;
819 
821  {
822  if (RegCreateKeyW(hkey, regkey, &hkeydriver) == ERROR_SUCCESS)
823  {
824  if(RegSetValueExW(hkeydriver, driver, 0, REG_SZ, (BYTE*)installed, sizeof(installed)) != ERROR_SUCCESS)
825  ERR("Failed to write registry installed key\n");
826 
827  RegCloseKey(hkeydriver);
828  }
829 
830  if (RegCreateKeyW(hkey, driver, &hkeydriver) == ERROR_SUCCESS)
831  {
832  WCHAR entry[1024];
833  const WCHAR *p;
834  DWORD usagecount = 0;
835  DWORD type, size;
836 
837  /* Skip name entry */
838  p = driver;
839  p += lstrlenW(p) + 1;
840 
841  if (!path_in)
843  else
844  lstrcpyW(path, path_in);
845 
846  /* Store Usage */
847  size = sizeof(usagecount);
848  RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
849  TRACE("Usage count %d\n", usagecount);
850 
851  for (; *p; p += lstrlenW(p) + 1)
852  {
853  WCHAR *divider = strchrW(p,'=');
854 
855  if (divider)
856  {
857  WCHAR *value;
858  int len;
859 
860  /* Write pair values to the registry. */
861  lstrcpynW(entry, p, divider - p + 1);
862 
863  divider++;
864  TRACE("Writing pair %s,%s\n", debugstr_w(entry), debugstr_w(divider));
865 
866  /* Driver, Setup, Translator entries use the system path unless a path is specified. */
867  if(lstrcmpiW(driverW, entry) == 0 || lstrcmpiW(setupW, entry) == 0 ||
868  lstrcmpiW(translator, entry) == 0)
869  {
870  len = lstrlenW(path) + lstrlenW(slash) + lstrlenW(divider) + 1;
871  value = heap_alloc(len * sizeof(WCHAR));
872  if(!value)
873  {
874  ERR("Out of memory\n");
875  return;
876  }
877 
878  lstrcpyW(value, path);
879  lstrcatW(value, slash);
880  lstrcatW(value, divider);
881  }
882  else
883  {
884  len = lstrlenW(divider) + 1;
885  value = heap_alloc(len * sizeof(WCHAR));
886  lstrcpyW(value, divider);
887  }
888 
889  if (RegSetValueExW(hkeydriver, entry, 0, REG_SZ, (BYTE*)value,
890  (lstrlenW(value)+1)*sizeof(WCHAR)) != ERROR_SUCCESS)
891  ERR("Failed to write registry data %s %s\n", debugstr_w(entry), debugstr_w(value));
892  heap_free(value);
893  }
894  else
895  {
896  ERR("No pair found. %s\n", debugstr_w(p));
897  break;
898  }
899  }
900 
901  /* Set Usage Count */
902  usagecount++;
903  if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&usagecount, sizeof(usagecount)) != ERROR_SUCCESS)
904  ERR("Failed to write registry UsageCount key\n");
905 
906  if (usage_count)
907  *usage_count = usagecount;
908 
909  RegCloseKey(hkeydriver);
910  }
911 
912  RegCloseKey(hkey);
913  }
914 }
915 
917  LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
918  WORD fRequest, LPDWORD lpdwUsageCount)
919 {
920  UINT len;
922 
923  clear_errors();
924  TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszDriver),
925  debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
926  fRequest, lpdwUsageCount);
927 
928  write_registry_values(odbcdrivers, lpszDriver, lpszPathIn, path, lpdwUsageCount);
929 
930  len = lstrlenW(path);
931 
932  if (pcbPathOut)
933  *pcbPathOut = len;
934 
935  if (lpszPathOut && cbPathOutMax > len)
936  {
937  lstrcpyW(lpszPathOut, path);
938  return TRUE;
939  }
940  return FALSE;
941 }
942 
943 BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn,
944  LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
945  WORD fRequest, LPDWORD lpdwUsageCount)
946 {
947  LPWSTR driver, pathin;
948  WCHAR pathout[MAX_PATH];
949  BOOL ret;
950  WORD cbOut = 0;
951 
952  clear_errors();
953  TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszDriver),
954  debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
955  fRequest, lpdwUsageCount);
956 
957  driver = SQLInstall_strdup_multi(lpszDriver);
958  pathin = SQLInstall_strdup(lpszPathIn);
959 
960  ret = SQLInstallDriverExW(driver, pathin, pathout, MAX_PATH, &cbOut,
961  fRequest, lpdwUsageCount);
962  if (ret)
963  {
964  int len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
965  0, NULL, NULL);
966  if (len)
967  {
968  if (pcbPathOut)
969  *pcbPathOut = len - 1;
970 
971  if (!lpszPathOut || cbPathOutMax < len)
972  {
973  ret = FALSE;
974  goto out;
975  }
976  len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
977  cbPathOutMax, NULL, NULL);
978  }
979  }
980 
981 out:
982  HeapFree(GetProcessHeap(), 0, driver);
983  HeapFree(GetProcessHeap(), 0, pathin);
984  return ret;
985 }
986 
988  WORD *pcbPathOut)
989 {
990  UINT len;
992 
993  TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
994 
995  if (cbPathMax < MAX_PATH)
996  return FALSE;
997 
998  clear_errors();
999 
1000  len = GetSystemDirectoryW(path, MAX_PATH);
1001 
1002  if (pcbPathOut)
1003  *pcbPathOut = len;
1004 
1005  if (lpszPath && cbPathMax > len)
1006  {
1007  lstrcpyW(lpszPath, path);
1008  return TRUE;
1009  }
1010  return FALSE;
1011 }
1012 
1014  WORD *pcbPathOut)
1015 {
1016  BOOL ret;
1017  WORD len, cbOut = 0;
1018  WCHAR path[MAX_PATH];
1019 
1020  TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
1021 
1022  if (cbPathMax < MAX_PATH)
1023  return FALSE;
1024 
1025  clear_errors();
1026 
1027  ret = SQLInstallDriverManagerW(path, MAX_PATH, &cbOut);
1028  if (ret)
1029  {
1030  len = WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath, 0,
1031  NULL, NULL);
1032  if (len)
1033  {
1034  if (pcbPathOut)
1035  *pcbPathOut = len - 1;
1036 
1037  if (!lpszPath || cbPathMax < len)
1038  return FALSE;
1039 
1040  len = WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath,
1041  cbPathMax, NULL, NULL);
1042  }
1043  }
1044  return ret;
1045 }
1046 
1048  LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
1049 {
1050  clear_errors();
1051  FIXME("%p %s %s %s\n", hwndParent, debugstr_w(lpszInfFile),
1052  debugstr_w(lpszSrcPath), debugstr_w(lpszDrivers));
1054  return FALSE;
1055 }
1056 
1058  LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
1059 {
1060  clear_errors();
1061  FIXME("%p %s %s %s\n", hwndParent, debugstr_a(lpszInfFile),
1062  debugstr_a(lpszSrcPath), debugstr_a(lpszDrivers));
1064  return FALSE;
1065 }
1066 
1068  LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
1069 {
1070  TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
1071  cbErrorMsgMax, pcbErrorMsg);
1072 
1073  if (iError == 0)
1074  {
1075  return SQL_ERROR;
1076  }
1077  else if (iError <= num_errors)
1078  {
1079  BOOL truncated = FALSE;
1080  WORD len;
1081  LPCWSTR msg;
1082  iError--;
1083  if (pfErrorCode)
1084  *pfErrorCode = error_code[iError];
1085  msg = error_msg[iError];
1086  len = msg ? lstrlenW(msg) : 0;
1087  if (pcbErrorMsg)
1088  *pcbErrorMsg = len;
1089  len++;
1090  if (cbErrorMsgMax < len)
1091  {
1092  len = cbErrorMsgMax;
1093  truncated = TRUE;
1094  }
1095  if (lpszErrorMsg && len)
1096  {
1097  if (msg)
1098  {
1099  memcpy (lpszErrorMsg, msg, len * sizeof(WCHAR));
1100  }
1101  else
1102  {
1103  assert(len==1);
1104  *lpszErrorMsg = 0;
1105  }
1106  }
1107  else
1108  {
1109  /* Yes. If you pass a null pointer and a large length it is not an error! */
1110  truncated = TRUE;
1111  }
1112 
1113  return truncated ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
1114  }
1115 
1116  /* At least on Windows 2000 , the buffers are not altered in this case. However that is a little too dangerous a test for just now */
1117  if (pcbErrorMsg)
1118  *pcbErrorMsg = 0;
1119 
1120  if (lpszErrorMsg && cbErrorMsgMax > 0)
1121  *lpszErrorMsg = '\0';
1122 
1123  return SQL_NO_DATA;
1124 }
1125 
1127  LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
1128 {
1129  SQLRETURN ret;
1130  LPWSTR wbuf;
1131  WORD cbwbuf;
1132  TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
1133  cbErrorMsgMax, pcbErrorMsg);
1134 
1135  wbuf = 0;
1136  if (lpszErrorMsg && cbErrorMsgMax)
1137  {
1138  wbuf = HeapAlloc(GetProcessHeap(), 0, cbErrorMsgMax*sizeof(WCHAR));
1139  if (!wbuf)
1140  return SQL_ERROR;
1141  }
1142  ret = SQLInstallerErrorW(iError, pfErrorCode, wbuf, cbErrorMsgMax, &cbwbuf);
1143  if (wbuf)
1144  {
1145  WORD cbBuf = 0;
1146  SQLInstall_narrow(1, lpszErrorMsg, wbuf, cbwbuf+1, cbErrorMsgMax, &cbBuf);
1147  HeapFree(GetProcessHeap(), 0, wbuf);
1148  if (pcbErrorMsg)
1149  *pcbErrorMsg = cbBuf-1;
1150  }
1151  return ret;
1152 }
1153 
1155  LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
1156  WORD fRequest, LPDWORD lpdwUsageCount)
1157 {
1158  UINT len;
1159  WCHAR path[MAX_PATH];
1160 
1161  clear_errors();
1162  TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszTranslator),
1163  debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
1164  fRequest, lpdwUsageCount);
1165 
1166  write_registry_values(odbctranslators, lpszTranslator, lpszPathIn, path, lpdwUsageCount);
1167 
1168  len = lstrlenW(path);
1169 
1170  if (pcbPathOut)
1171  *pcbPathOut = len;
1172 
1173  if (lpszPathOut && cbPathOutMax > len)
1174  {
1175  lstrcpyW(lpszPathOut, path);
1176  return TRUE;
1177  }
1178  return FALSE;
1179 }
1180 
1181 BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn,
1182  LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
1183  WORD fRequest, LPDWORD lpdwUsageCount)
1184 {
1185  LPCSTR p;
1186  LPWSTR translator, pathin;
1187  WCHAR pathout[MAX_PATH];
1188  BOOL ret;
1189  WORD cbOut = 0;
1190 
1191  clear_errors();
1192  TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszTranslator),
1193  debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
1194  fRequest, lpdwUsageCount);
1195 
1196  for (p = lpszTranslator; *p; p += lstrlenA(p) + 1)
1197  TRACE("%s\n", debugstr_a(p));
1198 
1199  translator = SQLInstall_strdup_multi(lpszTranslator);
1200  pathin = SQLInstall_strdup(lpszPathIn);
1201 
1202  ret = SQLInstallTranslatorExW(translator, pathin, pathout, MAX_PATH,
1203  &cbOut, fRequest, lpdwUsageCount);
1204  if (ret)
1205  {
1206  int len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
1207  0, NULL, NULL);
1208  if (len)
1209  {
1210  if (pcbPathOut)
1211  *pcbPathOut = len - 1;
1212 
1213  if (!lpszPathOut || cbPathOutMax < len)
1214  {
1215  ret = FALSE;
1216  goto out;
1217  }
1218  len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
1219  cbPathOutMax, NULL, NULL);
1220  }
1221  }
1222 
1223 out:
1224  HeapFree(GetProcessHeap(), 0, translator);
1225  HeapFree(GetProcessHeap(), 0, pathin);
1226  return ret;
1227 }
1228 
1229 BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator,
1230  LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax,
1231  WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
1232 {
1233  clear_errors();
1234  TRACE("%s %s %s %p %d %p %d %p\n", debugstr_a(lpszInfFile),
1235  debugstr_a(lpszTranslator), debugstr_a(lpszPathIn), lpszPathOut,
1236  cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1237 
1238  if (lpszInfFile)
1239  return FALSE;
1240 
1241  return SQLInstallTranslatorEx(lpszTranslator, lpszPathIn, lpszPathOut,
1242  cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1243 }
1244 
1245 BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator,
1246  LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax,
1247  WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
1248 {
1249  clear_errors();
1250  TRACE("%s %s %s %p %d %p %d %p\n", debugstr_w(lpszInfFile),
1251  debugstr_w(lpszTranslator), debugstr_w(lpszPathIn), lpszPathOut,
1252  cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1253 
1254  if (lpszInfFile)
1255  return FALSE;
1256 
1257  return SQLInstallTranslatorExW(lpszTranslator, lpszPathIn, lpszPathOut,
1258  cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1259 }
1260 
1262 {
1263  clear_errors();
1264  FIXME("%p\n", hwnd);
1266  return FALSE;
1267 }
1268 
1270 {
1271  FIXME("%u %s\n", fErrorCode, debugstr_w(szErrorMsg));
1273  return FALSE;
1274 }
1275 
1277 {
1278  FIXME("%u %s\n", fErrorCode, debugstr_a(szErrorMsg));
1280  return FALSE;
1281 }
1282 
1283 BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
1284  LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString,
1285  WORD *pcbString)
1286 {
1287  clear_errors();
1288  FIXME("%s %s %s %s %d %p\n", debugstr_w(lpszFileName), debugstr_w(lpszAppName),
1289  debugstr_w(lpszKeyName), debugstr_w(lpszString), cbString, pcbString);
1291  return FALSE;
1292 }
1293 
1294 BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
1295  LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString,
1296  WORD *pcbString)
1297 {
1298  clear_errors();
1299  FIXME("%s %s %s %s %d %p\n", debugstr_a(lpszFileName), debugstr_a(lpszAppName),
1300  debugstr_a(lpszKeyName), debugstr_a(lpszString), cbString, pcbString);
1302  return FALSE;
1303 }
1304 
1306 {
1307  clear_errors();
1308  FIXME("\n");
1310  return FALSE;
1311 }
1312 
1313 BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
1314 {
1315  HKEY hkey;
1316  DWORD usagecount = 1;
1317 
1318  clear_errors();
1319  TRACE("%s %d %p\n", debugstr_w(drivername), remove_dsn, usage_count);
1320 
1322  {
1323  HKEY hkeydriver;
1324 
1325  if (RegOpenKeyW(hkey, drivername, &hkeydriver) == ERROR_SUCCESS)
1326  {
1327  DWORD size, type;
1328  DWORD count;
1329 
1330  size = sizeof(usagecount);
1331  RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
1332  TRACE("Usage count %d\n", usagecount);
1333  count = usagecount - 1;
1334  if (count)
1335  {
1336  if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&count, sizeof(count)) != ERROR_SUCCESS)
1337  ERR("Failed to write registry UsageCount key\n");
1338  }
1339 
1340  RegCloseKey(hkeydriver);
1341  }
1342 
1343  if (usagecount)
1344  usagecount--;
1345 
1346  if (!usagecount)
1347  {
1348  if (RegDeleteKeyW(hkey, drivername) != ERROR_SUCCESS)
1349  ERR("Failed to delete registry key: %s\n", debugstr_w(drivername));
1350 
1351  if (RegOpenKeyW(hkey, odbcdrivers, &hkeydriver) == ERROR_SUCCESS)
1352  {
1353  if(RegDeleteValueW(hkeydriver, drivername) != ERROR_SUCCESS)
1354  ERR("Failed to delete registry value: %s\n", debugstr_w(drivername));
1355  RegCloseKey(hkeydriver);
1356  }
1357  }
1358 
1359  RegCloseKey(hkey);
1360  }
1361 
1362  if (usage_count)
1363  *usage_count = usagecount;
1364 
1365  return TRUE;
1366 }
1367 
1368 BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN,
1369  LPDWORD lpdwUsageCount)
1370 {
1371  WCHAR *driver;
1372  BOOL ret;
1373 
1374  clear_errors();
1375  TRACE("%s %d %p\n", debugstr_a(lpszDriver), fRemoveDSN, lpdwUsageCount);
1376 
1377  driver = SQLInstall_strdup(lpszDriver);
1378 
1379  ret = SQLRemoveDriverW(driver, fRemoveDSN, lpdwUsageCount);
1380 
1381  HeapFree(GetProcessHeap(), 0, driver);
1382  return ret;
1383 }
1384 
1386 {
1387  clear_errors();
1388  FIXME("%p\n", pdwUsageCount);
1389  if (pdwUsageCount) *pdwUsageCount = 1;
1390  return TRUE;
1391 }
1392 
1394 {
1395  clear_errors();
1396  FIXME("%s\n", debugstr_w(lpszDSN));
1398  return FALSE;
1399 }
1400 
1402 {
1403  clear_errors();
1404  FIXME("%s\n", debugstr_a(lpszDSN));
1406  return FALSE;
1407 }
1408 
1409 BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
1410 {
1411  HKEY hkey;
1412  DWORD usagecount = 1;
1413  BOOL ret = TRUE;
1414 
1415  clear_errors();
1416  TRACE("%s %p\n", debugstr_w(translator), usage_count);
1417 
1419  {
1420  HKEY hkeydriver;
1421 
1422  if (RegOpenKeyW(hkey, translator, &hkeydriver) == ERROR_SUCCESS)
1423  {
1424  DWORD size, type;
1425  DWORD count;
1426 
1427  size = sizeof(usagecount);
1428  RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
1429  TRACE("Usage count %d\n", usagecount);
1430  count = usagecount - 1;
1431  if (count)
1432  {
1433  if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&count, sizeof(count)) != ERROR_SUCCESS)
1434  ERR("Failed to write registry UsageCount key\n");
1435  }
1436 
1437  RegCloseKey(hkeydriver);
1438  }
1439 
1440  if (usagecount)
1441  usagecount--;
1442 
1443  if (!usagecount)
1444  {
1445  if(RegDeleteKeyW(hkey, translator) != ERROR_SUCCESS)
1446  {
1448  WARN("Failed to delete registry key: %s\n", debugstr_w(translator));
1449  ret = FALSE;
1450  }
1451 
1452  if (ret && RegOpenKeyW(hkey, odbctranslators, &hkeydriver) == ERROR_SUCCESS)
1453  {
1454  if(RegDeleteValueW(hkeydriver, translator) != ERROR_SUCCESS)
1455  {
1457  WARN("Failed to delete registry key: %s\n", debugstr_w(translator));
1458  ret = FALSE;
1459  }
1460 
1461  RegCloseKey(hkeydriver);
1462  }
1463  }
1464 
1465  RegCloseKey(hkey);
1466  }
1467 
1468  if (ret && usage_count)
1469  *usage_count = usagecount;
1470 
1471  return ret;
1472 }
1473 
1474 BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
1475 {
1476  WCHAR *translator;
1477  BOOL ret;
1478 
1479  clear_errors();
1480  TRACE("%s %p\n", debugstr_a(lpszTranslator), lpdwUsageCount);
1481 
1482  translator = SQLInstall_strdup(lpszTranslator);
1483  ret = SQLRemoveTranslatorW(translator, lpdwUsageCount);
1484 
1485  HeapFree(GetProcessHeap(), 0, translator);
1486  return ret;
1487 }
1488 
1490 {
1491  clear_errors();
1492  TRACE("%u\n", wConfigMode);
1493 
1494  if (wConfigMode > ODBC_SYSTEM_DSN)
1495  {
1497  return FALSE;
1498  }
1499  else
1500  {
1501  config_mode = wConfigMode;
1502  return TRUE;
1503  }
1504 }
1505 
1507 {
1508  clear_errors();
1509  FIXME("%s\n", debugstr_w(lpszDSN));
1511  return FALSE;
1512 }
1513 
1515 {
1516  clear_errors();
1517  FIXME("%s\n", debugstr_a(lpszDSN));
1519  return FALSE;
1520 }
1521 
1523 {
1524  clear_errors();
1525  FIXME("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
1527  return FALSE;
1528 }
1529 
1531 {
1532  clear_errors();
1533  FIXME("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
1535  return FALSE;
1536 }
1537 
1538 BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
1539  LPCWSTR lpszKeyName, LPCWSTR lpszString)
1540 {
1541  clear_errors();
1542  FIXME("%s %s %s %s\n", debugstr_w(lpszFileName), debugstr_w(lpszAppName),
1543  debugstr_w(lpszKeyName), debugstr_w(lpszString));
1545  return FALSE;
1546 }
1547 
1548 BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
1549  LPCSTR lpszKeyName, LPCSTR lpszString)
1550 {
1551  clear_errors();
1552  FIXME("%s %s %s %s\n", debugstr_a(lpszFileName), debugstr_a(lpszAppName),
1553  debugstr_a(lpszKeyName), debugstr_a(lpszString));
1555  return FALSE;
1556 }
1557 
1559  LPCWSTR lpszString, LPCWSTR lpszFilename)
1560 {
1561  LONG ret;
1562  HKEY hkey;
1563 
1564  clear_errors();
1565  TRACE("%s %s %s %s\n", debugstr_w(lpszSection), debugstr_w(lpszEntry),
1566  debugstr_w(lpszString), debugstr_w(lpszFilename));
1567 
1568  if(!lpszFilename || !*lpszFilename)
1569  {
1571  return FALSE;
1572  }
1573 
1574  if ((ret = RegCreateKeyW(HKEY_CURRENT_USER, odbcW, &hkey)) == ERROR_SUCCESS)
1575  {
1576  HKEY hkeyfilename;
1577 
1578  if ((ret = RegCreateKeyW(hkey, lpszFilename, &hkeyfilename)) == ERROR_SUCCESS)
1579  {
1580  HKEY hkey_section;
1581 
1582  if ((ret = RegCreateKeyW(hkeyfilename, lpszSection, &hkey_section)) == ERROR_SUCCESS)
1583  {
1584  ret = RegSetValueExW(hkey_section, lpszEntry, 0, REG_SZ, (BYTE*)lpszString, (lstrlenW(lpszString)+1)*sizeof(WCHAR));
1585  RegCloseKey(hkey_section);
1586  }
1587 
1588  RegCloseKey(hkeyfilename);
1589  }
1590 
1591  RegCloseKey(hkey);
1592  }
1593 
1594  return ret == ERROR_SUCCESS;
1595 }
1596 
1598  LPCSTR lpszString, LPCSTR lpszFilename)
1599 {
1600  BOOL ret;
1601  WCHAR *sect, *entry, *string, *file;
1602  clear_errors();
1603  TRACE("%s %s %s %s\n", lpszSection, lpszEntry, lpszString, lpszFilename);
1604 
1605  sect = heap_strdupAtoW(lpszSection);
1606  entry = heap_strdupAtoW(lpszEntry);
1607  string = heap_strdupAtoW(lpszString);
1608  file = heap_strdupAtoW(lpszFilename);
1609 
1610  ret = SQLWritePrivateProfileStringW(sect, entry, string, file);
1611 
1612  heap_free(sect);
1613  heap_free(entry);
1614  heap_free(string);
1615  heap_free(file);
1616 
1617  return ret;
1618 }
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1975
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static UWORD config_mode
Definition: odbccp32.c:51
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:38
BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPCWSTR lpszString)
Definition: odbccp32.c:1538
#define ODBC_INSTALL_COMPLETE
Definition: odbcinst.h:20
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
unsigned short WORD
Definition: ntddk_ex.h:93
#define TRUE
Definition: types.h:120
static const WCHAR odbc_error_general_err[]
Definition: odbccp32.c:60
BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes)
Definition: odbccp32.c:237
BOOL WINAPI SQLInstallDriverManagerW(LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:987
BOOL WINAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile, LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
Definition: odbccp32.c:1057
BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1181
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static const WCHAR * error_msg[8]
Definition: odbccp32.c:59
BOOL WINAPI SQLInstallODBCW(HWND hwndParent, LPCWSTR lpszInfFile, LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
Definition: odbccp32.c:1047
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI SQLCreateDataSource(HWND hwnd, LPCSTR lpszDS)
Definition: odbccp32.c:450
#define WideCharToMultiByte
Definition: compat.h:101
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
BOOL WINAPI SQLRemoveDefaultDataSource(void)
Definition: odbccp32.c:1305
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ODBC_ERROR_LOAD_LIB_FAILED
Definition: odbcinst.h:43
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR odbc_error_invalid_param_sequence[]
Definition: odbccp32.c:64
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
static BOOL write_config_value(const WCHAR *driver, const WCHAR *args)
Definition: odbccp32.c:298
#define CP_ACP
Definition: compat.h:99
static void write_registry_values(const WCHAR *regkey, const WCHAR *driver, const WCHAR *path_in, WCHAR *path, DWORD *usage_count)
Definition: odbccp32.c:810
BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszString, LPCSTR lpszFilename)
Definition: odbccp32.c:1597
#define HKEY_CURRENT_USER
Definition: winreg.h:11
BOOL WINAPI SQLManageDataSources(HWND hwnd)
Definition: odbccp32.c:1261
static WCHAR * heap_strdupAtoW(const char *str)
Definition: odbccp32.c:88
uint8_t entry
Definition: isohybrid.c:63
#define WARN(fmt,...)
Definition: debug.h:111
#define SQL_NO_DATA
Definition: sql.h:315
SQLRETURN WINAPI SQLPostInstallerError(DWORD fErrorCode, LPCSTR szErrorMsg)
Definition: odbccp32.c:1276
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1240
BOOL WINAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
Definition: odbccp32.c:1393
BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1154
HANDLE HWND
Definition: compat.h:13
static void clear_errors(void)
Definition: odbccp32.c:83
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define RRF_RT_REG_SZ
Definition: driver.c:575
#define assert(x)
Definition: debug.h:53
BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPCSTR lpszString)
Definition: odbccp32.c:1548
GLuint buffer
Definition: glext.h:5915
BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:794
static void push_error(int code, LPCWSTR msg)
Definition: odbccp32.c:72
BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString, WORD *pcbString)
Definition: odbccp32.c:1294
Definition: parser.c:55
char * LPSTR
Definition: xmlstorage.h:182
const char * filename
Definition: ioapi.h:135
int WINAPI SQLGetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR defvalue, LPWSTR buff, int buff_len, LPCWSTR filename)
Definition: odbccp32.c:603
#define lstrlenW
Definition: compat.h:407
GLint namelen
Definition: glext.h:7232
Definition: match.c:390
static LPWSTR SQLInstall_strdup(LPCSTR str)
Definition: odbccp32.c:132
#define SQL_SUCCESS_WITH_INFO
Definition: sql.h:164
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
DWORD DWORD
Definition: winlogon.h:84
#define SQL_SUCCESS
Definition: sql.h:163
BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
Definition: odbccp32.c:1522
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
BOOL WINAPI SQLGetInstalledDriversW(WCHAR *buf, WORD size, WORD *sizeout)
Definition: odbccp32.c:485
#define lstrcpynW
Definition: compat.h:397
BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1229
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static const WCHAR odbc_error_invalid_buff_len[]
Definition: odbccp32.c:61
const GLfloat * p2
Definition: s_aatritemp.h:44
static const WCHAR filenameW[]
Definition: amstream.c:41
GLuint const GLchar * name
Definition: glext.h:6031
#define ODBC_ERROR_GENERAL_ERR
Definition: odbcinst.h:31
GLenum GLclampf GLint i
Definition: glfuncs.h:14
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
Definition: odbccp32.c:222
BOOL WINAPI SQLGetAvailableDriversW(LPCWSTR lpszInfFile, LPWSTR lpszBuf, WORD cbBufMax, WORD *pcbBufOut)
Definition: odbccp32.c:458
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
static const WCHAR odbcini[]
Definition: odbccp32.c:43
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
#define debugstr_w
Definition: kernel32.h:32
#define ODBC_ERROR_COMPONENT_NOT_FOUND
Definition: odbcinst.h:36
#define FIXME(fmt,...)
Definition: debug.h:110
#define ODBC_ERROR_INVALID_KEYWORD_VALUE
Definition: odbcinst.h:38
SQLRETURN WINAPI SQLPostInstallerErrorW(DWORD fErrorCode, LPCWSTR szErrorMsg)
Definition: odbccp32.c:1269
static int num_errors
Definition: odbccp32.c:57
static const WCHAR odbc_error_component_not_found[]
Definition: odbccp32.c:62
static int error_code[8]
Definition: odbccp32.c:58
BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
Definition: odbccp32.c:1530
const WCHAR * str
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2867
#define SQL_ERROR
Definition: sql.h:68
#define LoadLibraryW(x)
Definition: compat.h:404
smooth NULL
Definition: ftsmooth.c:416
static HWND hwndParent
Definition: cryptui.c:300
#define ODBC_ERROR_REQUEST_FAILED
Definition: odbcinst.h:41
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
static const WCHAR odbc_error_invalid_param_string[]
Definition: odbccp32.c:65
BOOL WINAPI SQLGetTranslatorW(HWND hwndParent, LPWSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption)
Definition: odbccp32.c:756
LSTATUS WINAPI RegGetValueA(HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:2081
#define RRF_RT_DWORD
Definition: driver.c:581
static const WCHAR odbc_error_out_of_mem[]
Definition: odbccp32.c:63
#define ODBC_CONFIG_DRIVER
Definition: odbcinst.h:23
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4917
SQLRETURN WINAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode, LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
Definition: odbccp32.c:1126
SQLRETURN WINAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode, LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
Definition: odbccp32.c:1067
BOOL WINAPI ODBCCPlApplet(LONG i, LONG j, LONG *p1, LONG *p2)
Definition: odbccp32.c:105
BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
Definition: odbccp32.c:1514
#define ODBC_BOTH_DSN
Definition: odbcinst.h:28
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
#define ODBC_SYSTEM_DSN
Definition: odbcinst.h:30
LONG WINAPI RegEnumValueA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpdwReserved, _Out_opt_ LPDWORD lpdwType, _Out_opt_ LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData)
Definition: reg.c:2705
static const WCHAR odbc_error_request_failed[]
Definition: odbccp32.c:68
#define GetProcessHeap()
Definition: compat.h:395
BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:778
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
Definition: odbccp32.c:356
Definition: pbuf.h:79
#define debugstr_a
Definition: kernel32.h:31
HANDLE HKEY
Definition: registry.h:24
BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1368
BOOL WINAPI SQLConfigDriver(HWND hwnd, WORD request, LPCSTR driver, LPCSTR args, LPSTR msg, WORD msgmax, WORD *msgout)
Definition: odbccp32.c:388
BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
Definition: odbccp32.c:476
#define MAX_PATH
Definition: compat.h:26
const char file[]
Definition: icontest.c:11
static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename)
Definition: odbccp32.c:584
BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf, WORD cbBufMax, WORD *pcbBufOut)
Definition: odbccp32.c:467
static FILE * out
Definition: regtests2xml.c:44
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define success(from, fromstr, to, tostr)
#define SetLastError(x)
Definition: compat.h:409
#define ODBC_ERROR_OUT_OF_MEM
Definition: odbcinst.h:51
static const WCHAR drivers_key[]
Definition: odbccp32.c:41
BOOL WINAPI SQLInstallDriverManager(LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:1013
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
Definition: odbccp32.c:442
static HMODULE load_config_driver(const WCHAR *driver)
Definition: odbccp32.c:246
BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString, WORD *pcbString)
Definition: odbccp32.c:1283
#define ODBC_ERROR_INVALID_DSN
Definition: odbcinst.h:39
#define ODBC_ERROR_INVALID_STR
Definition: odbcinst.h:34
BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode)
Definition: odbccp32.c:1489
int ret
unsigned short UWORD
Definition: lzx.c:49
BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:943
#define ODBC_ERROR_INVALID_PARAM_SEQUENCE
Definition: odbcinst.h:44
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int WINAPI SQLGetPrivateProfileString(LPCSTR section, LPCSTR entry, LPCSTR defvalue, LPSTR buff, int buff_len, LPCSTR filename)
Definition: odbccp32.c:675
struct @1598::@1599 driver
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1202
GLenum GLsizei len
Definition: glext.h:6722
static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
Definition: odbccp32.c:170
GLenum mode
Definition: glext.h:6217
int code
Definition: i386-dis.c:3591
#define ERROR_MORE_DATA
Definition: dderror.h:13
BOOL WINAPI SQLRemoveDriverManager(LPDWORD pdwUsageCount)
Definition: odbccp32.c:1385
GLsizei const GLfloat * value
Definition: glext.h:6069
#define WINAPI
Definition: msvc.h:20
unsigned char BYTE
Definition: ntddk_ex.h:96
char string[160]
Definition: util.h:11
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
#define ERR(fmt,...)
Definition: debug.h:109
BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout)
Definition: odbccp32.c:552
WINE_DEFAULT_DEBUG_CHANNEL(odbc)
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define lstrcpyW
Definition: compat.h:406
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
Definition: odbccp32.c:1313
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BOOL WINAPI SQLRemoveDSNFromIni(LPCSTR lpszDSN)
Definition: odbccp32.c:1401
BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1245
Definition: services.c:325
BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1474
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
BOOL WINAPI SQLGetTranslator(HWND hwndParent, LPSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption)
Definition: odbccp32.c:767
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define lstrcpynA
Definition: compat.h:408
static const WCHAR odbc_error_invalid_dsn[]
Definition: odbccp32.c:66
static const WCHAR odbcdrivers[]
Definition: odbccp32.c:44
#define MultiByteToWideChar
Definition: compat.h:100
Definition: tftpd.h:85
HANDLE HMODULE
Definition: typedefs.h:75
BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
Definition: odbccp32.c:1409
static const WCHAR odbc_error_load_lib_failed[]
Definition: odbccp32.c:67
#define msg(x)
Definition: auth_time.c:54
Definition: name.c:36
static const WCHAR odbc_error_invalid_keyword[]
Definition: odbccp32.c:69
GLuint res
Definition: glext.h:9613
uint32_t * LPDWORD
Definition: typedefs.h:57
UINT msg
Definition: msvc.h:92
BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszString, LPCWSTR lpszFilename)
Definition: odbccp32.c:1558
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define GetProcAddress(x, y)
Definition: compat.h:410
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4831
GLfloat GLfloat p
Definition: glext.h:8902
const GLfloat * p1
Definition: s_aatritemp.h:43
#define ODBC_ERROR_INVALID_BUFF_LEN
Definition: odbcinst.h:32
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:539
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define args
Definition: format.c:66
BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN)
Definition: odbccp32.c:1506
static const WCHAR odbctranslators[]
Definition: odbccp32.c:45
#define BOOL
Definition: msvc.h:23
static unsigned char buff[32768]
Definition: fatten.c:17
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:916
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static LPWSTR SQLInstall_strdup_multi(LPCSTR str)
Definition: odbccp32.c:112
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22
static const WCHAR odbcW[]
Definition: odbccp32.c:42