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