ReactOS 0.4.17-dev-966-gf06eace
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
38#include "odbcinst.h"
39
41
42/* This config mode is known to be process-wide.
43 * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet.
44 * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping.
45 */
47
48/* MSDN documentation suggests that the error subsystem handles errors 1 to 8
49 * only and experimentation (Windows 2000) shows that the errors are process-
50 * wide so go for the simple solution; static arrays.
51 */
52static int num_errors;
53static int error_code[8];
54static const WCHAR *error_msg[8];
55
56static BOOL (WINAPI *pConfigDSN)(HWND hwnd, WORD request, const char *driver, const char *attr);
57static BOOL (WINAPI *pConfigDSNW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *attr);
58
59/* Push an error onto the error stack, taking care of ranges etc. */
60static void push_error(int code, LPCWSTR msg)
61{
63 {
66 num_errors++;
67 }
68}
69
70/* Clear the error stack */
71static void clear_errors(void)
72{
73 num_errors = 0;
74}
75
76static inline WCHAR *strdupAtoW(const char *str)
77{
78 LPWSTR ret = NULL;
79
80 if(str) {
81 DWORD len;
82
83 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
84 ret = malloc(len * sizeof(WCHAR));
85 if(ret)
87 }
88
89 return ret;
90}
91
92
94{
96 FIXME( "( %ld %ld %p %p) : stub!\n", i, j, p1, p2);
97 return FALSE;
98}
99
101{
102 LPCSTR p;
103 LPWSTR ret = NULL;
104 DWORD len;
105
106 if (!str)
107 return ret;
108
109 for (p = str; *p; p += lstrlenA(p) + 1)
110 ;
111
112 len = MultiByteToWideChar(CP_ACP, 0, str, p - str, NULL, 0 );
113 ret = malloc((len + 1) * sizeof(WCHAR));
115 ret[len] = 0;
116
117 return ret;
118}
119
121{
122 LPCWSTR p;
123 LPSTR ret = NULL;
124 DWORD len;
125
126 if (!str)
127 return ret;
128
129 for (p = str; *p; p += lstrlenW(p) + 1)
130 ;
131
133 ret = malloc((len + 1));
135 ret[len] = 0;
136
137 return ret;
138}
139
140static inline char *strdupWtoA( const WCHAR *str )
141{
142 char *ret = NULL;
143 if (str)
144 {
145 DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
146 if ((ret = malloc( len )))
148 }
149 return ret;
150}
151
153{
154 DWORD len;
155 LPWSTR ret = NULL;
156
157 if (!str)
158 return ret;
159
160 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0 );
161 ret = malloc(len * sizeof(WCHAR));
163
164 return ret;
165}
166
167/* Convert the wide string or zero-length-terminated list of wide strings to a
168 * narrow string or zero-length-terminated list of narrow strings.
169 * Do not try to emulate windows undocumented excesses (e.g. adding a third \0
170 * to a list)
171 * Arguments
172 * mode Indicates the sort of string.
173 * 1 denotes that the buffers contain strings terminated by a single nul
174 * character
175 * 2 denotes that the buffers contain zero-length-terminated lists
176 * (frequently erroneously referred to as double-null-terminated)
177 * buffer The narrow-character buffer into which to place the result. This
178 * must be a non-null pointer to the first element of a buffer whose
179 * length is passed in buffer_length.
180 * str The wide-character buffer containing the string or list of strings to
181 * be converted. str_length defines how many wide characters in the
182 * buffer are to be converted, including all desired terminating nul
183 * characters.
184 * str_length Effective length of str
185 * buffer_length Length of buffer
186 * returned_length A pointer to a variable that will receive the number of
187 * narrow characters placed into the buffer. This pointer
188 * may be NULL.
189 */
190static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
191{
192 LPSTR pbuf; /* allows us to allocate a temporary buffer only if needed */
193 int len; /* Length of the converted list */
195 assert(mode == 1 || mode == 2);
196 assert(buffer_length);
197 len = WideCharToMultiByte(CP_ACP, 0, str, str_length, 0, 0, NULL, NULL);
198 if (len > 0)
199 {
200 if (len > buffer_length)
201 {
202 pbuf = malloc(len);
203 }
204 else
205 {
206 pbuf = buffer;
207 }
208 len = WideCharToMultiByte(CP_ACP, 0, str, str_length, pbuf, len, NULL, NULL);
209 if (len > 0)
210 {
211 if (pbuf != buffer)
212 {
213 if (buffer_length > (mode - 1))
214 {
215 memcpy (buffer, pbuf, buffer_length-mode);
216 *(buffer+buffer_length-mode) = '\0';
217 }
218 *(buffer+buffer_length-1) = '\0';
219 }
220 if (returned_length)
221 {
222 *returned_length = pbuf == buffer ? len : buffer_length;
223 }
224 success = TRUE;
225 }
226 else
227 {
228 ERR("transferring wide to narrow\n");
229 }
230 if (pbuf != buffer)
231 {
232 free(pbuf);
233 }
234 }
235 else
236 {
237 ERR("measuring wide to narrow\n");
238 }
239 return success;
240}
241
243{
244 long ret;
247 DWORD size = 0, type;
248 HKEY hkey;
249
250 if ((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\", &hkey)) == ERROR_SUCCESS)
251 {
252 HKEY hkeydriver;
253
254 if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
255 {
256 ret = RegGetValueW(hkeydriver, NULL, L"Setup", RRF_RT_REG_SZ, &type, NULL, &size);
257 if(ret != ERROR_SUCCESS || type != REG_SZ)
258 {
259 RegCloseKey(hkeydriver);
260 RegCloseKey(hkey);
261 push_error(ODBC_ERROR_INVALID_DSN, L"Invalid DSN");
262
263 return NULL;
264 }
265
267 if(!filename)
268 {
269 RegCloseKey(hkeydriver);
270 RegCloseKey(hkey);
271 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
272
273 return NULL;
274 }
275 ret = RegGetValueW(hkeydriver, NULL, L"Setup", RRF_RT_REG_SZ, &type, filename, &size);
276
277 RegCloseKey(hkeydriver);
278 }
279
280 RegCloseKey(hkey);
281 }
282
283 if(ret != ERROR_SUCCESS)
284 {
285 free(filename);
286 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, L"Component not found");
287 return NULL;
288 }
289
291 free(filename);
292
293 if(!hmod)
294 push_error(ODBC_ERROR_LOAD_LIB_FAILED, L"Load Library Failed");
295
296 return hmod;
297}
298
300{
301 long ret;
302 HKEY hkey, hkeydriver;
303 WCHAR *name = NULL;
304
305 if(!args)
306 return FALSE;
307
308 if((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\", &hkey)) == ERROR_SUCCESS)
309 {
310 if((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
311 {
312 WCHAR *divider, *value;
313
314 name = malloc((wcslen(args) + 1) * sizeof(WCHAR));
315 if(!name)
316 {
317 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
318 goto fail;
319 }
321
322 divider = wcschr(name,'=');
323 if(!divider)
324 {
325 push_error(ODBC_ERROR_INVALID_KEYWORD_VALUE, L"Invalid keyword value");
326 goto fail;
327 }
328
329 value = divider + 1;
330 *divider = '\0';
331
332 TRACE("Write pair: %s = %s\n", debugstr_w(name), debugstr_w(value));
333 if(RegSetValueExW(hkeydriver, name, 0, REG_SZ, (BYTE*)value,
334 (lstrlenW(value)+1) * sizeof(WCHAR)) != ERROR_SUCCESS)
335 ERR("Failed to write registry installed key\n");
336 free(name);
337
338 RegCloseKey(hkeydriver);
339 }
340
341 RegCloseKey(hkey);
342 }
343
344 if(ret != ERROR_SUCCESS)
345 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, L"Component not found");
346
347 return ret == ERROR_SUCCESS;
348
349fail:
350 RegCloseKey(hkeydriver);
351 RegCloseKey(hkey);
352 free(name);
353
354 return FALSE;
355}
356
358{
359 switch (request)
360 {
361 case ODBC_ADD_DSN:
362 case ODBC_ADD_SYS_DSN:
363 return ODBC_ADD_DSN;
364
365 case ODBC_CONFIG_DSN:
367 return ODBC_CONFIG_DSN;
368
369 case ODBC_REMOVE_DSN:
371 return ODBC_REMOVE_DSN;
372
373 default:
374 FIXME("unhandled request %u\n", request);
375 return 0;
376 }
377}
378
380{
382 return ODBC_SYSTEM_DSN;
383}
384
386{
387 HMODULE mod;
388 BOOL ret = FALSE;
389 UWORD config_mode_prev = config_mode;
390 WORD mapped_request;
391
392 TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_w(driver), debugstr_w(attributes));
393 if (TRACE_ON(odbc) && attributes)
394 {
395 const WCHAR *p;
396 for (p = attributes; *p; p += lstrlenW(p) + 1)
397 TRACE("%s\n", debugstr_w(p));
398 }
399
400 clear_errors();
401
402 mapped_request = map_request(request);
403 if (!mapped_request)
404 return FALSE;
405
407 if (!mod)
408 return FALSE;
409
411
412 pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW");
413 if(pConfigDSNW)
414 ret = pConfigDSNW(hwnd, mapped_request, driver, attributes);
415 else
416 {
417 pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN");
418 if (pConfigDSN)
419 {
421 char *driverA = strdupWtoA(driver);
422 TRACE("Calling ConfigDSN\n");
423
424 ret = pConfigDSN(hwnd, mapped_request, driverA, attr);
425 free(attr);
426 free(driverA);
427 }
428 else
429 ERR("Failed to find ConfigDSN/W\n");
430 }
431
432 config_mode = config_mode_prev;
433
434 if (!ret)
435 push_error(ODBC_ERROR_REQUEST_FAILED, L"Request Failed");
436
438
439 return ret;
440}
441
443{
444 HMODULE mod;
445 BOOL ret = FALSE;
446 WCHAR *driverW;
447 UWORD config_mode_prev = config_mode;
448 WORD mapped_request;
449
450 TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_a(driver), debugstr_a(attributes));
451
452 if (TRACE_ON(odbc) && attributes)
453 {
454 const char *p;
455 for (p = attributes; *p; p += lstrlenA(p) + 1)
456 TRACE("%s\n", debugstr_a(p));
457 }
458
459 clear_errors();
460
461 mapped_request = map_request(request);
462 if (!mapped_request)
463 return FALSE;
464
466 if (!driverW)
467 {
468 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
469 return FALSE;
470 }
471
473 if (!mod)
474 {
475 free(driverW);
476 return FALSE;
477 }
478
480
481 pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN");
482 if (pConfigDSN)
483 {
484 TRACE("Calling ConfigDSN\n");
485 ret = pConfigDSN(hwnd, mapped_request, driver, attributes);
486 }
487 else
488 {
489 pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW");
490 if (pConfigDSNW)
491 {
492 WCHAR *attr = NULL;
493 TRACE("Calling ConfigDSNW\n");
494
496 if(attr)
497 ret = pConfigDSNW(hwnd, mapped_request, driverW, attr);
498 free(attr);
499 }
500 }
501
502 config_mode = config_mode_prev;
503
504 if (!ret)
505 push_error(ODBC_ERROR_REQUEST_FAILED, L"Request Failed");
506
507 free(driverW);
509
510 return ret;
511}
512
514 LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
515{
516 BOOL (WINAPI *pConfigDriverW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *args, const WCHAR *msg, WORD msgmax, WORD *msgout);
518 BOOL funcret = FALSE;
519
520 clear_errors();
521 TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_w(driver),
522 debugstr_w(args), msg, msgmax, msgout);
523
525 {
527 }
528
530 if(!hmod)
531 return FALSE;
532
533 pConfigDriverW = (void*)GetProcAddress(hmod, "ConfigDriverW");
534 if(pConfigDriverW)
535 funcret = pConfigDriverW(hwnd, request, driver, args, msg, msgmax, msgout);
536
537 if(!funcret)
538 push_error(ODBC_ERROR_REQUEST_FAILED, L"Request Failed");
539
541
542 return funcret;
543}
544
546 LPCSTR args, LPSTR msg, WORD msgmax, WORD *msgout)
547{
548 BOOL (WINAPI *pConfigDriverA)(HWND hwnd, WORD request, const char *driver, const char *args, const char *msg, WORD msgmax, WORD *msgout);
550 WCHAR *driverW;
551 BOOL funcret = FALSE;
552
553 clear_errors();
554 TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_a(driver),
555 debugstr_a(args), msg, msgmax, msgout);
556
558 if(!driverW)
559 {
560 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
561 return FALSE;
562 }
564 {
565 BOOL ret = FALSE;
566 WCHAR *argsW = strdupAtoW(args);
567 if(argsW)
568 {
570 free(argsW);
571 }
572 else
573 {
574 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
575 }
576
577 free(driverW);
578
579 return ret;
580 }
581
583 free(driverW);
584 if(!hmod)
585 return FALSE;
586
587 pConfigDriverA = (void*)GetProcAddress(hmod, "ConfigDriver");
588 if(pConfigDriverA)
589 funcret = pConfigDriverA(hwnd, request, driver, args, msg, msgmax, msgout);
590
591 if(!funcret)
592 push_error(ODBC_ERROR_REQUEST_FAILED, L"Request Failed");
593
595
596 return funcret;
597}
598
600{
601 clear_errors();
602 FIXME("%p %s\n", hwnd, debugstr_w(lpszDS));
604 return FALSE;
605}
606
608{
609 clear_errors();
610 FIXME("%p %s\n", hwnd, debugstr_a(lpszDS));
612 return FALSE;
613}
614
616 WORD cbBufMax, WORD *pcbBufOut)
617{
618 clear_errors();
619 FIXME("%s %p %d %p\n", debugstr_w(lpszInfFile), lpszBuf, cbBufMax, pcbBufOut);
621 return FALSE;
622}
623
625 WORD cbBufMax, WORD *pcbBufOut)
626{
627 clear_errors();
628 FIXME("%s %p %d %p\n", debugstr_a(lpszInfFile), lpszBuf, cbBufMax, pcbBufOut);
630 return FALSE;
631}
632
634{
635 clear_errors();
636 TRACE("%p\n", pwConfigMode);
637 if (pwConfigMode)
638 *pwConfigMode = config_mode;
639 return TRUE;
640}
641
643{
644 WORD written = 0;
645 DWORD index = 0;
646 BOOL ret = TRUE;
647 DWORD valuelen;
648 WCHAR *value;
649 HKEY drivers;
650 DWORD len;
651 LONG res;
652
653 clear_errors();
654
655 TRACE("%p %d %p\n", buf, size, sizeout);
656
657 if (!buf || !size)
658 {
659 push_error(ODBC_ERROR_INVALID_BUFF_LEN, L"Invalid buffer length");
660 return FALSE;
661 }
662
663 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\ODBC Drivers", 0,
664 KEY_QUERY_VALUE, &drivers);
665 if (res)
666 {
667 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, L"Component not found");
668 return FALSE;
669 }
670
671 valuelen = 256;
672 value = malloc(valuelen * sizeof(WCHAR));
673
674 size--;
675
676 while (1)
677 {
678 len = valuelen;
679 res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL);
680 while (res == ERROR_MORE_DATA)
681 {
682 value = realloc(value, ++len * sizeof(WCHAR));
683 res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL);
684 }
685 if (res == ERROR_SUCCESS)
686 {
687 lstrcpynW(buf + written, value, size - written);
688 written += min(len + 1, size - written);
689 }
690 else if (res == ERROR_NO_MORE_ITEMS)
691 break;
692 else
693 {
694 push_error(ODBC_ERROR_GENERAL_ERR, L"General error");
695 ret = FALSE;
696 break;
697 }
698 index++;
699 }
700
701 buf[written++] = 0;
702
703 free(value);
704 RegCloseKey(drivers);
705 if (sizeout)
706 *sizeout = written;
707 return ret;
708}
709
711{
712 WORD written;
713 WCHAR *wbuf;
714 BOOL ret;
715
716 TRACE("%p %d %p\n", buf, size, sizeout);
717
718 if (!buf || !size)
719 {
720 push_error(ODBC_ERROR_INVALID_BUFF_LEN, L"Invalid buffer length");
721 return FALSE;
722 }
723
724 wbuf = malloc(size * sizeof(WCHAR));
725 if (!wbuf)
726 {
727 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
728 return FALSE;
729 }
730
731 ret = SQLGetInstalledDriversW(wbuf, size, &written);
732 if (!ret)
733 {
734 free(wbuf);
735 return FALSE;
736 }
737
738 if (sizeout)
739 *sizeout = WideCharToMultiByte(CP_ACP, 0, wbuf, written, NULL, 0, NULL, NULL);
740 WideCharToMultiByte(CP_ACP, 0, wbuf, written, buf, size, NULL, NULL);
741
742 free(wbuf);
743 return TRUE;
744}
745
747{
748 HKEY hkey, hkeyfilename, hkeysection;
749 LONG ret;
750
751 if (RegOpenKeyW(root, L"Software\\ODBC", &hkey))
752 return NULL;
753
754 ret = RegOpenKeyW(hkey, filename, &hkeyfilename);
755 RegCloseKey(hkey);
756 if (ret)
757 return NULL;
758
759 ret = RegOpenKeyW(hkeyfilename, section, &hkeysection);
760 RegCloseKey(hkeyfilename);
761
762 return ret ? NULL : hkeysection;
763}
764
766 LPCWSTR defvalue, LPWSTR buff, int buff_len, LPCWSTR filename)
767{
768 BOOL usedefault = TRUE;
769 HKEY sectionkey;
770 LONG ret = 0;
771
772 TRACE("%s %s %s %p %d %s\n", debugstr_w(section), debugstr_w(entry),
774
775 clear_errors();
776
777 if (buff_len <= 0 || !section)
778 return 0;
779
780 if(buff)
781 buff[0] = 0;
782
783 if (!defvalue || !buff)
784 return 0;
785
786 /* odbcinit.ini is only for drivers, so default to local Machine */
787 if (!wcsicmp(filename, L"ODBCINST.INI") || config_mode == ODBC_SYSTEM_DSN)
789 else if (config_mode == ODBC_USER_DSN)
791 else
792 {
794 if (!sectionkey) sectionkey = get_privateprofile_sectionkey(HKEY_LOCAL_MACHINE, section, filename);
795 }
796
797 if (sectionkey)
798 {
799 DWORD type, size;
800
801 if (entry)
802 {
803 size = buff_len * sizeof(*buff);
804 if (RegGetValueW(sectionkey, NULL, entry, RRF_RT_REG_SZ, &type, buff, &size) == ERROR_SUCCESS)
805 {
806 usedefault = FALSE;
807 ret = (size / sizeof(*buff)) - 1;
808 }
809 }
810 else
811 {
813 DWORD index = 0;
815
816 usedefault = FALSE;
817
818 memset(buff, 0, buff_len);
819
820 namelen = sizeof(name);
821 while (RegEnumValueW(sectionkey, index, name, &namelen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
822 {
823 if ((ret + namelen+1) > buff_len)
824 break;
825
827 ret += namelen+1;
828 namelen = sizeof(name);
829 index++;
830 }
831 }
832
833 RegCloseKey(sectionkey);
834 }
835 else
836 usedefault = entry != NULL;
837
838 if (usedefault)
839 {
840 lstrcpynW(buff, defvalue, buff_len);
841 ret = lstrlenW(buff);
842 }
843
844 return ret;
845}
846
848 LPCSTR defvalue, LPSTR buff, int buff_len, LPCSTR filename)
849{
850 WCHAR *sectionW, *filenameW;
851 BOOL usedefault = TRUE;
852 HKEY sectionkey;
853 LONG ret = 0;
854
855 TRACE("%s %s %s %p %d %s\n", debugstr_a(section), debugstr_a(entry),
857
858 clear_errors();
859
860 if (buff_len <= 0)
861 return 0;
862
863 if (buff)
864 buff[0] = 0;
865
866 if (!section || !defvalue || !buff)
867 return 0;
868
869 if (!(sectionW = strdupAtoW(section))) return 0;
870 if (!(filenameW = strdupAtoW(filename)))
871 {
872 free(sectionW);
873 return 0;
874 }
875
878 else if (config_mode == ODBC_SYSTEM_DSN)
880 else
881 {
883 if (!sectionkey) sectionkey = get_privateprofile_sectionkey(HKEY_LOCAL_MACHINE, sectionW, filenameW);
884 }
885
886 free(sectionW);
888
889 if (sectionkey)
890 {
891 DWORD type, size;
892
893 if (entry)
894 {
895 size = buff_len * sizeof(*buff);
896 if (RegGetValueA(sectionkey, NULL, entry, RRF_RT_REG_SZ, &type, buff, &size) == ERROR_SUCCESS)
897 {
898 usedefault = FALSE;
899 ret = (size / sizeof(*buff)) - 1;
900 }
901 }
902 else
903 {
904 char name[MAX_PATH] = {0};
905 DWORD index = 0;
907
908 usedefault = FALSE;
909
910 memset(buff, 0, buff_len);
911
912 namelen = sizeof(name);
913 while (RegEnumValueA(sectionkey, index, name, &namelen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
914 {
915 if ((ret + namelen+1) > buff_len)
916 break;
917
919
920 ret += namelen+1;
921 namelen = sizeof(name);
922 index++;
923 }
924 }
925
926 RegCloseKey(sectionkey);
927 }
928 else
929 usedefault = entry != NULL;
930
931 if (usedefault)
932 {
933 lstrcpynA(buff, defvalue, buff_len);
934 ret = strlen(buff);
935 }
936
937 return ret;
938}
939
941 WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax,
942 WORD *pcbPathOut, DWORD *pvOption)
943{
944 clear_errors();
945 FIXME("%p %s %d %p %p %d %p %p\n", hwndParent, debugstr_w(lpszName), cbNameMax,
946 pcbNameOut, lpszPath, cbPathMax, pcbPathOut, pvOption);
948 return FALSE;
949}
950
952 WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax,
953 WORD *pcbPathOut, DWORD *pvOption)
954{
955 clear_errors();
956 FIXME("%p %s %d %p %p %d %p %p\n", hwndParent, debugstr_a(lpszName), cbNameMax,
957 pcbNameOut, lpszPath, cbPathMax, pcbPathOut, pvOption);
959 return FALSE;
960}
961
963 LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
964{
965 DWORD usage;
966
967 clear_errors();
968 TRACE("%s %s %p %d %p\n", debugstr_w(lpszInfFile),
969 debugstr_w(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
970
971 if (lpszInfFile)
972 return FALSE;
973
974 return SQLInstallDriverExW(lpszDriver, NULL, lpszPath, cbPathMax,
975 pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
976}
977
978BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver,
979 LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
980{
981 DWORD usage;
982
983 clear_errors();
984 TRACE("%s %s %p %d %p\n", debugstr_a(lpszInfFile),
985 debugstr_a(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
986
987 if (lpszInfFile)
988 return FALSE;
989
990 return SQLInstallDriverEx(lpszDriver, NULL, lpszPath, cbPathMax,
991 pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
992}
993
994static void write_registry_values(const WCHAR *regkey, const WCHAR *driver, const WCHAR *path_in, WCHAR *path,
995 DWORD *usage_count)
996{
997 HKEY hkey, hkeydriver;
998
999 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\", &hkey) == ERROR_SUCCESS)
1000 {
1001 if (RegCreateKeyW(hkey, regkey, &hkeydriver) == ERROR_SUCCESS)
1002 {
1003 if(RegSetValueExW(hkeydriver, driver, 0, REG_SZ, (BYTE*)L"Installed", sizeof(L"Installed")) != ERROR_SUCCESS)
1004 ERR("Failed to write registry installed key\n");
1005
1006 RegCloseKey(hkeydriver);
1007 }
1008
1009 if (RegCreateKeyW(hkey, driver, &hkeydriver) == ERROR_SUCCESS)
1010 {
1011 WCHAR entry[1024];
1012 const WCHAR *p;
1013 DWORD usagecount = 0;
1014 DWORD type, size;
1015
1016 /* Skip name entry */
1017 p = driver;
1018 p += lstrlenW(p) + 1;
1019
1020 if (!path_in)
1022 else
1023 lstrcpyW(path, path_in);
1024
1025 /* Store Usage */
1026 size = sizeof(usagecount);
1027 RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
1028 TRACE("Usage count %ld\n", usagecount);
1029
1030 for (; *p; p += lstrlenW(p) + 1)
1031 {
1032 WCHAR *divider = wcschr(p,'=');
1033
1034 if (divider)
1035 {
1036 WCHAR *value;
1037 int len;
1038
1039 /* Write pair values to the registry. */
1040 lstrcpynW(entry, p, divider - p + 1);
1041
1042 divider++;
1043 TRACE("Writing pair %s,%s\n", debugstr_w(entry), debugstr_w(divider));
1044
1045 /* Driver, Setup, Translator entries use the system path unless a path is specified. */
1046 if(lstrcmpiW(L"Driver", entry) == 0 || lstrcmpiW(L"Setup", entry) == 0 ||
1047 lstrcmpiW(L"Translator", entry) == 0)
1048 {
1050 {
1051 int pathlen = lstrlenW(path);
1052 len = pathlen + 1 + lstrlenW(divider) + 1;
1053 value = malloc(len * sizeof(WCHAR));
1054 if(!value)
1055 {
1056 RegCloseKey(hkeydriver);
1057 ERR("Out of memory\n");
1058 return;
1059 }
1060
1062 if (pathlen && path[pathlen - 1] != '\\')
1063 lstrcatW(value, L"\\");
1064 }
1065 else
1066 {
1067 value = calloc(1, (lstrlenW(divider)+1) * sizeof(WCHAR));
1068 if(!value)
1069 {
1070 RegCloseKey(hkeydriver);
1071 ERR("Out of memory\n");
1072 return;
1073 }
1074 }
1075 lstrcatW(value, divider);
1076 }
1077 else
1078 {
1079 len = lstrlenW(divider) + 1;
1080 value = malloc(len * sizeof(WCHAR));
1081 lstrcpyW(value, divider);
1082 }
1083
1084 if (RegSetValueExW(hkeydriver, entry, 0, REG_SZ, (BYTE*)value,
1085 (lstrlenW(value)+1)*sizeof(WCHAR)) != ERROR_SUCCESS)
1086 ERR("Failed to write registry data %s %s\n", debugstr_w(entry), debugstr_w(value));
1087 free(value);
1088 }
1089 else
1090 {
1091 ERR("No pair found. %s\n", debugstr_w(p));
1092 break;
1093 }
1094 }
1095
1096 /* Set Usage Count */
1097 usagecount++;
1098 if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&usagecount, sizeof(usagecount)) != ERROR_SUCCESS)
1099 ERR("Failed to write registry UsageCount key\n");
1100
1101 if (usage_count)
1102 *usage_count = usagecount;
1103
1104 RegCloseKey(hkeydriver);
1105 }
1106
1107 RegCloseKey(hkey);
1108 }
1109}
1110
1112 LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
1113 WORD fRequest, LPDWORD lpdwUsageCount)
1114{
1115 UINT len;
1117
1118 clear_errors();
1119 TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszDriver),
1120 debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
1121 fRequest, lpdwUsageCount);
1122
1123 write_registry_values(L"ODBC Drivers", lpszDriver, lpszPathIn, path, lpdwUsageCount);
1124
1125 len = lstrlenW(path);
1126
1127 if (pcbPathOut)
1128 *pcbPathOut = len;
1129
1130 if (lpszPathOut && cbPathOutMax > len)
1131 {
1132 lstrcpyW(lpszPathOut, path);
1133 return TRUE;
1134 }
1135 return FALSE;
1136}
1137
1139 LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
1140 WORD fRequest, LPDWORD lpdwUsageCount)
1141{
1142 LPWSTR driver, pathin;
1143 WCHAR pathout[MAX_PATH];
1144 BOOL ret;
1145 WORD cbOut = 0;
1146
1147 clear_errors();
1148 TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszDriver),
1149 debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
1150 fRequest, lpdwUsageCount);
1151
1152 driver = SQLInstall_strdup_multi(lpszDriver);
1153 pathin = SQLInstall_strdup(lpszPathIn);
1154
1155 ret = SQLInstallDriverExW(driver, pathin, pathout, MAX_PATH, &cbOut,
1156 fRequest, lpdwUsageCount);
1157 if (ret)
1158 {
1159 int len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
1160 0, NULL, NULL);
1161 if (len)
1162 {
1163 if (pcbPathOut)
1164 *pcbPathOut = len - 1;
1165
1166 if (!lpszPathOut || cbPathOutMax < len)
1167 {
1168 ret = FALSE;
1169 goto out;
1170 }
1171 len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
1172 cbPathOutMax, NULL, NULL);
1173 }
1174 }
1175
1176out:
1177 free(driver);
1178 free(pathin);
1179 return ret;
1180}
1181
1183 WORD *pcbPathOut)
1184{
1185 UINT len;
1187
1188 TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
1189
1190 if (cbPathMax < MAX_PATH)
1191 return FALSE;
1192
1193 clear_errors();
1194
1196
1197 if (pcbPathOut)
1198 *pcbPathOut = len;
1199
1200 if (lpszPath && cbPathMax > len)
1201 {
1202 lstrcpyW(lpszPath, path);
1203 return TRUE;
1204 }
1205 return FALSE;
1206}
1207
1209 WORD *pcbPathOut)
1210{
1211 BOOL ret;
1212 WORD len, cbOut = 0;
1214
1215 TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
1216
1217 if (cbPathMax < MAX_PATH)
1218 return FALSE;
1219
1220 clear_errors();
1221
1223 if (ret)
1224 {
1225 len = WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath, 0,
1226 NULL, NULL);
1227 if (len)
1228 {
1229 if (pcbPathOut)
1230 *pcbPathOut = len - 1;
1231
1232 if (!lpszPath || cbPathMax < len)
1233 return FALSE;
1234
1235 len = WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath,
1236 cbPathMax, NULL, NULL);
1237 }
1238 }
1239 return ret;
1240}
1241
1243 LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
1244{
1245 clear_errors();
1246 FIXME("%p %s %s %s\n", hwndParent, debugstr_w(lpszInfFile),
1247 debugstr_w(lpszSrcPath), debugstr_w(lpszDrivers));
1249 return FALSE;
1250}
1251
1253 LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
1254{
1255 clear_errors();
1256 FIXME("%p %s %s %s\n", hwndParent, debugstr_a(lpszInfFile),
1257 debugstr_a(lpszSrcPath), debugstr_a(lpszDrivers));
1259 return FALSE;
1260}
1261
1263 LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
1264{
1265 TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
1266 cbErrorMsgMax, pcbErrorMsg);
1267
1268 if (iError == 0)
1269 {
1270 return SQL_ERROR;
1271 }
1272 else if (iError <= num_errors)
1273 {
1274 BOOL truncated = FALSE;
1275 WORD len;
1276 LPCWSTR msg;
1277 iError--;
1278 if (pfErrorCode)
1279 *pfErrorCode = error_code[iError];
1280 msg = error_msg[iError];
1281 len = msg ? lstrlenW(msg) : 0;
1282 if (pcbErrorMsg)
1283 *pcbErrorMsg = len;
1284 len++;
1285 if (cbErrorMsgMax < len)
1286 {
1287 len = cbErrorMsgMax;
1288 truncated = TRUE;
1289 }
1290 if (lpszErrorMsg && len)
1291 {
1292 if (msg)
1293 {
1294 memcpy (lpszErrorMsg, msg, len * sizeof(WCHAR));
1295 }
1296 else
1297 {
1298 assert(len==1);
1299 *lpszErrorMsg = 0;
1300 }
1301 }
1302 else
1303 {
1304 /* Yes. If you pass a null pointer and a large length it is not an error! */
1305 truncated = TRUE;
1306 }
1307
1308 return truncated ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
1309 }
1310
1311 /* 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 */
1312 if (pcbErrorMsg)
1313 *pcbErrorMsg = 0;
1314
1315 if (lpszErrorMsg && cbErrorMsgMax > 0)
1316 *lpszErrorMsg = '\0';
1317
1318 return SQL_NO_DATA;
1319}
1320
1322 LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
1323{
1324 SQLRETURN ret;
1325 LPWSTR wbuf;
1326 WORD cbwbuf;
1327 TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
1328 cbErrorMsgMax, pcbErrorMsg);
1329
1330 wbuf = 0;
1331 if (lpszErrorMsg && cbErrorMsgMax)
1332 {
1333 wbuf = malloc(cbErrorMsgMax * sizeof(WCHAR));
1334 if (!wbuf)
1335 return SQL_ERROR;
1336 }
1337 ret = SQLInstallerErrorW(iError, pfErrorCode, wbuf, cbErrorMsgMax, &cbwbuf);
1338 if (wbuf)
1339 {
1340 WORD cbBuf = 0;
1341 SQLInstall_narrow(1, lpszErrorMsg, wbuf, cbwbuf+1, cbErrorMsgMax, &cbBuf);
1342 free(wbuf);
1343 if (pcbErrorMsg)
1344 *pcbErrorMsg = cbBuf-1;
1345 }
1346 return ret;
1347}
1348
1350 LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
1351 WORD fRequest, LPDWORD lpdwUsageCount)
1352{
1353 UINT len;
1355
1356 clear_errors();
1357 TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszTranslator),
1358 debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
1359 fRequest, lpdwUsageCount);
1360
1361 write_registry_values(L"ODBC Translators", lpszTranslator, lpszPathIn, path, lpdwUsageCount);
1362
1363 len = lstrlenW(path);
1364
1365 if (pcbPathOut)
1366 *pcbPathOut = len;
1367
1368 if (lpszPathOut && cbPathOutMax > len)
1369 {
1370 lstrcpyW(lpszPathOut, path);
1371 return TRUE;
1372 }
1373 return FALSE;
1374}
1375
1377 LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
1378 WORD fRequest, LPDWORD lpdwUsageCount)
1379{
1380 LPCSTR p;
1381 LPWSTR translator, pathin;
1382 WCHAR pathout[MAX_PATH];
1383 BOOL ret;
1384 WORD cbOut = 0;
1385
1386 clear_errors();
1387 TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszTranslator),
1388 debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
1389 fRequest, lpdwUsageCount);
1390
1391 for (p = lpszTranslator; *p; p += lstrlenA(p) + 1)
1392 TRACE("%s\n", debugstr_a(p));
1393
1394 translator = SQLInstall_strdup_multi(lpszTranslator);
1395 pathin = SQLInstall_strdup(lpszPathIn);
1396
1397 ret = SQLInstallTranslatorExW(translator, pathin, pathout, MAX_PATH,
1398 &cbOut, fRequest, lpdwUsageCount);
1399 if (ret)
1400 {
1401 int len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
1402 0, NULL, NULL);
1403 if (len)
1404 {
1405 if (pcbPathOut)
1406 *pcbPathOut = len - 1;
1407
1408 if (!lpszPathOut || cbPathOutMax < len)
1409 {
1410 ret = FALSE;
1411 goto out;
1412 }
1413 len = WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
1414 cbPathOutMax, NULL, NULL);
1415 }
1416 }
1417
1418out:
1419 free(translator);
1420 free(pathin);
1421 return ret;
1422}
1423
1424BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator,
1425 LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax,
1426 WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
1427{
1428 clear_errors();
1429 TRACE("%s %s %s %p %d %p %d %p\n", debugstr_a(lpszInfFile),
1430 debugstr_a(lpszTranslator), debugstr_a(lpszPathIn), lpszPathOut,
1431 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1432
1433 if (lpszInfFile)
1434 return FALSE;
1435
1436 return SQLInstallTranslatorEx(lpszTranslator, lpszPathIn, lpszPathOut,
1437 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1438}
1439
1441 LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax,
1442 WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
1443{
1444 clear_errors();
1445 TRACE("%s %s %s %p %d %p %d %p\n", debugstr_w(lpszInfFile),
1446 debugstr_w(lpszTranslator), debugstr_w(lpszPathIn), lpszPathOut,
1447 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1448
1449 if (lpszInfFile)
1450 return FALSE;
1451
1452 return SQLInstallTranslatorExW(lpszTranslator, lpszPathIn, lpszPathOut,
1453 cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
1454}
1455
1457{
1458 clear_errors();
1459 FIXME("%p\n", hwnd);
1461 return FALSE;
1462}
1463
1465{
1466 FIXME("%lu %s\n", fErrorCode, debugstr_w(szErrorMsg));
1468 return FALSE;
1469}
1470
1472{
1473 FIXME("%lu %s\n", fErrorCode, debugstr_a(szErrorMsg));
1475 return FALSE;
1476}
1477
1478BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
1479 LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString,
1480 WORD *pcbString)
1481{
1482 clear_errors();
1483 FIXME("%s %s %s %s %d %p\n", debugstr_w(lpszFileName), debugstr_w(lpszAppName),
1484 debugstr_w(lpszKeyName), debugstr_w(lpszString), cbString, pcbString);
1486 return FALSE;
1487}
1488
1489BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
1490 LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString,
1491 WORD *pcbString)
1492{
1493 clear_errors();
1494 FIXME("%s %s %s %s %d %p\n", debugstr_a(lpszFileName), debugstr_a(lpszAppName),
1495 debugstr_a(lpszKeyName), debugstr_a(lpszString), cbString, pcbString);
1497 return FALSE;
1498}
1499
1501{
1502 clear_errors();
1503 FIXME("\n");
1505 return FALSE;
1506}
1507
1508BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
1509{
1510 HKEY hkey;
1511 DWORD usagecount = 1;
1512
1513 clear_errors();
1514 TRACE("%s %d %p\n", debugstr_w(drivername), remove_dsn, usage_count);
1515
1516 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\", &hkey) == ERROR_SUCCESS)
1517 {
1518 HKEY hkeydriver;
1519
1520 if (RegOpenKeyW(hkey, drivername, &hkeydriver) == ERROR_SUCCESS)
1521 {
1522 DWORD size, type;
1523 DWORD count;
1524
1525 size = sizeof(usagecount);
1526 RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
1527 TRACE("Usage count %ld\n", usagecount);
1528 count = usagecount - 1;
1529 if (count)
1530 {
1531 if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&count, sizeof(count)) != ERROR_SUCCESS)
1532 ERR("Failed to write registry UsageCount key\n");
1533 }
1534
1535 RegCloseKey(hkeydriver);
1536 }
1537
1538 if (usagecount)
1539 usagecount--;
1540
1541 if (!usagecount)
1542 {
1543 if (RegDeleteKeyW(hkey, drivername) != ERROR_SUCCESS)
1544 ERR("Failed to delete registry key: %s\n", debugstr_w(drivername));
1545
1546 if (RegOpenKeyW(hkey, L"ODBC Drivers", &hkeydriver) == ERROR_SUCCESS)
1547 {
1548 if(RegDeleteValueW(hkeydriver, drivername) != ERROR_SUCCESS)
1549 ERR("Failed to delete registry value: %s\n", debugstr_w(drivername));
1550 RegCloseKey(hkeydriver);
1551 }
1552 }
1553
1554 RegCloseKey(hkey);
1555 }
1556
1557 if (usage_count)
1558 *usage_count = usagecount;
1559
1560 return TRUE;
1561}
1562
1563BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN,
1564 LPDWORD lpdwUsageCount)
1565{
1566 WCHAR *driver;
1567 BOOL ret;
1568
1569 clear_errors();
1570 TRACE("%s %d %p\n", debugstr_a(lpszDriver), fRemoveDSN, lpdwUsageCount);
1571
1572 driver = SQLInstall_strdup(lpszDriver);
1573
1574 ret = SQLRemoveDriverW(driver, fRemoveDSN, lpdwUsageCount);
1575
1576 free(driver);
1577 return ret;
1578}
1579
1581{
1582 clear_errors();
1583 FIXME("%p\n", pdwUsageCount);
1584 if (pdwUsageCount) *pdwUsageCount = 1;
1585 return TRUE;
1586}
1587
1589{
1590 HKEY hkey, hkeyroot = HKEY_CURRENT_USER;
1591
1592 TRACE("%s\n", debugstr_w(lpszDSN));
1593
1594 if (!SQLValidDSNW(lpszDSN))
1595 {
1596 push_error(ODBC_ERROR_INVALID_DSN, L"Invalid DSN");
1597 return FALSE;
1598 }
1599
1600 clear_errors();
1601
1603 hkeyroot = HKEY_LOCAL_MACHINE;
1604 else if (config_mode == ODBC_BOTH_DSN)
1605 {
1606 WCHAR *regpath = malloc( (wcslen(L"Software\\ODBC\\ODBC.INI\\") + wcslen(lpszDSN) + 1) * sizeof(WCHAR) );
1607 if (!regpath)
1608 {
1609 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
1610 return FALSE;
1611 }
1612 wcscpy(regpath, L"Software\\ODBC\\ODBC.INI\\");
1613 wcscat(regpath, lpszDSN);
1614
1615 /* ONLY removes one DSN, USER or SYSTEM */
1616 if (RegOpenKeyW(HKEY_CURRENT_USER, regpath, &hkey) == ERROR_SUCCESS)
1617 hkeyroot = HKEY_CURRENT_USER;
1618 else
1619 hkeyroot = HKEY_LOCAL_MACHINE;
1620
1621 RegCloseKey(hkey);
1622 free(regpath);
1623 }
1624
1625 if (RegOpenKeyW(hkeyroot, L"Software\\ODBC\\ODBC.INI\\ODBC Data Sources", &hkey) == ERROR_SUCCESS)
1626 {
1627 RegDeleteValueW(hkey, lpszDSN);
1628 RegCloseKey(hkey);
1629 }
1630
1631 if (RegOpenKeyW(hkeyroot, L"Software\\ODBC\\ODBC.INI", &hkey) == ERROR_SUCCESS)
1632 {
1633 RegDeleteTreeW(hkey, lpszDSN);
1634 RegCloseKey(hkey);
1635 }
1636
1637 return TRUE;
1638}
1639
1641{
1642 BOOL ret = FALSE;
1643 WCHAR *dsn;
1644
1645 TRACE("%s\n", debugstr_a(lpszDSN));
1646
1647 clear_errors();
1648
1649 dsn = SQLInstall_strdup(lpszDSN);
1650 if (dsn)
1652 else
1653 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
1654
1655 free(dsn);
1656
1657 return ret;
1658}
1659
1660BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
1661{
1662 HKEY hkey;
1663 DWORD usagecount = 1;
1664 BOOL ret = TRUE;
1665
1666 clear_errors();
1667 TRACE("%s %p\n", debugstr_w(translator), usage_count);
1668
1669 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\", &hkey) == ERROR_SUCCESS)
1670 {
1671 HKEY hkeydriver;
1672
1673 if (RegOpenKeyW(hkey, translator, &hkeydriver) == ERROR_SUCCESS)
1674 {
1675 DWORD size, type;
1676 DWORD count;
1677
1678 size = sizeof(usagecount);
1679 RegGetValueA(hkeydriver, NULL, "UsageCount", RRF_RT_DWORD, &type, &usagecount, &size);
1680 TRACE("Usage count %ld\n", usagecount);
1681 count = usagecount - 1;
1682 if (count)
1683 {
1684 if (RegSetValueExA(hkeydriver, "UsageCount", 0, REG_DWORD, (BYTE*)&count, sizeof(count)) != ERROR_SUCCESS)
1685 ERR("Failed to write registry UsageCount key\n");
1686 }
1687
1688 RegCloseKey(hkeydriver);
1689 }
1690
1691 if (usagecount)
1692 usagecount--;
1693
1694 if (!usagecount)
1695 {
1696 if(RegDeleteKeyW(hkey, translator) != ERROR_SUCCESS)
1697 {
1698 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, L"Component not found");
1699 WARN("Failed to delete registry key: %s\n", debugstr_w(translator));
1700 ret = FALSE;
1701 }
1702
1703 if (ret && RegOpenKeyW(hkey, L"ODBC Translators", &hkeydriver) == ERROR_SUCCESS)
1704 {
1705 if(RegDeleteValueW(hkeydriver, translator) != ERROR_SUCCESS)
1706 {
1707 push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, L"Component not found");
1708 WARN("Failed to delete registry key: %s\n", debugstr_w(translator));
1709 ret = FALSE;
1710 }
1711
1712 RegCloseKey(hkeydriver);
1713 }
1714 }
1715
1716 RegCloseKey(hkey);
1717 }
1718
1719 if (ret && usage_count)
1720 *usage_count = usagecount;
1721
1722 return ret;
1723}
1724
1725BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
1726{
1727 WCHAR *translator;
1728 BOOL ret;
1729
1730 clear_errors();
1731 TRACE("%s %p\n", debugstr_a(lpszTranslator), lpdwUsageCount);
1732
1733 translator = SQLInstall_strdup(lpszTranslator);
1734 ret = SQLRemoveTranslatorW(translator, lpdwUsageCount);
1735
1736 free(translator);
1737 return ret;
1738}
1739
1741{
1742 clear_errors();
1743 TRACE("%u\n", wConfigMode);
1744
1745 if (wConfigMode > ODBC_SYSTEM_DSN)
1746 {
1747 push_error(ODBC_ERROR_INVALID_PARAM_SEQUENCE, L"Invalid parameter sequence");
1748 return FALSE;
1749 }
1750 else
1751 {
1752 config_mode = wConfigMode;
1753 return TRUE;
1754 }
1755}
1756
1758{
1759 clear_errors();
1760 TRACE("%s\n", debugstr_w(lpszDSN));
1761
1762 if (!lpszDSN || !*lpszDSN || lstrlenW(lpszDSN) > SQL_MAX_DSN_LENGTH || wcspbrk(lpszDSN, L"[]{}(),;?*=!@\\"))
1763 {
1764 return FALSE;
1765 }
1766
1767 return TRUE;
1768}
1769
1771{
1772 static const char *invalid = "[]{}(),;?*=!@\\";
1773 clear_errors();
1774 TRACE("%s\n", debugstr_a(lpszDSN));
1775
1776 if (!lpszDSN || !*lpszDSN || strlen(lpszDSN) > SQL_MAX_DSN_LENGTH || strpbrk(lpszDSN, invalid))
1777 {
1778 return FALSE;
1779 }
1780
1781 return TRUE;
1782}
1783
1785{
1786 DWORD ret;
1787 HKEY hkey, hkeydriver, hkeyroot = HKEY_CURRENT_USER;
1789
1790 TRACE("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
1791
1792 clear_errors();
1793
1794 if (!SQLValidDSNW(lpszDSN))
1795 {
1796 push_error(ODBC_ERROR_INVALID_DSN, L"Invalid DSN");
1797 return FALSE;
1798 }
1799
1800 /* It doesn't matter if we cannot find the driver, windows just writes a blank value. */
1801 filename[0] = 0;
1802 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\ODBC\\ODBCINST.INI\\", &hkey) == ERROR_SUCCESS)
1803 {
1804 HKEY hkeydriver;
1805
1806 if (RegOpenKeyW(hkey, lpszDriver, &hkeydriver) == ERROR_SUCCESS)
1807 {
1808 DWORD size = MAX_PATH * sizeof(WCHAR);
1809 RegGetValueW(hkeydriver, NULL, L"driver", RRF_RT_REG_SZ, NULL, filename, &size);
1810 RegCloseKey(hkeydriver);
1811 }
1812 RegCloseKey(hkey);
1813 }
1814
1816 hkeyroot = HKEY_LOCAL_MACHINE;
1817 else if (config_mode == ODBC_BOTH_DSN)
1818 {
1819 WCHAR *regpath = malloc( (wcslen(L"Software\\ODBC\\ODBC.INI\\") + wcslen(lpszDSN) + 1) * sizeof(WCHAR) );
1820 if (!regpath)
1821 {
1822 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
1823 return FALSE;
1824 }
1825 wcscpy(regpath, L"Software\\ODBC\\ODBC.INI\\");
1826 wcscat(regpath, lpszDSN);
1827
1828 /* Check for existing entry */
1829 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey) == ERROR_SUCCESS)
1830 hkeyroot = HKEY_LOCAL_MACHINE;
1831 else
1832 hkeyroot = HKEY_CURRENT_USER;
1833
1834 RegCloseKey(hkey);
1835 free(regpath);
1836 }
1837
1838 if ((ret = RegCreateKeyW(hkeyroot, L"SOFTWARE\\ODBC\\ODBC.INI", &hkey)) == ERROR_SUCCESS)
1839 {
1840 HKEY sources;
1841
1842 if ((ret = RegCreateKeyW(hkey, L"ODBC Data Sources", &sources)) == ERROR_SUCCESS)
1843 {
1844 RegSetValueExW(sources, lpszDSN, 0, REG_SZ, (BYTE*)lpszDriver, (lstrlenW(lpszDriver)+1)*sizeof(WCHAR));
1846
1847 RegDeleteTreeW(hkey, lpszDSN);
1848 if ((ret = RegCreateKeyW(hkey, lpszDSN, &hkeydriver)) == ERROR_SUCCESS)
1849 {
1850 RegSetValueExW(sources, L"driver", 0, REG_SZ, (BYTE*)filename, (lstrlenW(filename)+1)*sizeof(WCHAR));
1851 RegCloseKey(hkeydriver);
1852 }
1853 }
1854 RegCloseKey(hkey);
1855 }
1856
1857 if (ret != ERROR_SUCCESS)
1858 push_error(ODBC_ERROR_REQUEST_FAILED, L"Request Failed");
1859
1860 return ret == ERROR_SUCCESS;
1861}
1862
1864{
1865 BOOL ret = FALSE;
1866 WCHAR *dsn, *driver;
1867
1868 TRACE("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
1869
1870 dsn = SQLInstall_strdup(lpszDSN);
1871 driver = SQLInstall_strdup(lpszDriver);
1872 if (dsn && driver)
1874 else
1875 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
1876
1877 free(dsn);
1878 free(driver);
1879
1880 return ret;
1881}
1882
1883BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
1884 LPCWSTR lpszKeyName, LPCWSTR lpszString)
1885{
1886 clear_errors();
1887 FIXME("%s %s %s %s\n", debugstr_w(lpszFileName), debugstr_w(lpszAppName),
1888 debugstr_w(lpszKeyName), debugstr_w(lpszString));
1890 return FALSE;
1891}
1892
1893BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
1894 LPCSTR lpszKeyName, LPCSTR lpszString)
1895{
1896 clear_errors();
1897 FIXME("%s %s %s %s\n", debugstr_a(lpszFileName), debugstr_a(lpszAppName),
1898 debugstr_a(lpszKeyName), debugstr_a(lpszString));
1900 return FALSE;
1901}
1902
1904 LPCWSTR lpszString, LPCWSTR lpszFilename)
1905{
1906 LONG ret;
1907 HKEY hkey;
1908 WCHAR *regpath;
1909
1910 clear_errors();
1911 TRACE("%s %s %s %s\n", debugstr_w(lpszSection), debugstr_w(lpszEntry),
1912 debugstr_w(lpszString), debugstr_w(lpszFilename));
1913
1914 if(!lpszFilename || !*lpszFilename)
1915 {
1916 push_error(ODBC_ERROR_INVALID_STR, L"Invalid parameter string");
1917 return FALSE;
1918 }
1919
1920 regpath = malloc ( (wcslen(L"Software\\ODBC\\") + wcslen(lpszFilename) + wcslen(L"\\")
1921 + wcslen(lpszSection) + 1) * sizeof(WCHAR));
1922 if (!regpath)
1923 {
1924 push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory");
1925 return FALSE;
1926 }
1927 wcscpy(regpath, L"Software\\ODBC\\");
1928 wcscat(regpath, lpszFilename);
1929 wcscat(regpath, L"\\");
1930 wcscat(regpath, lpszSection);
1931
1932 /* odbcinit.ini is only for drivers, so default to local Machine */
1933 if (!wcsicmp(lpszFilename, L"ODBCINST.INI") || config_mode == ODBC_SYSTEM_DSN)
1934 ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey);
1935 else if (config_mode == ODBC_USER_DSN)
1936 ret = RegCreateKeyW(HKEY_CURRENT_USER, regpath, &hkey);
1937 else
1938 {
1939 /* Check existing keys first */
1940 if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, regpath, &hkey)) != ERROR_SUCCESS)
1941 ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey);
1942
1943 if (ret != ERROR_SUCCESS)
1944 ret = RegCreateKeyW(HKEY_CURRENT_USER, regpath, &hkey);
1945 }
1946
1947 free(regpath);
1948
1949 if (ret == ERROR_SUCCESS)
1950 {
1951 if(lpszString)
1952 ret = RegSetValueExW(hkey, lpszEntry, 0, REG_SZ, (BYTE*)lpszString, (lstrlenW(lpszString)+1)*sizeof(WCHAR));
1953 else
1954 ret = RegSetValueExW(hkey, lpszEntry, 0, REG_SZ, (BYTE*)L"", sizeof(L""));
1955 RegCloseKey(hkey);
1956 }
1957
1958 return ret == ERROR_SUCCESS;
1959}
1960
1962 LPCSTR lpszString, LPCSTR lpszFilename)
1963{
1964 BOOL ret;
1965 WCHAR *sect, *entry, *string, *file;
1966 clear_errors();
1967 TRACE("%s %s %s %s\n", lpszSection, lpszEntry, lpszString, lpszFilename);
1968
1969 sect = strdupAtoW(lpszSection);
1970 entry = strdupAtoW(lpszEntry);
1971 string = strdupAtoW(lpszString);
1972 file = strdupAtoW(lpszFilename);
1973
1974 ret = SQLWritePrivateProfileStringW(sect, entry, string, file);
1975
1976 free(sect);
1977 free(entry);
1978 free(string);
1979 free(file);
1980
1981 return ret;
1982}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:68
#define REG_SZ
Definition: layer.c:22
#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:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
static HWND hwndParent
Definition: cryptui.c:299
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#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
#define wcschr
Definition: compat.h:17
#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 FreeLibrary(x)
Definition: compat.h:748
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2331
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP wchar_t *__cdecl wcspbrk(const wchar_t *, const wchar_t *)
Definition: wcs.c:2021
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP char *__cdecl strpbrk(const char *, const char *)
Definition: string.c:3530
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLsizei GLenum * sources
Definition: glext.h:7753
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
unsigned int UINT
Definition: sysinfo.c:13
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
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 NTSTATUS *static PWSTR CURDIR *static HMODULE hmod
Definition: security.c:104
static const WCHAR filenameW[]
Definition: resource.c:27
#define min(a, b)
Definition: monoChain.cc:55
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define BOOL
Definition: nt_native.h:43
#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_REMOVE_SYS_DSN
Definition: odbcinst.h:18
#define ODBC_ADD_DSN
Definition: odbcinst.h:12
#define ODBC_CONFIG_DRIVER
Definition: odbcinst.h:23
#define ODBC_REMOVE_DSN
Definition: odbcinst.h:14
#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_CONFIG_DSN
Definition: odbcinst.h:13
#define ODBC_BOTH_DSN
Definition: odbcinst.h:28
#define ODBC_ERROR_COMPONENT_NOT_FOUND
Definition: odbcinst.h:36
#define ODBC_CONFIG_SYS_DSN
Definition: odbcinst.h:17
#define ODBC_ERROR_GENERAL_ERR
Definition: odbcinst.h:31
#define ODBC_USER_DSN
Definition: odbcinst.h:29
#define ODBC_ERROR_INVALID_BUFF_LEN
Definition: odbcinst.h:32
#define ODBC_ADD_SYS_DSN
Definition: odbcinst.h:16
#define ODBC_ERROR_OUT_OF_MEM
Definition: odbcinst.h:51
#define ODBC_ERROR_INVALID_KEYWORD_VALUE
Definition: odbcinst.h:38
static HANDLE ACCESS_MASK ULONG attributes
Definition: om.c:94
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static const WCHAR driverW[]
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:615
wcscat
wcscpy
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void DWORD * buff_len
Definition: shcore.c:41
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void * buff
Definition: shcore.c:41
#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: cookie.c:202
Definition: inflate.c:139
Definition: fci.c:123
Definition: name.c:39
Definition: pbuf.h:186
Definition: tftpd.h:86
Definition: parser.c:56
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
char * LPSTR
Definition: typedefs.h:51
Definition: pdh_main.c:64
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPCSTR lpszString)
Definition: odbccp32.c:1893
BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode)
Definition: odbccp32.c:1740
BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1440
int WINAPI SQLGetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR defvalue, LPWSTR buff, int buff_len, LPCWSTR filename)
Definition: odbccp32.c:765
BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1725
static int error_code[8]
Definition: odbccp32.c:53
BOOL WINAPI SQLGetInstalledDriversW(WCHAR *buf, WORD size, WORD *sizeout)
Definition: odbccp32.c:642
BOOL WINAPI ODBCCPlApplet(LONG i, LONG j, LONG *p1, LONG *p2)
Definition: odbccp32.c:93
BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPCWSTR lpszString)
Definition: odbccp32.c:1883
BOOL WINAPI SQLGetAvailableDriversW(LPCWSTR lpszInfFile, LPWSTR lpszBuf, WORD cbBufMax, WORD *pcbBufOut)
Definition: odbccp32.c:615
BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1424
BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR attributes)
Definition: odbccp32.c:385
BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout)
Definition: odbccp32.c:710
BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1111
BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString, WORD *pcbString)
Definition: odbccp32.c:1478
BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString, WORD *pcbString)
Definition: odbccp32.c:1489
BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
Definition: odbccp32.c:599
BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
Definition: odbccp32.c:1508
SQLRETURN WINAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode, LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
Definition: odbccp32.c:1321
BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
Definition: odbccp32.c:513
BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN)
Definition: odbccp32.c:1757
BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:978
BOOL WINAPI SQLInstallDriverManager(LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:1208
BOOL WINAPI SQLManageDataSources(HWND hwnd)
Definition: odbccp32.c:1456
static WORD request
Definition: odbccp32.c:56
BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf, WORD cbBufMax, WORD *pcbBufOut)
Definition: odbccp32.c:624
BOOL WINAPI SQLRemoveDefaultDataSource(void)
Definition: odbccp32.c:1500
static void clear_errors(void)
Definition: odbccp32.c:71
BOOL WINAPI SQLConfigDriver(HWND hwnd, WORD request, LPCSTR driver, LPCSTR args, LPSTR msg, WORD msgmax, WORD *msgout)
Definition: odbccp32.c:545
BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
Definition: odbccp32.c:633
BOOL WINAPI SQLCreateDataSource(HWND hwnd, LPCSTR lpszDS)
Definition: odbccp32.c:607
static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
Definition: odbccp32.c:190
static void push_error(int code, LPCWSTR msg)
Definition: odbccp32.c:60
static WORD const char const char * attr
Definition: odbccp32.c:56
BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1138
static BOOL write_config_value(const WCHAR *driver, const WCHAR *args)
Definition: odbccp32.c:299
BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attributes)
Definition: odbccp32.c:442
BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
Definition: odbccp32.c:1784
static LPSTR SQLInstall_strdup_multiWtoA(LPCWSTR str)
Definition: odbccp32.c:120
BOOL WINAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile, LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
Definition: odbccp32.c:1252
static LPWSTR SQLInstall_strdup(LPCSTR str)
Definition: odbccp32.c:152
BOOL WINAPI SQLGetTranslator(HWND hwndParent, LPSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption)
Definition: odbccp32.c:951
static WORD const char * driver
Definition: odbccp32.c:56
static char * strdupWtoA(const WCHAR *str)
Definition: odbccp32.c:140
BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
Definition: odbccp32.c:1660
int WINAPI SQLGetPrivateProfileString(LPCSTR section, LPCSTR entry, LPCSTR defvalue, LPSTR buff, int buff_len, LPCSTR filename)
Definition: odbccp32.c:847
BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:962
BOOL WINAPI SQLRemoveDSNFromIni(LPCSTR lpszDSN)
Definition: odbccp32.c:1640
BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
Definition: odbccp32.c:1863
BOOL WINAPI SQLGetTranslatorW(HWND hwndParent, LPWSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption)
Definition: odbccp32.c:940
static void write_registry_values(const WCHAR *regkey, const WCHAR *driver, const WCHAR *path_in, WCHAR *path, DWORD *usage_count)
Definition: odbccp32.c:994
BOOL WINAPI SQLInstallDriverManagerW(LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut)
Definition: odbccp32.c:1182
BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
Definition: odbccp32.c:1770
BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszString, LPCSTR lpszFilename)
Definition: odbccp32.c:1961
BOOL WINAPI SQLInstallODBCW(HWND hwndParent, LPCWSTR lpszInfFile, LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
Definition: odbccp32.c:1242
BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1563
static WCHAR * strdupAtoW(const char *str)
Definition: odbccp32.c:76
SQLRETURN WINAPI SQLPostInstallerErrorW(DWORD fErrorCode, LPCWSTR szErrorMsg)
Definition: odbccp32.c:1464
static HKEY get_privateprofile_sectionkey(HKEY root, const WCHAR *section, const WCHAR *filename)
Definition: odbccp32.c:746
static HMODULE load_config_driver(const WCHAR *driver)
Definition: odbccp32.c:242
SQLRETURN WINAPI SQLPostInstallerError(DWORD fErrorCode, LPCSTR szErrorMsg)
Definition: odbccp32.c:1471
BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1376
static WORD map_request(WORD request)
Definition: odbccp32.c:357
BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszString, LPCWSTR lpszFilename)
Definition: odbccp32.c:1903
static UWORD get_config_mode(WORD request)
Definition: odbccp32.c:379
SQLRETURN WINAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode, LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
Definition: odbccp32.c:1262
BOOL WINAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
Definition: odbccp32.c:1588
static const WCHAR * error_msg[8]
Definition: odbccp32.c:54
BOOL WINAPI SQLRemoveDriverManager(LPDWORD pdwUsageCount)
Definition: odbccp32.c:1580
BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1349
static LPWSTR SQLInstall_strdup_multi(LPCSTR str)
Definition: odbccp32.c:100
static int num_errors
Definition: odbccp32.c:52
static UWORD config_mode
Definition: odbccp32.c:46
#define success(from, fromstr, to, tostr)
#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
Definition: winbase.h:346
#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
Definition: winbase.h:350
_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
#define RRF_RT_DWORD
Definition: winreg.h:64
#define RRF_RT_REG_SZ
Definition: winreg.h:58
unsigned char BYTE
Definition: xxhash.c:193