ReactOS 0.4.15-dev-8236-g99f0937
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 */
44static 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};
45static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C',0};
46static 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};
47static const WCHAR odbcdrivers[] = {'O','D','B','C',' ','D','r','i','v','e','r','s',0};
48static 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 */
60static int num_errors;
61static int error_code[8];
62static const WCHAR *error_msg[8];
63static const WCHAR odbc_error_general_err[] = {'G','e','n','e','r','a','l',' ','e','r','r','o','r',0};
64static 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};
65static 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};
66static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0};
67static 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};
68static 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};
69static const WCHAR odbc_error_invalid_dsn[] = {'I','n','v','a','l','i','d',' ','D','S','N',0};
70static 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};
71static const WCHAR odbc_error_request_failed[] = {'R','e','q','u','e','s','t',' ','F','a','i','l','e','d',0};
72static 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. */
75static void push_error(int code, LPCWSTR msg)
76{
78 {
81 num_errors++;
82 }
83}
84
85/* Clear the error stack */
86static void clear_errors(void)
87{
88 num_errors = 0;
89}
90
91static 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)
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));
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 */
173static 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 */
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 {
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;
255 DWORD size = 0, type;
256 HKEY hkey;
257
259 {
260 HKEY hkeydriver;
261
262 if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
263 {
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 }
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");
345
346 RegCloseKey(hkeydriver);
347 }
348
349 RegCloseKey(hkey);
350 }
351
352 if(ret != ERROR_SUCCESS)
354
355 return ret == ERROR_SUCCESS;
356
357fail:
358 RegCloseKey(hkeydriver);
359 RegCloseKey(hkey);
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);
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 {
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
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);
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
410 if(!driverW)
411 {
413 return FALSE;
414 }
416 {
417 BOOL ret = FALSE;
418 WCHAR *argsW = heap_strdupAtoW(args);
419 if(argsW)
420 {
422 HeapFree(GetProcessHeap(), 0, argsW);
423 }
424 else
425 {
427 }
428
430
431 return ret;
432 }
433
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
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
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
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;
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
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;
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
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
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
806BOOL 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
822static 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
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));
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
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
993out:
995 HeapFree(GetProcessHeap(), 0, pathin);
996 return ret;
997}
998
1000 WORD *pcbPathOut)
1001{
1002 UINT len;
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;
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;
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
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
1235out:
1236 HeapFree(GetProcessHeap(), 0, translator);
1237 HeapFree(GetProcessHeap(), 0, pathin);
1238 return ret;
1239}
1240
1241BOOL 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
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
1295BOOL 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
1306BOOL 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
1325BOOL 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
1380BOOL 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
1421BOOL 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
1486BOOL 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
1560BOOL 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
1570BOOL 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);
1640 heap_free(string);
1641 heap_free(file);
1642
1643 return ret;
1644}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:114
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
#define RegCloseKey(hKey)
Definition: registry.h:49
static HWND hwndParent
Definition: cryptui.c:300
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
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:2668
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
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:4882
LSTATUS WINAPI RegGetValueA(HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:2037
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
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:2830
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
static const WCHAR empty[]
Definition: main.c:47
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define CP_ACP
Definition: compat.h:109
#define lstrcpynA
Definition: compat.h:751
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define FreeLibrary(x)
Definition: compat.h:748
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define LoadLibraryW(x)
Definition: compat.h:747
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4261
#define RRF_RT_DWORD
Definition: driver.c:581
#define RRF_RT_REG_SZ
Definition: driver.c:575
#define assert(x)
Definition: debug.h:53
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLint namelen
Definition: glext.h:7232
GLuint index
Definition: glext.h:6031
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
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
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
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
unsigned short UWORD
Definition: lzx.c:49
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static const WCHAR filenameW[]
Definition: amstream.c:41
static const WCHAR invalid[]
Definition: assoc.c:39
#define min(a, b)
Definition: monoChain.cc:55
struct @1680::@1681 driver
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define ODBC_SYSTEM_DSN
Definition: odbcinst.h:30
#define ODBC_INSTALL_COMPLETE
Definition: odbcinst.h:20
#define ODBC_ERROR_REQUEST_FAILED
Definition: odbcinst.h:41
#define ODBC_CONFIG_DRIVER
Definition: odbcinst.h:23
#define ODBC_ERROR_INVALID_PARAM_SEQUENCE
Definition: odbcinst.h:44
#define ODBC_ERROR_INVALID_DSN
Definition: odbcinst.h:39
#define ODBC_ERROR_INVALID_STR
Definition: odbcinst.h:34
#define ODBC_ERROR_LOAD_LIB_FAILED
Definition: odbcinst.h:43
#define ODBC_BOTH_DSN
Definition: odbcinst.h:28
#define ODBC_ERROR_COMPONENT_NOT_FOUND
Definition: odbcinst.h:36
#define ODBC_ERROR_GENERAL_ERR
Definition: odbcinst.h:31
#define ODBC_ERROR_INVALID_BUFF_LEN
Definition: odbcinst.h:32
#define ODBC_ERROR_OUT_OF_MEM
Definition: odbcinst.h:51
#define ODBC_ERROR_INVALID_KEYWORD_VALUE
Definition: odbcinst.h:38
long LONG
Definition: pedump.c:60
static const WCHAR driverW[]
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
#define SQL_SUCCESS
Definition: sql.h:163
#define SQL_SUCCESS_WITH_INFO
Definition: sql.h:164
#define SQL_ERROR
Definition: sql.h:68
#define SQL_NO_DATA
Definition: sql.h:315
#define SQL_MAX_DSN_LENGTH
Definition: sqlext.h:320
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:38
Definition: match.c:390
Definition: inflate.c:139
Definition: fci.c:127
Definition: name.c:39
Definition: pbuf.h:79
Definition: tftpd.h:86
Definition: parser.c:56
uint32_t * LPDWORD
Definition: typedefs.h:59
Definition: pdh_main.c:94
int ret
BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPCSTR lpszString)
Definition: odbccp32.c:1570
BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode)
Definition: odbccp32.c:1501
BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
Definition: odbccp32.c:225
static const WCHAR odbctranslators[]
Definition: odbccp32.c:48
BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1257
int WINAPI SQLGetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR defvalue, LPWSTR buff, int buff_len, LPCWSTR filename)
Definition: odbccp32.c:615
BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1486
static int error_code[8]
Definition: odbccp32.c:61
BOOL WINAPI SQLGetInstalledDriversW(WCHAR *buf, WORD size, WORD *sizeout)
Definition: odbccp32.c:494
BOOL WINAPI ODBCCPlApplet(LONG i, LONG j, LONG *p1, LONG *p2)
Definition: odbccp32.c:108
BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPCWSTR lpszString)
Definition: odbccp32.c:1560
BOOL WINAPI SQLGetAvailableDriversW(LPCWSTR lpszInfFile, LPWSTR lpszBuf, WORD cbBufMax, WORD *pcbBufOut)
Definition: odbccp32.c:467
BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1241
BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout)
Definition: odbccp32.c:561
static WCHAR * heap_strdupAtoW(const char *str)
Definition: odbccp32.c:91
BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:928
BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString, WORD *pcbString)
Definition: odbccp32.c:1295
BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString, WORD *pcbString)
Definition: odbccp32.c:1306
BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
Definition: odbccp32.c:451
BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
Definition: odbccp32.c:1325
SQLRETURN WINAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode, LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
Definition: odbccp32.c:1138
BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
Definition: odbccp32.c:365
BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN)
Definition: odbccp32.c:1518
BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:806
BOOL WINAPI SQLInstallDriverManager(LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:1025
BOOL WINAPI SQLManageDataSources(HWND hwnd)
Definition: odbccp32.c:1273
BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf, WORD cbBufMax, WORD *pcbBufOut)
Definition: odbccp32.c:476
static const WCHAR odbc_error_invalid_dsn[]
Definition: odbccp32.c:69
BOOL WINAPI SQLRemoveDefaultDataSource(void)
Definition: odbccp32.c:1317
static void clear_errors(void)
Definition: odbccp32.c:86
static const WCHAR odbc_error_request_failed[]
Definition: odbccp32.c:71
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
BOOL WINAPI SQLCreateDataSource(HWND hwnd, LPCSTR lpszDS)
Definition: odbccp32.c:459
static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
Definition: odbccp32.c:173
static const WCHAR odbc_error_invalid_param_string[]
Definition: odbccp32.c:68
static void push_error(int code, LPCWSTR msg)
Definition: odbccp32.c:75
BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:955
static const WCHAR odbc_error_component_not_found[]
Definition: odbccp32.c:65
static BOOL write_config_value(const WCHAR *driver, const WCHAR *args)
Definition: odbccp32.c:307
BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes)
Definition: odbccp32.c:240
BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
Definition: odbccp32.c:1546
BOOL WINAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile, LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
Definition: odbccp32.c:1069
static LPWSTR SQLInstall_strdup(LPCSTR str)
Definition: odbccp32.c:135
BOOL WINAPI SQLGetTranslator(HWND hwndParent, LPSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption)
Definition: odbccp32.c:779
static const WCHAR odbcW[]
Definition: odbccp32.c:45
static const WCHAR odbc_error_invalid_buff_len[]
Definition: odbccp32.c:64
BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
Definition: odbccp32.c:1421
int WINAPI SQLGetPrivateProfileString(LPCSTR section, LPCSTR entry, LPCSTR defvalue, LPSTR buff, int buff_len, LPCSTR filename)
Definition: odbccp32.c:687
static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename)
Definition: odbccp32.c:596
static const WCHAR odbc_error_invalid_keyword[]
Definition: odbccp32.c:72
BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:790
static const WCHAR odbc_error_invalid_param_sequence[]
Definition: odbccp32.c:67
BOOL WINAPI SQLRemoveDSNFromIni(LPCSTR lpszDSN)
Definition: odbccp32.c:1413
BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
Definition: odbccp32.c:1553
static const WCHAR odbcini[]
Definition: odbccp32.c:46
BOOL WINAPI SQLGetTranslatorW(HWND hwndParent, LPWSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption)
Definition: odbccp32.c:768
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 SQLInstallDriverManagerW(LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:999
BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
Definition: odbccp32.c:1532
BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszString, LPCSTR lpszFilename)
Definition: odbccp32.c:1623
BOOL WINAPI SQLInstallODBCW(HWND hwndParent, LPCWSTR lpszInfFile, LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
Definition: odbccp32.c:1059
static const WCHAR odbc_error_load_lib_failed[]
Definition: odbccp32.c:70
BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1380
SQLRETURN WINAPI SQLPostInstallerErrorW(DWORD fErrorCode, LPCWSTR szErrorMsg)
Definition: odbccp32.c:1281
static const WCHAR drivers_key[]
Definition: odbccp32.c:44
static HMODULE load_config_driver(const WCHAR *driver)
Definition: odbccp32.c:249
SQLRETURN WINAPI SQLPostInstallerError(DWORD fErrorCode, LPCSTR szErrorMsg)
Definition: odbccp32.c:1288
BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1193
BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszString, LPCWSTR lpszFilename)
Definition: odbccp32.c:1580
SQLRETURN WINAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode, LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
Definition: odbccp32.c:1079
static const WCHAR odbc_error_out_of_mem[]
Definition: odbccp32.c:66
BOOL WINAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
Definition: odbccp32.c:1405
static const WCHAR odbcdrivers[]
Definition: odbccp32.c:47
static const WCHAR * error_msg[8]
Definition: odbccp32.c:62
BOOL WINAPI SQLRemoveDriverManager(LPDWORD pdwUsageCount)
Definition: odbccp32.c:1397
BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1166
static LPWSTR SQLInstall_strdup_multi(LPCSTR str)
Definition: odbccp32.c:115
static int num_errors
Definition: odbccp32.c:60
static const WCHAR odbc_error_general_err[]
Definition: odbccp32.c:63
static UWORD config_mode
Definition: odbccp32.c:54
#define success(from, fromstr, to, tostr)
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193