ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

odbccp32.c
Go to the documentation of this file.
00001 /*
00002  * Implementation of the ODBC driver installer
00003  *
00004  * Copyright 2005 Mike McCormack for CodeWeavers
00005  * Copyright 2005 Hans Leidekker
00006  * Copyright 2007 Bill Medland
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 #include <assert.h>
00024 #include <stdarg.h>
00025 
00026 #define COBJMACROS
00027 #define NONAMELESSUNION
00028 
00029 #include "windef.h"
00030 #include "winbase.h"
00031 #include "winreg.h"
00032 #include "winnls.h"
00033 #include "wine/debug.h"
00034 
00035 #include "odbcinst.h"
00036 
00037 WINE_DEFAULT_DEBUG_CHANNEL(odbc);
00038 
00039 /* Registry key names */
00040 static const WCHAR drivers_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\','O','D','B','C',' ','D','r','i','v','e','r','s',0};
00041 
00042 /* This config mode is known to be process-wide.
00043  * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet.
00044  * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping.
00045  */
00046 static UWORD config_mode = ODBC_BOTH_DSN;
00047 
00048 /* MSDN documentation suggests that the error subsystem handles errors 1 to 8
00049  * only and experimentation (Windows 2000) shows that the errors are process-
00050  * wide so go for the simple solution; static arrays.
00051  */
00052 static int num_errors;
00053 static int error_code[8];
00054 static const WCHAR *error_msg[8];
00055 static const WCHAR odbc_error_general_err[] = {'G','e','n','e','r','a','l',' ','e','r','r','o','r',0};
00056 static const WCHAR odbc_error_invalid_buff_len[] = {'I','n','v','a','l','i','d',' ','b','u','f','f','e','r',' ','l','e','n','g','t','h',0};
00057 static const WCHAR odbc_error_component_not_found[] = {'C','o','m','p','o','n','e','n','t',' ','n','o','t',' ','f','o','u','n','d',0};
00058 static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0};
00059 static const WCHAR odbc_error_invalid_param_sequence[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','e','q','u','e','n','c','e',0};
00060 
00061 /* Push an error onto the error stack, taking care of ranges etc. */
00062 static void push_error(int code, LPCWSTR msg)
00063 {
00064     if (num_errors < sizeof error_code/sizeof error_code[0])
00065     {
00066         error_code[num_errors] = code;
00067         error_msg[num_errors] = msg;
00068         num_errors++;
00069     }
00070 }
00071 
00072 /* Clear the error stack */
00073 static void clear_errors(void)
00074 {
00075     num_errors = 0;
00076 }
00077 
00078 BOOL WINAPI ODBCCPlApplet( LONG i, LONG j, LONG * p1, LONG * p2)
00079 {
00080     clear_errors();
00081     FIXME( "( %d %d %p %p) : stub!\n", i, j, p1, p2);
00082     return FALSE;
00083 }
00084 
00085 static LPWSTR SQLInstall_strdup_multi(LPCSTR str)
00086 {
00087     LPCSTR p;
00088     LPWSTR ret = NULL;
00089     DWORD len;
00090 
00091     if (!str)
00092         return ret;
00093 
00094     for (p = str; *p; p += lstrlenA(p) + 1)
00095         ;
00096 
00097     len = MultiByteToWideChar(CP_ACP, 0, str, p - str, NULL, 0 );
00098     ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
00099     MultiByteToWideChar(CP_ACP, 0, str, p - str, ret, len );
00100     ret[len] = 0;
00101 
00102     return ret;
00103 }
00104 
00105 static LPWSTR SQLInstall_strdup(LPCSTR str)
00106 {
00107     DWORD len;
00108     LPWSTR ret = NULL;
00109 
00110     if (!str)
00111         return ret;
00112 
00113     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0 );
00114     ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
00115     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len );
00116 
00117     return ret;
00118 }
00119 
00120 /* Convert the wide string or zero-length-terminated list of wide strings to a
00121  * narrow string or zero-length-terminated list of narrow strings.
00122  * Do not try to emulate windows undocumented excesses (e.g. adding a third \0
00123  * to a list)
00124  * Arguments
00125  *   mode Indicates the sort of string.
00126  *     1 denotes that the buffers contain strings terminated by a single nul
00127  *       character
00128  *     2 denotes that the buffers contain zero-length-terminated lists
00129  *       (frequently erroneously referred to as double-null-terminated)
00130  *   buffer The narrow-character buffer into which to place the result.  This
00131  *          must be a non-null pointer to the first element of a buffer whose
00132  *          length is passed in buffer_length.
00133  *   str The wide-character buffer containing the string or list of strings to
00134  *       be converted.  str_length defines how many wide characters in the
00135  *       buffer are to be converted, including all desired terminating nul
00136  *       characters.
00137  *   str_length Effective length of str
00138  *   buffer_length Length of buffer
00139  *   returned_length A pointer to a variable that will receive the number of
00140  *                   narrow characters placed into the buffer.  This pointer
00141  *                   may be NULL.
00142  */
00143 static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_length, WORD buffer_length, WORD *returned_length)
00144 {
00145     LPSTR pbuf; /* allows us to allocate a temporary buffer only if needed */
00146     int len; /* Length of the converted list */
00147     BOOL success = FALSE;
00148     assert(mode == 1 || mode == 2);
00149     assert(buffer_length);
00150     len = WideCharToMultiByte(CP_ACP, 0, str, str_length, 0, 0, NULL, NULL);
00151     if (len > 0)
00152     {
00153         if (len > buffer_length)
00154         {
00155             pbuf = HeapAlloc(GetProcessHeap(), 0, len);
00156         }
00157         else
00158         {
00159             pbuf = buffer;
00160         }
00161         len = WideCharToMultiByte(CP_ACP, 0, str, str_length, pbuf, len, NULL, NULL);
00162         if (len > 0)
00163         {
00164             if (pbuf != buffer)
00165             {
00166                 if (buffer_length > (mode - 1))
00167                 {
00168                     memcpy (buffer, pbuf, buffer_length-mode);
00169                     *(buffer+buffer_length-mode) = '\0';
00170                 }
00171                 *(buffer+buffer_length-1) = '\0';
00172             }
00173             if (returned_length)
00174             {
00175                 *returned_length = pbuf == buffer ? len : buffer_length;
00176             }
00177             success = TRUE;
00178         }
00179         else
00180         {
00181             ERR("transferring wide to narrow\n");
00182         }
00183         if (pbuf != buffer)
00184         {
00185             HeapFree(GetProcessHeap(), 0, pbuf);
00186         }
00187     }
00188     else
00189     {
00190         ERR("measuring wide to narrow\n");
00191     }
00192     return success;
00193 }
00194 
00195 BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest,
00196                LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
00197 {
00198     LPCWSTR p;
00199 
00200     clear_errors();
00201     FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_w(lpszDriver),
00202           debugstr_w(lpszAttributes));
00203 
00204     for (p = lpszAttributes; *p; p += lstrlenW(p) + 1)
00205         FIXME("%s\n", debugstr_w(p));
00206 
00207     return TRUE;
00208 }
00209 
00210 BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
00211                LPCSTR lpszDriver, LPCSTR lpszAttributes)
00212 {
00213     FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_a(lpszDriver),
00214           debugstr_a(lpszAttributes));
00215     clear_errors();
00216     return TRUE;
00217 }
00218 
00219 BOOL WINAPI SQLConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver,
00220                LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
00221 {
00222     clear_errors();
00223     FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_w(lpszDriver),
00224           debugstr_w(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
00225     return TRUE;
00226 }
00227 
00228 BOOL WINAPI SQLConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver,
00229                LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
00230 {
00231     clear_errors();
00232     FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_a(lpszDriver),
00233           debugstr_a(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
00234     return TRUE;
00235 }
00236 
00237 BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
00238 {
00239     clear_errors();
00240     FIXME("\n");
00241     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00242     return FALSE;
00243 }
00244 
00245 BOOL WINAPI SQLCreateDataSource(HWND hwnd, LPCSTR lpszDS)
00246 {
00247     clear_errors();
00248     FIXME("\n");
00249     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00250     return FALSE;
00251 }
00252 
00253 BOOL WINAPI SQLGetAvailableDriversW(LPCWSTR lpszInfFile, LPWSTR lpszBuf,
00254                WORD cbBufMax, WORD *pcbBufOut)
00255 {
00256     clear_errors();
00257     FIXME("\n");
00258     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00259     return FALSE;
00260 }
00261 
00262 BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf,
00263                WORD cbBufMax, WORD *pcbBufOut)
00264 {
00265     clear_errors();
00266     FIXME("\n");
00267     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00268     return FALSE;
00269 }
00270 
00271 BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode)
00272 {
00273     clear_errors();
00274     if (pwConfigMode)
00275         *pwConfigMode = config_mode;
00276     return TRUE;
00277 }
00278 
00279 /* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations
00280  * e.g. The Microsoft one occasionally actually adds a third nul character (possibly beyond the buffer).
00281  * e.g. If the key has no drivers then version 3.525.1117.0 does not modify the buffer at all, not even a nul character.
00282  */
00283 BOOL WINAPI SQLGetInstalledDriversW(LPWSTR lpszBuf, WORD cbBufMax,
00284                WORD *pcbBufOut)
00285 {
00286     HKEY hDrivers; /* Registry handle to the Drivers key */
00287     LONG reg_ret; /* Return code from registry functions */
00288     BOOL success = FALSE; /* The value we will return */
00289 
00290     clear_errors();
00291     if (!lpszBuf || cbBufMax == 0)
00292     {
00293         push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len);
00294     }
00295     else if ((reg_ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE /* The drivers does not depend on the config mode */,
00296             drivers_key, 0, KEY_READ /* Maybe overkill */,
00297             &hDrivers)) == ERROR_SUCCESS)
00298     {
00299         DWORD index = 0;
00300         cbBufMax--;
00301         success = TRUE;
00302         while (cbBufMax > 0)
00303         {
00304             DWORD size_name;
00305             size_name = cbBufMax;
00306             if ((reg_ret = RegEnumValueW(hDrivers, index, lpszBuf, &size_name, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
00307             {
00308                 index++;
00309                 assert (size_name < cbBufMax && *(lpszBuf + size_name) == 0);
00310                 size_name++;
00311                 cbBufMax-= size_name;
00312                 lpszBuf+=size_name;
00313             }
00314             else
00315             {
00316                 if (reg_ret != ERROR_NO_MORE_ITEMS)
00317                 {
00318                     success = FALSE;
00319                     push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
00320                 }
00321                 break;
00322             }
00323         }
00324         *lpszBuf = 0;
00325         if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS)
00326             TRACE ("Error %d closing ODBC Drivers key\n", reg_ret);
00327     }
00328     else
00329     {
00330         /* MSDN states that it returns failure with COMPONENT_NOT_FOUND in this case.
00331          * Version 3.525.1117.0 (Windows 2000) does not; it actually returns success.
00332          * I doubt if it will actually be an issue.
00333          */
00334         push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found);
00335     }
00336     return success;
00337 }
00338 
00339 BOOL WINAPI SQLGetInstalledDrivers(LPSTR lpszBuf, WORD cbBufMax,
00340                WORD *pcbBufOut)
00341 {
00342     BOOL ret;
00343     int size_wbuf = cbBufMax;
00344     LPWSTR wbuf;
00345     WORD size_used;
00346     wbuf = HeapAlloc(GetProcessHeap(), 0, size_wbuf*sizeof(WCHAR));
00347     if (wbuf)
00348     {
00349         ret = SQLGetInstalledDriversW(wbuf, size_wbuf, &size_used);
00350         if (ret)
00351         {
00352             if (!(ret = SQLInstall_narrow(2, lpszBuf, wbuf, size_used, cbBufMax, pcbBufOut)))
00353             {
00354                 push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err);
00355             }
00356         }
00357         HeapFree(GetProcessHeap(), 0, wbuf);
00358         /* ignore failure; we have achieved the aim */
00359     }
00360     else
00361     {
00362         push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
00363         ret = FALSE;
00364     }
00365     return ret;
00366 }
00367 
00368 int WINAPI SQLGetPrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry,
00369                LPCWSTR lpszDefault, LPCWSTR RetBuffer, int cbRetBuffer,
00370                LPCWSTR lpszFilename)
00371 {
00372     clear_errors();
00373     FIXME("\n");
00374     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00375     return FALSE;
00376 }
00377 
00378 int WINAPI SQLGetPrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry,
00379                LPCSTR lpszDefault, LPCSTR RetBuffer, int cbRetBuffer,
00380                LPCSTR lpszFilename)
00381 {
00382     clear_errors();
00383     FIXME("\n");
00384     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00385     return FALSE;
00386 }
00387 
00388 BOOL WINAPI SQLGetTranslatorW(HWND hwndParent, LPWSTR lpszName, WORD cbNameMax,
00389                WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax,
00390                WORD *pcbPathOut, DWORD *pvOption)
00391 {
00392     clear_errors();
00393     FIXME("\n");
00394     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00395     return FALSE;
00396 }
00397 
00398 BOOL WINAPI SQLGetTranslator(HWND hwndParent, LPSTR lpszName, WORD cbNameMax,
00399                WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax,
00400                WORD *pcbPathOut, DWORD *pvOption)
00401 {
00402     clear_errors();
00403     FIXME("\n");
00404     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00405     return FALSE;
00406 }
00407 
00408 BOOL WINAPI SQLInstallDriverW(LPCWSTR lpszInfFile, LPCWSTR lpszDriver,
00409                LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
00410 {
00411     DWORD usage;
00412 
00413     clear_errors();
00414     TRACE("%s %s %p %d %p\n", debugstr_w(lpszInfFile),
00415           debugstr_w(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
00416 
00417     if (lpszInfFile)
00418         return FALSE;
00419 
00420     return SQLInstallDriverExW(lpszDriver, NULL, lpszPath, cbPathMax,
00421                                pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
00422 }
00423 
00424 BOOL WINAPI SQLInstallDriver(LPCSTR lpszInfFile, LPCSTR lpszDriver,
00425                LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut)
00426 {
00427     DWORD usage;
00428 
00429     clear_errors();
00430     TRACE("%s %s %p %d %p\n", debugstr_a(lpszInfFile),
00431           debugstr_a(lpszDriver), lpszPath, cbPathMax, pcbPathOut);
00432 
00433     if (lpszInfFile)
00434         return FALSE;
00435    
00436     return SQLInstallDriverEx(lpszDriver, NULL, lpszPath, cbPathMax,
00437                               pcbPathOut, ODBC_INSTALL_COMPLETE, &usage);
00438 }
00439 
00440 BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn,
00441                LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
00442                WORD fRequest, LPDWORD lpdwUsageCount)
00443 {
00444     UINT len;
00445     LPCWSTR p;
00446     WCHAR path[MAX_PATH];
00447 
00448     clear_errors();
00449     TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszDriver),
00450           debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
00451           fRequest, lpdwUsageCount);
00452 
00453     for (p = lpszDriver; *p; p += lstrlenW(p) + 1)
00454         TRACE("%s\n", debugstr_w(p));
00455 
00456     len = GetSystemDirectoryW(path, MAX_PATH);
00457 
00458     if (pcbPathOut)
00459         *pcbPathOut = len;
00460 
00461     len = GetSystemDirectoryW(path, MAX_PATH);
00462 
00463     if (lpszPathOut && cbPathOutMax > len)
00464     {
00465         lstrcpyW(lpszPathOut, path);
00466         return TRUE;
00467     }
00468     return FALSE;
00469 }
00470 
00471 BOOL WINAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn,
00472                LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
00473                WORD fRequest, LPDWORD lpdwUsageCount)
00474 {
00475     LPCSTR p;
00476     LPWSTR driver, pathin;
00477     WCHAR pathout[MAX_PATH];
00478     BOOL ret;
00479     WORD cbOut = 0;
00480 
00481     clear_errors();
00482     TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszDriver),
00483           debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
00484           fRequest, lpdwUsageCount);
00485 
00486     for (p = lpszDriver; *p; p += lstrlenA(p) + 1)
00487         TRACE("%s\n", debugstr_a(p));
00488 
00489     driver = SQLInstall_strdup_multi(lpszDriver);
00490     pathin = SQLInstall_strdup(lpszPathIn);
00491 
00492     ret = SQLInstallDriverExW(driver, pathin, pathout, MAX_PATH, &cbOut,
00493                               fRequest, lpdwUsageCount);
00494     if (ret)
00495     {
00496         int len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
00497                                        0, NULL, NULL);
00498         if (len)
00499         {
00500             if (pcbPathOut)
00501                 *pcbPathOut = len - 1;
00502 
00503             if (!lpszPathOut || cbPathOutMax < len)
00504             {
00505                 ret = FALSE;
00506                 goto out;
00507             }
00508             len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
00509                                        cbPathOutMax, NULL, NULL);
00510         }
00511     }
00512 
00513 out:
00514     HeapFree(GetProcessHeap(), 0, driver);
00515     HeapFree(GetProcessHeap(), 0, pathin);
00516     return ret;
00517 }
00518 
00519 BOOL WINAPI SQLInstallDriverManagerW(LPWSTR lpszPath, WORD cbPathMax,
00520                WORD *pcbPathOut)
00521 {
00522     UINT len;
00523     WCHAR path[MAX_PATH];
00524 
00525     TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
00526 
00527     if (cbPathMax < MAX_PATH)
00528         return FALSE;
00529 
00530     clear_errors();
00531 
00532     len = GetSystemDirectoryW(path, MAX_PATH);
00533 
00534     if (pcbPathOut)
00535         *pcbPathOut = len;
00536 
00537     if (lpszPath && cbPathMax > len)
00538     {
00539         lstrcpyW(lpszPath, path);
00540         return TRUE;
00541     }
00542     return FALSE;
00543 }
00544 
00545 BOOL WINAPI SQLInstallDriverManager(LPSTR lpszPath, WORD cbPathMax,
00546                WORD *pcbPathOut)
00547 {
00548     BOOL ret;
00549     WORD len, cbOut = 0;
00550     WCHAR path[MAX_PATH];
00551 
00552     TRACE("(%p %d %p)\n", lpszPath, cbPathMax, pcbPathOut);
00553 
00554     if (cbPathMax < MAX_PATH)
00555         return FALSE;
00556 
00557     clear_errors();
00558 
00559     ret = SQLInstallDriverManagerW(path, MAX_PATH, &cbOut);
00560     if (ret)
00561     {
00562         len =  WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath, 0,
00563                                    NULL, NULL);
00564         if (len)
00565         {
00566             if (pcbPathOut)
00567                 *pcbPathOut = len - 1;
00568 
00569             if (!lpszPath || cbPathMax < len)
00570                 return FALSE;
00571 
00572             len =  WideCharToMultiByte(CP_ACP, 0, path, -1, lpszPath,
00573                                        cbPathMax, NULL, NULL);
00574         }
00575     }
00576     return ret;
00577 }
00578 
00579 BOOL WINAPI SQLInstallODBCW(HWND hwndParent, LPCWSTR lpszInfFile,
00580                LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers)
00581 {
00582     clear_errors();
00583     FIXME("\n");
00584     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00585     return FALSE;
00586 }
00587 
00588 BOOL WINAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile,
00589                LPCSTR lpszSrcPath, LPCSTR lpszDrivers)
00590 {
00591     clear_errors();
00592     FIXME("\n");
00593     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00594     return FALSE;
00595 }
00596 
00597 SQLRETURN WINAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode,
00598                LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
00599 {
00600     TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
00601           cbErrorMsgMax, pcbErrorMsg);
00602 
00603     if (iError == 0)
00604     {
00605         return SQL_ERROR;
00606     }
00607     else if (iError <= num_errors)
00608     {
00609         BOOL truncated = FALSE;
00610         WORD len;
00611         LPCWSTR msg;
00612         iError--;
00613         if (pfErrorCode)
00614             *pfErrorCode = error_code[iError];
00615         msg = error_msg[iError];
00616         len = msg ? lstrlenW(msg) : 0;
00617         if (pcbErrorMsg)
00618             *pcbErrorMsg = len;
00619         len++;
00620         if (cbErrorMsgMax < len)
00621         {
00622             len = cbErrorMsgMax;
00623             truncated = TRUE;
00624         }
00625         if (lpszErrorMsg && len)
00626         {
00627             if (msg)
00628             {
00629                 memcpy (lpszErrorMsg, msg, len * sizeof(WCHAR));
00630             }
00631             else
00632             {
00633                 assert(len==1);
00634                 *lpszErrorMsg = 0;
00635             }
00636         }
00637         else
00638         {
00639             /* Yes.  If you pass a null pointer and a large length it is not an error! */
00640             truncated = TRUE;
00641         }
00642 
00643         return truncated ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
00644     }
00645 
00646     /* 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 */
00647     if (pcbErrorMsg)
00648         *pcbErrorMsg = 0;
00649 
00650     if (lpszErrorMsg && cbErrorMsgMax > 0)
00651         *lpszErrorMsg = '\0';
00652 
00653     return SQL_NO_DATA;
00654 }
00655 
00656 SQLRETURN WINAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode,
00657                LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg)
00658 {
00659     SQLRETURN ret;
00660     LPWSTR wbuf;
00661     WORD cbwbuf;
00662     TRACE("%d %p %p %d %p\n", iError, pfErrorCode, lpszErrorMsg,
00663           cbErrorMsgMax, pcbErrorMsg);
00664 
00665     wbuf = 0;
00666     if (lpszErrorMsg && cbErrorMsgMax)
00667     {
00668         wbuf = HeapAlloc(GetProcessHeap(), 0, cbErrorMsgMax*sizeof(WCHAR));
00669         if (!wbuf)
00670             return SQL_ERROR;
00671     }
00672     ret = SQLInstallerErrorW(iError, pfErrorCode, wbuf, cbErrorMsgMax, &cbwbuf);
00673     if (wbuf)
00674     {
00675         WORD cbBuf = 0;
00676         SQLInstall_narrow(1, lpszErrorMsg, wbuf, cbwbuf+1, cbErrorMsgMax, &cbBuf);
00677         HeapFree(GetProcessHeap(), 0, wbuf);
00678         if (pcbErrorMsg)
00679             *pcbErrorMsg = cbBuf-1;
00680     }
00681     return ret;
00682 }
00683 
00684 BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn,
00685                LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
00686                WORD fRequest, LPDWORD lpdwUsageCount)
00687 {
00688     UINT len;
00689     LPCWSTR p;
00690     WCHAR path[MAX_PATH];
00691 
00692     clear_errors();
00693     TRACE("%s %s %p %d %p %d %p\n", debugstr_w(lpszTranslator),
00694           debugstr_w(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
00695           fRequest, lpdwUsageCount);
00696 
00697     for (p = lpszTranslator; *p; p += lstrlenW(p) + 1)
00698         TRACE("%s\n", debugstr_w(p));
00699 
00700     len = GetSystemDirectoryW(path, MAX_PATH);
00701 
00702     if (pcbPathOut)
00703         *pcbPathOut = len;
00704 
00705     if (lpszPathOut && cbPathOutMax > len)
00706     {
00707         lstrcpyW(lpszPathOut, path);
00708         return TRUE;
00709     }
00710     return FALSE;
00711 }
00712 
00713 BOOL WINAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn,
00714                LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut,
00715                WORD fRequest, LPDWORD lpdwUsageCount)
00716 {
00717     LPCSTR p;
00718     LPWSTR translator, pathin;
00719     WCHAR pathout[MAX_PATH];
00720     BOOL ret;
00721     WORD cbOut = 0;
00722 
00723     clear_errors();
00724     TRACE("%s %s %p %d %p %d %p\n", debugstr_a(lpszTranslator),
00725           debugstr_a(lpszPathIn), lpszPathOut, cbPathOutMax, pcbPathOut,
00726           fRequest, lpdwUsageCount);
00727 
00728     for (p = lpszTranslator; *p; p += lstrlenA(p) + 1)
00729         TRACE("%s\n", debugstr_a(p));
00730 
00731     translator = SQLInstall_strdup_multi(lpszTranslator);
00732     pathin = SQLInstall_strdup(lpszPathIn);
00733 
00734     ret = SQLInstallTranslatorExW(translator, pathin, pathout, MAX_PATH,
00735                                   &cbOut, fRequest, lpdwUsageCount);
00736     if (ret)
00737     {
00738         int len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
00739                                        0, NULL, NULL);
00740         if (len)
00741         {
00742             if (pcbPathOut)
00743                 *pcbPathOut = len - 1;
00744 
00745             if (!lpszPathOut || cbPathOutMax < len)
00746             {
00747                 ret = FALSE;
00748                 goto out;
00749             }
00750             len =  WideCharToMultiByte(CP_ACP, 0, pathout, -1, lpszPathOut,
00751                                        cbPathOutMax, NULL, NULL);
00752         }
00753     }
00754 
00755 out:
00756     HeapFree(GetProcessHeap(), 0, translator);
00757     HeapFree(GetProcessHeap(), 0, pathin);
00758     return ret;
00759 }
00760 
00761 BOOL WINAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator,
00762                LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax,
00763                WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
00764 {
00765     clear_errors();
00766     TRACE("%s %s %s %p %d %p %d %p\n", debugstr_a(lpszInfFile),
00767           debugstr_a(lpszTranslator), debugstr_a(lpszPathIn), lpszPathOut,
00768           cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
00769 
00770     if (lpszInfFile)
00771         return FALSE;
00772 
00773     return SQLInstallTranslatorEx(lpszTranslator, lpszPathIn, lpszPathOut,
00774                        cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
00775 }
00776 
00777 BOOL WINAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator,
00778               LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax,
00779               WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
00780 {
00781     clear_errors();
00782     TRACE("%s %s %s %p %d %p %d %p\n", debugstr_w(lpszInfFile),
00783           debugstr_w(lpszTranslator), debugstr_w(lpszPathIn), lpszPathOut,
00784           cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
00785 
00786     if (lpszInfFile)
00787         return FALSE;
00788 
00789     return SQLInstallTranslatorExW(lpszTranslator, lpszPathIn, lpszPathOut,
00790                         cbPathOutMax, pcbPathOut, fRequest, lpdwUsageCount);
00791 }
00792 
00793 BOOL WINAPI SQLManageDataSources(HWND hwnd)
00794 {
00795     clear_errors();
00796     FIXME("\n");
00797     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00798     return FALSE;
00799 }
00800 
00801 SQLRETURN WINAPI SQLPostInstallerErrorW(DWORD fErrorCode, LPCWSTR szErrorMsg)
00802 {
00803     FIXME("\n");
00804     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00805     return FALSE;
00806 }
00807 
00808 SQLRETURN WINAPI SQLPostInstallerError(DWORD fErrorCode, LPCSTR szErrorMsg)
00809 {
00810     FIXME("\n");
00811     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00812     return FALSE;
00813 }
00814 
00815 BOOL WINAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
00816                LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString,
00817                WORD *pcbString)
00818 {
00819     clear_errors();
00820     FIXME("\n");
00821     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00822     return FALSE;
00823 }
00824 
00825 BOOL WINAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
00826                LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString,
00827                WORD *pcbString)
00828 {
00829     clear_errors();
00830     FIXME("\n");
00831     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00832     return FALSE;
00833 }
00834 
00835 BOOL WINAPI SQLRemoveDefaultDataSource(void)
00836 {
00837     clear_errors();
00838     FIXME("\n");
00839     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00840     return FALSE;
00841 }
00842 
00843 BOOL WINAPI SQLRemoveDriverW(LPCWSTR lpszDriver, BOOL fRemoveDSN,
00844                LPDWORD lpdwUsageCount)
00845 {
00846     clear_errors();
00847     FIXME("stub\n");
00848     if (lpdwUsageCount) *lpdwUsageCount = 1;
00849     return TRUE;
00850 }
00851 
00852 BOOL WINAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN,
00853                LPDWORD lpdwUsageCount)
00854 {
00855     clear_errors();
00856     FIXME("stub\n");
00857     if (lpdwUsageCount) *lpdwUsageCount = 1;
00858     return TRUE;
00859 }
00860 
00861 BOOL WINAPI SQLRemoveDriverManager(LPDWORD pdwUsageCount)
00862 {
00863     clear_errors();
00864     FIXME("stub\n");
00865     if (pdwUsageCount) *pdwUsageCount = 1;
00866     return TRUE;
00867 }
00868 
00869 BOOL WINAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN)
00870 {
00871     clear_errors();
00872     FIXME("\n");
00873     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00874     return FALSE;
00875 }
00876 
00877 BOOL WINAPI SQLRemoveDSNFromIni(LPCSTR lpszDSN)
00878 {
00879     clear_errors();
00880     FIXME("\n");
00881     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00882     return FALSE;
00883 }
00884 
00885 BOOL WINAPI SQLRemoveTranslatorW(LPCWSTR lpszTranslator, LPDWORD lpdwUsageCount)
00886 {
00887     clear_errors();
00888     FIXME("\n");
00889     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00890     return FALSE;
00891 }
00892 
00893 BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount)
00894 {
00895     clear_errors();
00896     FIXME("\n");
00897     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00898     return FALSE;
00899 }
00900 
00901 BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode)
00902 {
00903     clear_errors();
00904     if (wConfigMode > ODBC_SYSTEM_DSN)
00905     {
00906         push_error(ODBC_ERROR_INVALID_PARAM_SEQUENCE, odbc_error_invalid_param_sequence);
00907         return FALSE;
00908     }
00909     else
00910     {
00911         config_mode = wConfigMode;
00912         return TRUE;
00913     }
00914 }
00915 
00916 BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN)
00917 {
00918     clear_errors();
00919     FIXME("\n");
00920     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00921     return FALSE;
00922 }
00923 
00924 BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
00925 {
00926     clear_errors();
00927     FIXME("\n");
00928     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00929     return FALSE;
00930 }
00931 
00932 BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
00933 {
00934     clear_errors();
00935     FIXME("\n");
00936     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00937     return FALSE;
00938 }
00939 
00940 BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
00941 {
00942     clear_errors();
00943     FIXME("\n");
00944     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00945     return FALSE;
00946 }
00947 
00948 BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
00949                LPCWSTR lpszKeyName, LPCWSTR lpszString)
00950 {
00951     clear_errors();
00952     FIXME("\n");
00953     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00954     return FALSE;
00955 }
00956 
00957 BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName,
00958                LPCSTR lpszKeyName, LPCSTR lpszString)
00959 {
00960     clear_errors();
00961     FIXME("\n");
00962     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00963     return FALSE;
00964 }
00965 
00966 BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry,
00967                LPCWSTR lpszString, LPCWSTR lpszFilename)
00968 {
00969     clear_errors();
00970     FIXME("\n");
00971     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00972     return FALSE;
00973 }
00974 
00975 BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry,
00976                LPCSTR lpszString, LPCSTR lpszFilename)
00977 {
00978     clear_errors();
00979     FIXME("\n");
00980     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00981     return FALSE;
00982 }

Generated on Sat May 26 2012 04:19:46 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.