merged core_conn from linux to Windows

This commit is contained in:
Hadis Kakanejadi Fard 2017-01-19 13:00:41 -08:00
parent dcc4ff2d11
commit 0d3b475277

View file

@ -20,13 +20,20 @@
#include "core_sqlsrv.h"
#include <php.h>
#ifdef _WIN32
#include <psapi.h>
#include <windows.h>
#include <winver.h>
#endif
#include <string>
#include <sstream>
#ifdef __linux__
#include <sys/utsname.h>
#endif
// *** internal variables and constants ***
namespace {
@ -91,7 +98,7 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
std::string conn_str;
conn_str.reserve( DEFAULT_CONN_STR_LEN );
sqlsrv_malloc_auto_ptr<sqlsrv_conn> conn;
sqlsrv_malloc_auto_ptr<wchar_t> wconn_string;
sqlsrv_malloc_auto_ptr<SQLWCHAR> wconn_string;
unsigned int wconn_len = 0;
try {
@ -105,7 +112,6 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
zval* option_z = NULL;
int zr = SUCCESS;
option_z = zend_hash_index_find(options_ht, SQLSRV_CONN_OPTION_CONN_POOLING);
if (option_z) {
@ -126,28 +132,27 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
for ( std::size_t i = DRIVER_VERSION::MIN; i <= DRIVER_VERSION::MAX; ++i ) {
conn_str = CONNECTION_STRING_DRIVER_NAME[i];
build_connection_string_and_set_conn_attr( conn, server, uid, pwd, options_ht, valid_conn_opts, driver,
conn_str TSRMLS_CC );
build_connection_string_and_set_conn_attr( conn, server, uid, pwd, options_ht, valid_conn_opts, driver, conn_str TSRMLS_CC );
// We only support UTF-8 encoding for connection string.
// Convert our UTF-8 connection string to UTF-16 before connecting with SQLDriverConnnectW
wconn_len = static_cast<unsigned int>( conn_str.length() + 1 ) * sizeof( wchar_t );
wconn_string = utf16_string_from_mbcs_string(SQLSRV_ENCODING_UTF8, conn_str.c_str(), static_cast<unsigned int>(conn_str.length()), &wconn_len);
CHECK_CUSTOM_ERROR( wconn_string == NULL, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE, get_last_error_message())
{
throw core::CoreException();
}
SQLSMALLINT output_conn_size;
r = SQLDriverConnectW( conn->handle(), NULL, reinterpret_cast<SQLWCHAR*>( wconn_string.get()),
static_cast<SQLSMALLINT>( wconn_len ), NULL,
0, &output_conn_size, SQL_DRIVER_NOPROMPT );
// clear the connection string from memory to remove sensitive data (such as a password).
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( wchar_t )); // wconn_len is the number of characters, not bytes
conn_str.clear();
wconn_len = static_cast<unsigned int>( conn_str.length() + 1 ) * sizeof( SQLWCHAR );
wconn_string = utf16_string_from_mbcs_string( SQLSRV_ENCODING_UTF8, conn_str.c_str(), static_cast<unsigned int>( conn_str.length() ), &wconn_len );
CHECK_CUSTOM_ERROR( wconn_string == 0, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE, get_last_error_message() )
{
throw core::CoreException();
}
SQLSMALLINT output_conn_size;
r = SQLDriverConnectW( conn->handle(), NULL, reinterpret_cast<SQLWCHAR*>( wconn_string.get() ),
static_cast<SQLSMALLINT>( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT );
// clear the connection string from memory to remove sensitive data (such as a password).
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
conn_str.clear();
if( !SQL_SUCCEEDED( r )) {
SQLCHAR state[SQL_SQLSTATE_BUFSIZE];
SQLSMALLINT len;
@ -182,27 +187,27 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
}
catch( std::bad_alloc& ) {
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( wchar_t )); // wconn_len is the number of characters, not bytes
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
conn->invalidate();
DIE( "C++ memory allocation failure building the connection string." );
}
catch( std::out_of_range const& ex ) {
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( wchar_t )); // wconn_len is the number of characters, not bytes
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
conn->invalidate();
throw;
}
catch( std::length_error const& ex ) {
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( wchar_t )); // wconn_len is the number of characters, not bytes
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
conn->invalidate();
throw;
}
catch( core::CoreException& ) {
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( wchar_t )); // wconn_len is the number of characters, not bytes
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
conn->invalidate();
throw;
}
@ -336,10 +341,10 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
// convert the string from its encoding to UTf-16
// if the string is empty, we initialize the fields and skip since an empty string is a
// failure case for utf16_string_from_mbcs_string
sqlsrv_malloc_auto_ptr<wchar_t> wsql_string;
sqlsrv_malloc_auto_ptr<SQLWCHAR> wsql_string;
unsigned int wsql_len = 0;
if( sql_len == 0 || ( sql[0] == '\0' && sql_len == 1 )) {
wsql_string = reinterpret_cast<wchar_t*>( sqlsrv_malloc( sizeof( wchar_t )));
wsql_string = reinterpret_cast<SQLWCHAR*>( sqlsrv_malloc( sizeof( SQLWCHAR )));
wsql_string[0] = L'\0';
wsql_len = 0;
}
@ -355,7 +360,7 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
stmt->encoding() );
wsql_string = utf16_string_from_mbcs_string( encoding, reinterpret_cast<const char*>( sql ),
static_cast<int>( sql_len ), &wsql_len );
CHECK_CUSTOM_ERROR( wsql_string == NULL, stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
CHECK_CUSTOM_ERROR( wsql_string == 0, stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
get_last_error_message() ) {
throw core::CoreException();
}
@ -385,10 +390,10 @@ void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_versi
SQLSMALLINT buffer_len = 0;
get_server_version( conn, &buffer, buffer_len TSRMLS_CC );
core::sqlsrv_zval_stringl( server_version, buffer, buffer_len );
if (NULL != buffer) {
sqlsrv_free( buffer );
}
core::sqlsrv_zval_stringl( server_version, buffer, buffer_len );
if ( buffer != 0 ) {
sqlsrv_free( buffer );
}
buffer.transferred();
}
@ -456,7 +461,11 @@ void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSR
// Get the ODBC driver's dll name
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
core::SQLGetInfo( conn, SQL_DRIVER_NAME, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC );
#if defined (__linux__) || defined(__MACH__)
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverName", buffer, 0 /*duplicate*/ TSRMLS_CC );
#else
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverDllName", buffer, 0 /*duplicate*/ TSRMLS_CC );
#endif
buffer.transferred();
// Get the ODBC driver's ODBC version
@ -536,10 +545,8 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
HashTable* options, const connection_option valid_conn_opts[],
void* driver,_Inout_ std::string& connection_string TSRMLS_DC )
{
bool credentials_mentioned = false;
bool mars_mentioned = false;
connection_option const* conn_opt;
int zr = SUCCESS;
try {
@ -654,6 +661,23 @@ void get_server_version( sqlsrv_conn* conn, char** server_version, SQLSMALLINT&
// and return the string of the processor name.
const char* get_processor_arch( void )
{
#ifdef __linux__
struct utsname sys_info;
if ( uname(&sys_info) == -1 )
{
DIE( "Error retrieving system info" );
}
if( strcmp(sys_info.machine, "x86") ) {
return PROCESSOR_ARCH[0];
} else if ( strcmp(sys_info.machine, "x86_64") ) {
return PROCESSOR_ARCH[1];
} else if ( strcmp(sys_info.machine, "ia64") ) {
return PROCESSOR_ARCH[2];
} else {
DIE( "Unknown processor architecture." );
}
return NULL;
#else
SYSTEM_INFO sys_info;
GetSystemInfo( &sys_info);
switch( sys_info.wProcessorArchitecture ) {
@ -671,6 +695,8 @@ const char* get_processor_arch( void )
DIE( "Unknown Windows processor architecture." );
return NULL;
}
return NULL;
#endif
}
@ -690,6 +716,7 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC )
char version_major_str[ 3 ];
SERVER_VERSION version_major;
memcpy_s( version_major_str, sizeof( version_major_str ), p, 2 );
version_major_str[ 2 ] = '\0';
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));