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