Added source and binaries for the latest release

This commit is contained in:
Meet Bhagdev 2016-07-06 11:47:05 -07:00
parent ca435f6e62
commit 5ddaaeb728
35 changed files with 1312 additions and 1352 deletions

View file

@ -1,16 +1,27 @@
# Microsoft Drivers for PHP for SQL Server
**Welcome to the Microsoft Drivers for PHP for SQL Server PHP 7 (Release Candidate)**
**Welcome to the Microsoft Drivers for PHP for SQL Server PHP 7**
The Microsoft Drivers for PHP for SQL Server are PHP extensions that allow for the reading and writing of SQL Server data from within PHP scripts. The SQLSRV extension provides a procedural interface while the PDO_SQLSRV extension implements PDO for accessing data in all editions of SQL Server 2005 and later (including Azure SQL DB). These drivers rely on the Microsoft ODBC Driver for SQL Server to handle the low-level communication with SQL Server.
This preview contains the SQLSRV and PDO_SQLSRV drivers for PHP 7 with improvements on both drivers and some limitations (see Limitations below for details). Upcoming release(s) will contain more functionality, bug fixes, and more (see Plans below for more details).
This release contains the SQLSRV and PDO_SQLSRV drivers for PHP 7 with improvements on both drivers and some limitations (see Limitations below for details). Upcoming release(s) will contain more functionality, bug fixes, and more (see Plans below for more details).
The Microsoft Drivers for PHP for SQL Server Team
##Announcements
June 13, 2016 (4.0) Release Candidate: The quality of SQLSRV and PDO_SQLSRV is improved and includes some bug fixes:
June 30, 2016 (4.0.6): The quality of SQLSRV and PDO_SQLSRV is improved and includes some memory leak fixes:
- Fixed a heap corruption when binding parameters in a prepare statement with error
- Fixed leaks in SQLSRV streams and output parameters handling
- Fixed leaks in SQLSRV fetch object
- Fixed leaks in SQLSRV binding object parameters
- Fixed leaks in SQLSRV buffered result set
- Fixed leaks in SQLSRV getting datetime and stream fields
- Fixed leaks in PDO_SQLSRV field cache
- Fixed leaks in PDO_SQLSRV construct when connecting with error
- Fixed leaks in PDO_SQLSRV exception handling
June 13, 2016 (4.0.5): The quality of SQLSRV and PDO_SQLSRV is improved and includes some bug fixes:
- Added ability to connect to Microsoft ODBC Driver 13.
- Fixed some memory leaks in data retrieval.
- Fixed issue with error handling in bound stream parameters when send_stream_at_exec option is set to false.
@ -66,7 +77,7 @@ You must first be able to build PHP 7 without including these extensions. For h
5. To install the resulting build, run `nmake install` or just copy php_sqlsrv.dll and/or php_pdo_sqlsrv.dll to your PHP extension directory.
This software has been compiled and tested under PHP 7.0.7 using the Visual C++ 2015 compiler.
This software has been compiled and tested under PHP 7.0.8 using the Visual C++ 2015 compiler.
## Install
@ -122,7 +133,7 @@ Thank you!
**Q:** What's next?
**A:** On Jan 29, 2016 we released an early technical preview for our PHP Driver and several since. We will continue releasing frequent technical previews until we reach production quality.
**A:** On Jan 29, 2016 we released an early technical preview for our PHP Driver and several since. We will continue to release frequently to improve the quality of our driver.
**Q:** Is Microsoft taking pull requests for this project?
@ -159,3 +170,5 @@ The Microsoft Drivers for PHP for SQL Server are licensed under the MIT license.
[odbc13]: https://www.microsoft.com/en-us/download/details.aspx?id=50420
[phpazure]: https://azure.microsoft.com/en-us/documentation/articles/sql-database-develop-php-simple-windows/
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -57,7 +57,7 @@ const char CONNECTION_OPTION_MARS_ON[] = "MARS_Connection={Yes};";
void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* server, const char* uid, const char* pwd,
HashTable* options_ht, const connection_option valid_conn_opts[],
void* driver,__inout std::string& connection_string TSRMLS_DC );
void* driver,_Inout_ std::string& connection_string TSRMLS_DC );
void determine_server_version( sqlsrv_conn* conn TSRMLS_DC );
const char* get_processor_arch( void );
void get_server_version( sqlsrv_conn* conn, char** server_version, SQLSMALLINT& len TSRMLS_DC );
@ -377,7 +377,7 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
// conn - The connection resource by which the client and server are connected.
// *server_version - zval for returning results.
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, __out zval *server_version TSRMLS_DC )
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_version TSRMLS_DC )
{
try {
@ -404,7 +404,7 @@ void core_sqlsrv_get_server_version( sqlsrv_conn* conn, __out zval *server_versi
// conn - The connection resource by which the client and server are connected.
// *server_info - zval for returning results.
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, __out zval *server_info TSRMLS_DC )
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval *server_info TSRMLS_DC )
{
try {
@ -443,7 +443,7 @@ void core_sqlsrv_get_server_info( sqlsrv_conn* conn, __out zval *server_info TSR
// conn - The connection resource by which the client and server are connected.
// *client_info - zval for returning the results.
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, __out zval *client_info TSRMLS_DC )
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC )
{
try {
@ -534,7 +534,7 @@ connection_option const* get_connection_option( sqlsrv_conn* conn, SQLULEN key,
void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* server, const char* uid, const char* pwd,
HashTable* options, const connection_option valid_conn_opts[],
void* driver,__inout std::string& connection_string TSRMLS_DC )
void* driver,_Inout_ std::string& connection_string TSRMLS_DC )
{
bool credentials_mentioned = false;
bool mars_mentioned = false;
@ -689,7 +689,7 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC )
errno = 0;
char version_major_str[ 3 ];
SERVER_VERSION version_major;
memcpy( version_major_str, p, 2 );
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 ));

View file

@ -145,14 +145,14 @@ void core_sqlsrv_mshutdown( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp )
if( henv_ncp != SQL_NULL_HANDLE ) {
henv_ncp.invalidate();
delete &henv_ncp;
}
delete &henv_ncp;
if( henv_cp != SQL_NULL_HANDLE ) {
henv_cp.invalidate();
delete &henv_cp;
}
delete &henv_cp;
return;
}

View file

@ -85,7 +85,7 @@ void cache_row_dtor(zval* data);
// There is an extra copy here, but given the size is short (usually <20 bytes) and the complications of
// subclassing a new streambuf just to avoid the copy, it's easier to do the copy
template <typename Char, typename Number>
SQLRETURN number_to_string( Number* number_data, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
SQLRETURN number_to_string( Number* number_data, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
sqlsrv_error_auto_ptr& last_error )
{
std::basic_ostringstream<Char> os;
@ -107,14 +107,14 @@ SQLRETURN number_to_string( Number* number_data, __out void* buffer, SQLLEN buff
}
*out_buffer_length = str_num.size() * sizeof(Char) + sizeof(Char); // include NULL terminator
memcpy( buffer, str_num.c_str(), *out_buffer_length );
memcpy_s( buffer, buffer_length, str_num.c_str(), *out_buffer_length );
return SQL_SUCCESS;
}
template <typename Number, typename Char>
SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error )
SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error )
{
Number* number_data = reinterpret_cast<Number*>( buffer );
std::locale loc; // default locale should match system
@ -214,7 +214,7 @@ SQLRETURN sqlsrv_odbc_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset
}
SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ SQLPOINTER buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )
{
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
@ -222,8 +222,8 @@ SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLIN
}
SQLRETURN sqlsrv_odbc_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC )
{
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length,
@ -596,7 +596,7 @@ SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN off
}
SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ SQLPOINTER buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )
{
last_error = NULL;
@ -632,8 +632,8 @@ SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMA
}
SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC )
{
SQLSRV_ASSERT( record_number == 1, "Only record number 1 can be fetched by sqlsrv_buffered_result_set::get_diag_field" );
SQLSRV_ASSERT( diag_identifier == SQL_DIAG_SQLSTATE,
@ -648,7 +648,7 @@ SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number,
SQLSRV_ASSERT( last_error->sqlstate != NULL,
"Must have a SQLSTATE in a valid last_error in sqlsrv_buffered_result_set::get_diag_field" );
memcpy( diag_info_buffer, last_error->sqlstate, min( buffer_length, SQL_SQLSTATE_BUFSIZE ));
memcpy_s( diag_info_buffer, buffer_length, last_error->sqlstate, min( buffer_length, SQL_SQLSTATE_BUFSIZE ));
return SQL_SUCCESS;
}
@ -684,8 +684,8 @@ SQLLEN sqlsrv_buffered_result_set::row_count( TSRMLS_D )
// private functions
template <typename Char>
SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, __out void* buffer,
SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, _Out_ void* buffer,
SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
sqlsrv_error_auto_ptr& out_error )
{
// hex characters for the conversion loop below
@ -745,8 +745,8 @@ SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, __out voi
return r;
}
SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLCHAR* row = get_row();
SQLCHAR* field_data = NULL;
@ -763,8 +763,8 @@ SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field
return binary_to_string<char>( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLCHAR* row = get_row();
SQLCHAR* field_data = NULL;
@ -782,8 +782,8 @@ SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_i
}
SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to long" );
SQLSRV_ASSERT( buffer_length >= sizeof(SQLLEN), "Buffer length must be able to find a long in "
@ -811,8 +811,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, _
return SQL_SUCCESS;
}
SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to system string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_system_string" );
@ -823,8 +823,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field
return number_to_string<char>( double_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to wide string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_wide_string" );
@ -835,8 +835,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_i
return number_to_string<WCHAR>( double_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to long" );
SQLSRV_ASSERT( buffer_length >= sizeof(double), "Buffer length must be able to find a long in sqlsrv_buffered_result_set::double_to_long" );
@ -850,8 +850,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, _
return SQL_SUCCESS;
}
SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to system string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_system_string" );
@ -862,8 +862,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_i
return number_to_string<char>( long_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to wide string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_wide_string" );
@ -874,8 +874,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_ind
return number_to_string<WCHAR>( long_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to double" );
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
@ -886,8 +886,8 @@ SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index,
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to double" );
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
@ -898,8 +898,8 @@ SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to long" );
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
@ -910,8 +910,8 @@ SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, _
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to long" );
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
@ -922,8 +922,8 @@ SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index,
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::system_to_wide_string" );
SQLSRV_ASSERT( buffer_length % 2 == 0, "Odd buffer length passed to sqlsrv_buffered_result_set::system_to_wide_string" );
@ -1015,8 +1015,8 @@ SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_i
return r;
}
SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::to_same_string" );
@ -1074,19 +1074,19 @@ SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, _
SQLSRV_ASSERT( to_copy >= 0, "Negative field length calculated in buffered result set" );
if( to_copy > 0 ) {
memcpy( buffer, field_data + read_so_far, to_copy );
memcpy_s( buffer, buffer_length, field_data + read_so_far, to_copy );
read_so_far += to_copy;
}
if( extra ) {
OACR_WARNING_SUPPRESS( 26001, "Buffer length verified above" );
memcpy( reinterpret_cast<SQLCHAR*>( buffer ) + to_copy, L"\0", extra );
memcpy_s( reinterpret_cast<SQLCHAR*>( buffer ) + to_copy, buffer_length, L"\0", extra );
}
return r;
}
SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::wide_to_system_string" );
@ -1159,7 +1159,7 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i
if( to_copy > 0 ) {
memcpy( buffer, temp_string.get() + read_so_far, to_copy );
memcpy_s( buffer, buffer_length, temp_string.get() + read_so_far, to_copy );
}
SQLSRV_ASSERT( to_copy >= 0, "Invalid field copy length" );
OACR_WARNING_SUPPRESS( BUFFER_UNDERFLOW, "Buffer length verified above" );
@ -1170,14 +1170,14 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i
}
SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
return to_same_string( field_index, buffer, buffer_length, out_buffer_length );
}
SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invlid conversion to long" );
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer too small for SQL_C_LONG" ); // technically should ignore this
@ -1185,14 +1185,14 @@ SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, __out vo
unsigned char* row = get_row();
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
memcpy( buffer, long_data, sizeof( LONG ));
memcpy_s( buffer, buffer_length, long_data, sizeof( LONG ));
*out_buffer_length = sizeof( LONG );
return SQL_SUCCESS;
}
SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invlid conversion to double" );
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer too small for SQL_C_DOUBLE" ); // technically should ignore this
@ -1200,7 +1200,7 @@ SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, __out
unsigned char* row = get_row();
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
memcpy( buffer, double_data, sizeof( double ));
memcpy_s( buffer, buffer_length, double_data, sizeof( double ));
*out_buffer_length = sizeof( double );
return SQL_SUCCESS;
@ -1226,6 +1226,7 @@ void cache_row_dtor( zval* data )
}
sqlsrv_free( row );
sqlsrv_free( cl );
}
SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta,

View file

@ -889,6 +889,8 @@ class sqlsrv_context {
{
if( handle_ != SQL_NULL_HANDLE ) {
::SQLFreeHandle( handle_type_, handle_ );
last_error_.reset();
}
handle_ = SQL_NULL_HANDLE;
}
@ -1136,9 +1138,9 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
void core_sqlsrv_begin_transaction( sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_commit( sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_rollback( sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, __out zval* server_info TSRMLS_DC );
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, __out zval *server_version TSRMLS_DC );
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, __out zval *client_info TSRMLS_DC );
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval* server_info TSRMLS_DC );
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_version TSRMLS_DC );
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC );
bool core_is_conn_opt_value_escaped( const char* value, size_t value_len );
size_t core_str_zval_is_true( zval* str_zval );
@ -1197,7 +1199,7 @@ struct sqlsrv_stream {
};
// close any active stream
void close_active_stream( __inout sqlsrv_stmt* stmt TSRMLS_DC );
void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC );
extern php_stream_wrapper g_sqlsrv_stream_wrapper;
@ -1323,8 +1325,8 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql = NULL, i
field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT colno TSRMLS_DC );
bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULEN fetch_offset TSRMLS_DC );
void core_sqlsrv_get_field(sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_phptype, bool prefer_string,
__out void*& field_value, __out SQLLEN* field_length, bool cache_field,
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC);
_Out_ void*& field_value, _Out_ SQLLEN* field_length, bool cache_field,
_Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC);
bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC );
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true, bool throw_on_errors = true );
void core_sqlsrv_post_param( sqlsrv_stmt* stmt, zend_ulong paramno, zval* param_z TSRMLS_DC );
@ -1359,11 +1361,11 @@ struct sqlsrv_result_set {
virtual bool cached( int field_index ) = 0;
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ) = 0;
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )= 0;
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0;
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0;
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ) = 0;
virtual SQLLEN row_count( TSRMLS_D ) = 0;
};
@ -1376,11 +1378,11 @@ struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
virtual bool cached( int field_index ) { return false; }
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC );
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC );
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
virtual SQLLEN row_count( TSRMLS_D );
@ -1414,11 +1416,11 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
virtual bool cached( int field_index ) { return true; }
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC );
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC );
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
virtual SQLLEN row_count( TSRMLS_D );
@ -1449,55 +1451,55 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
sqlsrv_malloc_auto_ptr<SQLCHAR> temp_string; // temp buffer to hold a converted field while in use
SQLLEN temp_length; // number of bytes in the temp conversion buffer
typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
typedef std::map< SQLINTEGER, std::map< SQLINTEGER, conv_fn > > conv_matrix_t;
// two dimentional sparse matrix that holds the [from][to] functions that do conversions
static conv_matrix_t conv_matrix;
// string conversion functions
SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN binary_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN system_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN to_binary_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN to_same_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN wide_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// long conversion functions
SQLRETURN to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
SQLRETURN long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length );
SQLRETURN long_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN long_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN long_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// double conversion functions
SQLRETURN to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
SQLRETURN double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length );
SQLRETURN double_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN double_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN double_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// string to number conversion functions
// Future: See if these can be converted directly to template member functions
SQLRETURN string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN string_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN string_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN wstring_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN wstring_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// utility functions for conversions
unsigned char* get_row( void );
@ -1520,7 +1522,7 @@ bool convert_zval_string_from_utf16(SQLSRV_ENCODING encoding, zval* value_z, SQL
bool validate_string(char* string, SQLLEN& len);
bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const wchar_t* inString, SQLINTEGER cchInLen, char** outString, SQLLEN& cchOutLen );
wchar_t* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const char* mbcs_string,
unsigned int mbcs_len, __out unsigned int* utf16_len );
unsigned int mbcs_len, _Out_ unsigned int* utf16_len );
//*********************************************************************************************************************************
// Error handling routines and Predefined Errors
@ -1598,7 +1600,7 @@ enum error_handling_flags {
// 2/code) driver specific error code
// 3/message) driver specific error message
// The fetch type determines if the indices are numeric, associative, or both.
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, __out sqlsrv_error_auto_ptr& error,
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, _Out_ sqlsrv_error_auto_ptr& error,
logging_severity severity TSRMLS_DC );
// format and return a driver specfic error
@ -1754,8 +1756,7 @@ namespace core {
throw CoreException();
}
std::size_t driver_version = stmt->conn->driver_version;
if(( len == sizeof( CONNECTION_BUSY_ODBC_ERROR[driver_version] ) - 1 ) &&
!strcmp( reinterpret_cast<const char*>( err_msg ), CONNECTION_BUSY_ODBC_ERROR[driver_version] )) {
if( !strcmp( reinterpret_cast<const char*>( err_msg ), CONNECTION_BUSY_ODBC_ERROR[driver_version] )) {
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_MARS_OFF );
}
@ -1771,8 +1772,8 @@ namespace core {
// the context to hold the error, they are not passed as const.
inline SQLRETURN SQLGetDiagField( sqlsrv_context* ctx, SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC )
{
SQLRETURN r = ::SQLGetDiagField( ctx->handle_type(), ctx->handle(), record_number, diag_identifier,
diag_info_buffer, buffer_length, out_buffer_length );
@ -1785,7 +1786,7 @@ namespace core {
}
inline void SQLAllocHandle( SQLSMALLINT HandleType, sqlsrv_context& InputHandle,
__out_ecount(1) SQLHANDLE* OutputHandlePtr TSRMLS_DC )
_Out_writes_(1) SQLHANDLE* OutputHandlePtr TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLAllocHandle( HandleType, InputHandle.handle(), OutputHandlePtr );
@ -1801,9 +1802,9 @@ namespace core {
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
__inout SQLPOINTER ParameterValuePtr,
_Inout_ SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
__inout SQLLEN * StrLen_Or_IndPtr
_Inout_ SQLLEN * StrLen_Or_IndPtr
TSRMLS_DC )
{
SQLRETURN r;
@ -1817,8 +1818,8 @@ namespace core {
inline void SQLColAttribute( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLUSMALLINT field_identifier,
__out SQLPOINTER field_type_char, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length, __out SQLLEN* field_type_num TSRMLS_DC )
_Out_ SQLPOINTER field_type_char, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length, _Out_ SQLLEN* field_type_num TSRMLS_DC )
{
SQLRETURN r = ::SQLColAttribute( stmt->handle(), field_index, field_identifier, field_type_char,
buffer_length, out_buffer_length, field_type_num );
@ -1829,9 +1830,9 @@ namespace core {
}
inline void SQLDescribeCol( sqlsrv_stmt* stmt, SQLSMALLINT colno, __out_z SQLCHAR* col_name, SQLSMALLINT col_name_length,
__out SQLSMALLINT* col_name_length_out, SQLSMALLINT* data_type, __out SQLULEN* col_size,
__out SQLSMALLINT* decimal_digits, __out SQLSMALLINT* nullable TSRMLS_DC )
inline void SQLDescribeCol( sqlsrv_stmt* stmt, SQLSMALLINT colno, _Out_ SQLCHAR* col_name, SQLSMALLINT col_name_length,
_Out_ SQLSMALLINT* col_name_length_out, SQLSMALLINT* data_type, _Out_ SQLULEN* col_size,
_Out_ SQLSMALLINT* decimal_digits, _Out_ SQLSMALLINT* nullable TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLDescribeCol( stmt->handle(), colno, col_name, col_name_length, col_name_length_out,
@ -1914,7 +1915,7 @@ namespace core {
}
inline SQLRETURN SQLGetData( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )
{
SQLRETURN r = ::SQLGetData( stmt->handle(), field_index, target_type, buffer, buffer_length, out_buffer_length );
@ -1936,8 +1937,8 @@ namespace core {
}
inline void SQLGetInfo( sqlsrv_conn* conn, SQLUSMALLINT info_type, __out SQLPOINTER info_value, SQLSMALLINT buffer_len,
__out SQLSMALLINT* str_len TSRMLS_DC )
inline void SQLGetInfo( sqlsrv_conn* conn, SQLUSMALLINT info_type, _Out_ SQLPOINTER info_value, SQLSMALLINT buffer_len,
_Out_ SQLSMALLINT* str_len TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLGetInfo( conn->handle(), info_type, info_value, buffer_len, str_len );
@ -1986,7 +1987,7 @@ namespace core {
// SQLParamData returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA when there are more
// parameters or when the parameters are all processed.
inline SQLRETURN SQLParamData( sqlsrv_stmt* stmt, __out SQLPOINTER* value_ptr_ptr TSRMLS_DC )
inline SQLRETURN SQLParamData( sqlsrv_stmt* stmt, _Out_ SQLPOINTER* value_ptr_ptr TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLParamData( stmt->handle(), value_ptr_ptr );
@ -2141,7 +2142,7 @@ namespace core {
}
}
inline void sqlsrv_array_init( sqlsrv_context& ctx, __out zval* new_array TSRMLS_DC)
inline void sqlsrv_array_init( sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC)
{
int zr = ::array_init(new_array);
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2158,7 +2159,7 @@ namespace core {
}
}
inline void sqlsrv_zend_hash_get_current_data(sqlsrv_context& ctx, HashTable* ht, __out zval*& output_data TSRMLS_DC)
inline void sqlsrv_zend_hash_get_current_data(sqlsrv_context& ctx, HashTable* ht, _Out_ zval*& output_data TSRMLS_DC)
{
int zr = (output_data = ::zend_hash_get_current_data(ht)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2166,7 +2167,7 @@ namespace core {
}
}
inline void sqlsrv_zend_hash_get_current_data_ptr(sqlsrv_context& ctx, HashTable* ht, __out void*& output_data TSRMLS_DC)
inline void sqlsrv_zend_hash_get_current_data_ptr(sqlsrv_context& ctx, HashTable* ht, _Out_ void*& output_data TSRMLS_DC)
{
int zr = (output_data = ::zend_hash_get_current_data_ptr(ht)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {

View file

@ -35,7 +35,7 @@ struct field_cache {
// if the value is NULL, then just record a NULL pointer
if( field_value != NULL ) {
value = sqlsrv_malloc( field_len );
memcpy( value, field_value, field_len );
memcpy_s( value, field_len, field_value, field_len );
len = field_len;
}
else {
@ -76,23 +76,23 @@ const size_t DATE_FORMAT_LEN = sizeof( DATE_FORMAT );
// *** internal functions ***
// Only declarations are put here. Functions contain the documentation they need at their definition sites.
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, __out SQLLEN& size TSRMLS_DC );
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, _Out_ SQLLEN& size TSRMLS_DC );
size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_end TSRMLS_DC );
bool check_for_next_stream_parameter( sqlsrv_stmt* stmt TSRMLS_DC );
bool convert_input_param_to_utf16( zval* input_param_z, zval* convert_param_z );
void core_get_field_common(__inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, __out void*& field_value, __out SQLLEN* field_len TSRMLS_DC);
void core_get_field_common(_Inout_ sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC);
// returns the ODBC C type constant that matches the PHP type and encoding given
SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* param_z, SQLSRV_ENCODING encoding TSRMLS_DC );
void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLULEN& column_size, __out SQLSMALLINT& decimal_digits TSRMLS_DC );
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC );
// given a zval and encoding, determine the appropriate sql type, column size, and decimal scale (if appropriate)
void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLSMALLINT& sql_type TSRMLS_DC );
_Out_ SQLSMALLINT& sql_type TSRMLS_DC );
void field_cache_dtor( zval* data_z );
void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC );
void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type,
__out void*& field_value, __out SQLLEN* field_len TSRMLS_DC );
_Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC );
stmt_option const* get_stmt_option( sqlsrv_conn const* conn, zend_ulong key, const stmt_option stmt_opts[] TSRMLS_DC );
bool is_valid_sqlsrv_phptype( sqlsrv_phptype type );
// assure there is enough space for the output parameter string
@ -607,6 +607,8 @@ void core_sqlsrv_bind_param(sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALLI
// This is equivalent to the PHP code: $param_z->format( $format_z ); where param_z is the
// DateTime object and $format_z is the format string.
int zr = call_user_function( EG( function_table ), param_z, &function_z, &buffer_z, 1, params TSRMLS_CC );
zend_string_release( Z_STR( format_z ));
zend_string_release( Z_STR( function_z ));
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
throw core::CoreException();
}
@ -706,7 +708,11 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_
catch( core::CoreException& e ) {
// if the statement executed but failed in a subsequent operation before returning,
// we need to cancel the statement
// we need to cancel the statement and deref the output and stream parameters
if ( stmt->send_streams_at_exec ) {
zend_hash_clean( Z_ARRVAL( stmt->output_params ));
zend_hash_clean( Z_ARRVAL( stmt->param_streams ));
}
if( stmt->executed ) {
SQLCancel( stmt->handle() );
// stmt->executed = false; should this be reset if something fails?
@ -864,8 +870,8 @@ field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT coln
// Nothing, excpetion thrown if an error occurs
void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type_in, bool prefer_string,
__out void*& field_value, __out SQLLEN* field_len, bool cache_field,
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC)
_Out_ void*& field_value, _Out_ SQLLEN* field_len, bool cache_field,
_Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC)
{
try {
@ -884,7 +890,7 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
else {
field_value = sqlsrv_malloc( cached->len, sizeof( char ), 1 );
memcpy( field_value, cached->value, cached->len );
memcpy_s( field_value, ( cached->len * sizeof( char )), cached->value, cached->len );
if( cached->type.typeinfo.type == SQLSRV_PHPTYPE_STRING) {
// prevent the 'string not null terminated' warning
reinterpret_cast<char*>( field_value )[ cached->len ] = '\0';
@ -1329,7 +1335,7 @@ void stmt_option_buffered_query_limit:: operator()( sqlsrv_stmt* stmt, stmt_opti
// internal function to release the active stream. Called by each main API function
// that will alter the statement and cancel any retrieval of data from a stream.
void close_active_stream( __inout sqlsrv_stmt* stmt TSRMLS_DC )
void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
{
// if there is no active stream, return
if( Z_TYPE( stmt->active_stream ) == IS_UNDEF ) {
@ -1372,7 +1378,7 @@ bool is_streamable_type( SQLLEN sql_type )
return false;
}
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, __out SQLLEN& size TSRMLS_DC )
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, _Out_ SQLLEN& size TSRMLS_DC )
{
try {
@ -1468,8 +1474,8 @@ size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_e
// The memory allocation has to happen in the core layer because otherwise
// the driver layer would have to calculate size of the field_value
// to decide the amount of memory allocation.
void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, __out void*& field_value, __out SQLLEN* field_len TSRMLS_DC )
void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC )
{
try {
@ -1554,13 +1560,10 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
zval params[1];
zval field_value_temp_z;
zval function_z;
zval_auto_ptr return_value_z;
ZVAL_UNDEF( &field_value_temp_z );
ZVAL_UNDEF( &function_z );
ZVAL_UNDEF( params );
return_value_z = (zval *)sqlsrv_malloc( sizeof( zval ));
ZVAL_UNDEF( return_value_z );
SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_CHAR, field_value_temp,
MAX_DATETIME_STRING_LEN, field_len, true TSRMLS_CC );
@ -1569,6 +1572,10 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
throw core::CoreException();
}
zval_auto_ptr return_value_z;
return_value_z = ( zval * )sqlsrv_malloc( sizeof( zval ));
ZVAL_UNDEF( return_value_z );
if( *field_len == SQL_NULL_DATA ) {
ZVAL_NULL( return_value_z );
field_value = reinterpret_cast<void*>( return_value_z.get());
@ -1599,9 +1606,6 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
case SQLSRV_PHPTYPE_STREAM:
{
zval_auto_ptr return_value_z;
return_value_z = (zval *)sqlsrv_malloc(sizeof(zval));
ZVAL_UNDEF(return_value_z);
php_stream* stream = NULL;
sqlsrv_stream* ss = NULL;
SQLLEN sql_type;
@ -1627,6 +1631,10 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
ss->sql_type = static_cast<SQLUSMALLINT>( sql_type );
ss->encoding = static_cast<SQLSRV_ENCODING>( sqlsrv_php_type.typeinfo.encoding );
zval_auto_ptr return_value_z;
return_value_z = ( zval * )sqlsrv_malloc( sizeof( zval ));
ZVAL_UNDEF( return_value_z );
// turn our stream into a zval to be returned
php_stream_to_zval( stream, return_value_z );
@ -1659,7 +1667,7 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
// check_for_next_stream_parameter
// see if there is another stream to be sent. Returns true and sets the stream as current in the statement structure, otherwise
// returns false
bool check_for_next_stream_parameter( __inout sqlsrv_stmt* stmt TSRMLS_DC )
bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
{
int stream_index = 0;
SQLRETURN r = SQL_SUCCESS;
@ -1810,7 +1818,7 @@ SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* para
// given a zval and encoding, determine the appropriate sql type
void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLSMALLINT& sql_type TSRMLS_DC )
_Out_ SQLSMALLINT& sql_type TSRMLS_DC )
{
sql_type = SQL_UNKNOWN_TYPE;
int php_type = Z_TYPE_P(param_z);
@ -1880,7 +1888,7 @@ void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV
// given a zval and encoding, determine the appropriate column size, and decimal scale (if appropriate)
void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLULEN& column_size, __out SQLSMALLINT& decimal_digits TSRMLS_DC )
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC )
{
int php_type = Z_TYPE_P( param_z );
column_size = 0;
@ -1933,11 +1941,12 @@ void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval*
void field_cache_dtor( zval* data_z )
{
field_cache* cache = reinterpret_cast<field_cache*>(Z_PTR_P(data_z));
field_cache* cache = static_cast<field_cache*>( Z_PTR_P( data_z ));
if( cache->value )
{
sqlsrv_free( cache->value );
}
sqlsrv_free( cache );
}
@ -1968,6 +1977,7 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC )
char* str = Z_STRVAL_P( value_z );
SQLLEN str_len = stmt->param_ind_ptrs[ output_param->param_num ];
if( str_len == SQL_NULL_DATA ) {
zend_string_release( Z_STR_P( value_z ));
ZVAL_NULL( value_z );
continue;
}
@ -2044,7 +2054,7 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC )
}
void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type,
__out void*& field_value, __out SQLLEN* field_len TSRMLS_DC )
_Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC )
{
SQLRETURN r;
SQLSMALLINT c_type;
@ -2433,6 +2443,7 @@ void sqlsrv_output_param_dtor( zval* data )
{
sqlsrv_output_param *output_param = static_cast<sqlsrv_output_param*>( Z_PTR_P( data ));
zval_ptr_dtor( output_param->param_z ); // undo the reference to the string we will no longer hold
sqlsrv_free( output_param );
}
// called by Zend for each stream in the sqlsrv_stmt::param_streams hash table when it is cleaned/destroyed
@ -2440,6 +2451,7 @@ void sqlsrv_stream_dtor( zval* data )
{
sqlsrv_stream* stream_encoding = static_cast<sqlsrv_stream*>( Z_PTR_P( data ));
zval_ptr_dtor( stream_encoding->stream_z ); // undo the reference to the stream we will no longer hold
sqlsrv_free( stream_encoding );
}
}

View file

@ -45,7 +45,7 @@ int sqlsrv_stream_close( php_stream* stream, int /*close_handle*/ TSRMLS_DC )
// read from a sqlsrv stream into the buffer provided by Zend. The parameters for binary vs. char are
// set when sqlsrv_get_field is called by the user specifying which field type they want.
size_t sqlsrv_stream_read( php_stream* stream, __out_bcount(count) char* buf, size_t count TSRMLS_DC )
size_t sqlsrv_stream_read( php_stream* stream, _Out_writes_bytes_(count) char* buf, size_t count TSRMLS_DC )
{
SQLLEN read = 0;
SQLSMALLINT c_type = SQL_C_CHAR;
@ -203,8 +203,8 @@ php_stream_ops sqlsrv_stream_ops = {
// open a stream and return the sqlsrv_stream_ops function table as part of the
// return value. There is only one valid way to open a stream, using sqlsrv_get_field on
// certain field types. A sqlsrv stream may only be opened in read mode.
static php_stream* sqlsrv_stream_opener( php_stream_wrapper* wrapper, __in const char*, __in const char* mode,
int options, __in zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC )
static php_stream* sqlsrv_stream_opener( php_stream_wrapper* wrapper, _In_ const char*, _In_ const char* mode,
int options, _In_ zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC )
{
#if ZEND_DEBUG

View file

@ -33,9 +33,9 @@ SQLCHAR INTERNAL_FORMAT_ERROR[] = "An internal error occurred. FormatMessage fa
char last_err_msg[ 2048 ]; // 2k to hold the error messages
// routine used by utf16_string_from_mbcs_string
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, __in_bcount(mbcs_len) char const* mbcs_in_string,
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string,
unsigned int mbcs_len,
__out_ecount(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
_Out_writes_(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
unsigned int utf16_len );
}
@ -370,8 +370,8 @@ namespace {
// returned in utf16_out_string. An empty string passed in will result as
// a failure since MBTWC returns 0 for both an empty string and failure
// to convert.
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, __in_bcount(mbcs_len) char const* mbcs_in_string,
unsigned int mbcs_len, __out_ecount(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string,
unsigned int mbcs_len, _Out_writes_(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
unsigned int utf16_len )
{
unsigned int win_encoding = CP_ACP;

View file

@ -888,7 +888,7 @@ RETCODE SQL_API bcp_moretext (HDBC, DBINT, LPCBYTE);
RETCODE SQL_API bcp_readfmtA (HDBC, LPCSTR);
RETCODE SQL_API bcp_readfmtW (HDBC, LPCWSTR);
RETCODE SQL_API bcp_sendrow (HDBC);
RETCODE SQL_API bcp_setbulkmode (HDBC, INT, __in_bcount(cbField) void*, INT cbField, __in_bcount(cbRow) void *, INT cbRow);
RETCODE SQL_API bcp_setbulkmode (HDBC, INT, _In_reads_bytes_(cbField) void*, INT cbField, _In_reads_bytes_(cbRow) void *, INT cbRow);
RETCODE SQL_API bcp_setcolfmt (HDBC, INT, INT, void *, INT);
RETCODE SQL_API bcp_writefmtA (HDBC, LPCSTR);
RETCODE SQL_API bcp_writefmtW (HDBC, LPCWSTR);
@ -958,7 +958,7 @@ HANDLE __stdcall OpenSqlFilestream (
LPCWSTR FilestreamPath,
SQL_FILESTREAM_DESIRED_ACCESS DesiredAccess,
ULONG OpenOptions,
__in_bcount(FilestreamTransactionContextLength)
_In_reads_bytes_(FilestreamTransactionContextLength)
LPBYTE FilestreamTransactionContext,
SSIZE_T FilestreamTransactionContextLength,
PLARGE_INTEGER AllocationSize);
@ -995,11 +995,11 @@ extern "C" {
// type definition for LocalDBCreateInstance function
typedef HRESULT __cdecl FnLocalDBCreateInstance (
// I the LocalDB version (e.g. 11.0 or 11.0.1094.2)
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
);
// type definition for pointer to LocalDBCreateInstance function
@ -1008,14 +1008,14 @@ typedef FnLocalDBCreateInstance* PFnLocalDBCreateInstance;
// type definition for LocalDBStartInstance function
typedef HRESULT __cdecl FnLocalDBStartInstance (
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// O the buffer to store the connection string to the LocalDB instance
__out_ecount_z_opt(*lpcchSqlConnection) LPWSTR wszSqlConnection,
_Out_writes_opt_z_(*lpcchSqlConnection) LPWSTR wszSqlConnection,
// I/O on input has the size of the wszSqlConnection buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null.
__inout_opt LPDWORD lpcchSqlConnection
_Inout_opt_ LPDWORD lpcchSqlConnection
);
// type definition for pointer to LocalDBStartInstance function
@ -1027,19 +1027,19 @@ typedef FnLocalDBStartInstance* PFnLocalDBStartInstance;
// type definition for LocalDBFormatMessage function
typedef HRESULT __cdecl FnLocalDBFormatMessage(
// I the LocalDB error code
__in HRESULT hrLocalDB,
_In_ HRESULT hrLocalDB,
// I Available flags:
// LOCALDB_TRUNCATE_ERR_MESSAGE - if the input buffer is too short,
// the error message will be truncated to fit into the buffer
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I Language desired (LCID) or 0 (in which case Win32 FormatMessage order is used)
__in DWORD dwLanguageId,
_In_ DWORD dwLanguageId,
// O the buffer to store the LocalDB error message
__out_ecount_z(*lpcchMessage) LPWSTR wszMessage,
_Out_writes_z_(*lpcchMessage) LPWSTR wszMessage,
// I/O on input has the size of the wszMessage buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null. If the function succeeds
// contains the number of characters in the message, excluding the trailing null
__inout LPDWORD lpcchMessage
_Inout_ LPDWORD lpcchMessage
);
// type definition for function pointer to LocalDBFormatMessage function
@ -1112,14 +1112,14 @@ FnLocalDBStartInstance LocalDBStartInstance;
// type definition for LocalDBStopInstance function
typedef HRESULT __cdecl FnLocalDBStopInstance (
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I Available flags:
// LOCALDB_SHUTDOWN_KILL_PROCESS - force the instance to stop immediately
// LOCALDB_SHUTDOWN_WITH_NOWAIT - shutdown the instance with NOWAIT option
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I the time in seconds to wait this operation to complete. If this value is 0, this function will return immediately
// without waiting for LocalDB instance to stop
__in ULONG ulTimeout
_In_ ULONG ulTimeout
);
// type definition for pointer to LocalDBStopInstance function
@ -1149,9 +1149,9 @@ FnLocalDBStopInstance LocalDBStopInstance;
// type definition for LocalDBDeleteInstance function
typedef HRESULT __cdecl FnLocalDBDeleteInstance (
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
);
// type definition for pointer to LocalDBDeleteInstance function
@ -1202,10 +1202,10 @@ typedef TLocalDBInstanceName* PTLocalDBInstanceName;
// type definition for LocalDBGetInstances function
typedef HRESULT __cdecl FnLocalDBGetInstances(
// O buffer for a LocalDB instance names
__out PTLocalDBInstanceName pInstanceNames,
_Out_ PTLocalDBInstanceName pInstanceNames,
// I/O on input has the number slots for instance names in the pInstanceNames buffer. On output,
// has the number of existing LocalDB instances
__inout LPDWORD lpdwNumberOfInstances
_Inout_ LPDWORD lpdwNumberOfInstances
);
// type definition for pointer to LocalDBGetInstances function
@ -1267,11 +1267,11 @@ typedef LocalDBInstanceInfo* PLocalDBInstanceInfo;
// type definition for LocalDBGetInstanceInfo function
typedef HRESULT __cdecl FnLocalDBGetInstanceInfo(
// I the LocalDB instance name
__in_z PCWSTR wszInstanceName,
_In_z_ PCWSTR wszInstanceName,
// O instance information
__out PLocalDBInstanceInfo pInfo,
_Out_ PLocalDBInstanceInfo pInfo,
// I Size of LocalDBInstanceInfo structure in bytes
__in DWORD cbInfo);
_In_ DWORD cbInfo);
// type definition for pointer to LocalDBGetInstances function
typedef FnLocalDBGetInstanceInfo* PFnLocalDBGetInstanceInfo;
@ -1298,10 +1298,10 @@ typedef TLocalDBVersion* PTLocalDBVersion;
// type definition for LocalDBGetVersions function
typedef HRESULT __cdecl FnLocalDBGetVersions(
// O buffer for installed LocalDB versions
__out PTLocalDBVersion pVersions,
_Out_ PTLocalDBVersion pVersions,
// I/O on input has the number slots for versions in the pVersions buffer. On output,
// has the number of existing LocalDB versions
__inout LPDWORD lpdwNumberOfVersions
_Inout_ LPDWORD lpdwNumberOfVersions
);
// type definition for pointer to LocalDBGetVersions function
@ -1352,11 +1352,11 @@ typedef LocalDBVersionInfo* PLocalDBVersionInfo;
// type definition for LocalDBGetVersionInfo function
typedef HRESULT __cdecl FnLocalDBGetVersionInfo(
// I LocalDB version string
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// O version information
__out PLocalDBVersionInfo pVersionInfo,
_Out_ PLocalDBVersionInfo pVersionInfo,
// I Size of LocalDBVersionInfo structure in bytes
__in DWORD cbVersionInfo
_In_ DWORD cbVersionInfo
);
// type definition for pointer to LocalDBGetVersionInfo function
@ -1402,13 +1402,13 @@ FnLocalDBStopTracing LocalDBStopTracing;
// type definition for LocalDBShareInstance function
typedef HRESULT __cdecl FnLocalDBShareInstance(
// I the SID of the LocalDB instance owner
__in_opt PSID pOwnerSID,
_In_opt_ PSID pOwnerSID,
// I the private name of LocalDB instance which should be shared
__in_z PCWSTR wszPrivateLocalDBInstanceName,
_In_z_ PCWSTR wszPrivateLocalDBInstanceName,
// I the public shared name
__in_z PCWSTR wszSharedName,
_In_z_ PCWSTR wszSharedName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags);
_In_ DWORD dwFlags);
// type definition for pointer to LocalDBShareInstance function
typedef FnLocalDBShareInstance* PFnLocalDBShareInstance;
@ -1426,9 +1426,9 @@ FnLocalDBShareInstance LocalDBShareInstance;
// type definition for LocalDBUnshareInstance function
typedef HRESULT __cdecl FnLocalDBUnshareInstance(
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags);
_In_ DWORD dwFlags);
// type definition for pointer to LocalDBUnshareInstance function
typedef FnLocalDBUnshareInstance* PFnLocalDBUnshareInstance;
@ -1653,11 +1653,11 @@ Cleanup:
HRESULT __cdecl
LocalDBCreateInstance (
// I the LocalDB version (e.g. 11.0 or 11.0.1094.2)
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
)
{
LOCALDB_PROXY(LocalDBCreateInstance)(wszVersion, pInstanceName, dwFlags);
@ -1666,14 +1666,14 @@ LocalDBCreateInstance (
HRESULT __cdecl
LocalDBStartInstance(
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// O the buffer to store the connection string to the LocalDB instance
__out_ecount_z_opt(*lpcchSqlConnection) LPWSTR wszSqlConnection,
_Out_writes_z__opt(*lpcchSqlConnection) LPWSTR wszSqlConnection,
// I/O on input has the size of the wszSqlConnection buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null.
__inout_opt LPDWORD lpcchSqlConnection
_Inout_opt_ LPDWORD lpcchSqlConnection
)
{
LOCALDB_PROXY(LocalDBStartInstance)(pInstanceName, dwFlags, wszSqlConnection, lpcchSqlConnection);
@ -1682,14 +1682,14 @@ LocalDBStartInstance(
HRESULT __cdecl
LocalDBStopInstance (
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I Available flags:
// LOCALDB_SHUTDOWN_KILL_PROCESS - force the instance to stop immediately
// LOCALDB_SHUTDOWN_WITH_NOWAIT - shutdown the instance with NOWAIT option
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I the time in seconds to wait this operation to complete. If this value is 0, this function will return immediately
// without waiting for LocalDB instance to stop
__in ULONG ulTimeout
_In_ ULONG ulTimeout
)
{
LOCALDB_PROXY(LocalDBStopInstance)(pInstanceName, dwFlags, ulTimeout);
@ -1698,9 +1698,9 @@ LocalDBStopInstance (
HRESULT __cdecl
LocalDBDeleteInstance (
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
)
{
LOCALDB_PROXY(LocalDBDeleteInstance)(pInstanceName, dwFlags);
@ -1709,19 +1709,19 @@ LocalDBDeleteInstance (
HRESULT __cdecl
LocalDBFormatMessage(
// I the LocalDB error code
__in HRESULT hrLocalDB,
_In_ HRESULT hrLocalDB,
// I Available flags:
// LOCALDB_TRUNCATE_ERR_MESSAGE - if the input buffer is too short,
// the error message will be truncated to fit into the buffer
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I Language desired (LCID) or 0 (in which case Win32 FormatMessage order is used)
__in DWORD dwLanguageId,
_In_ DWORD dwLanguageId,
// O the buffer to store the LocalDB error message
__out_ecount_z(*lpcchMessage) LPWSTR wszMessage,
_Out_writes_z_(*lpcchMessage) LPWSTR wszMessage,
// I/O on input has the size of the wszMessage buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null. If the function succeeds
// contains the number of characters in the message, excluding the trailing null
__inout LPDWORD lpcchMessage
_Inout_ LPDWORD lpcchMessage
)
{
LOCALDB_PROXY(LocalDBFormatMessage)(hrLocalDB, dwFlags, dwLanguageId, wszMessage, lpcchMessage);
@ -1730,10 +1730,10 @@ LocalDBFormatMessage(
HRESULT __cdecl
LocalDBGetInstances(
// O buffer with instance names
__out PTLocalDBInstanceName pInstanceNames,
_Out_ PTLocalDBInstanceName pInstanceNames,
// I/O on input has the number slots for instance names in the pInstanceNames buffer. On output,
// has the number of existing LocalDB instances
__inout LPDWORD lpdwNumberOfInstances
_Inout_ LPDWORD lpdwNumberOfInstances
)
{
LOCALDB_PROXY(LocalDBGetInstances)(pInstanceNames, lpdwNumberOfInstances);
@ -1742,11 +1742,11 @@ LocalDBGetInstances(
HRESULT __cdecl
LocalDBGetInstanceInfo(
// I the instance name
__in_z PCWSTR wszInstanceName,
_In_z_ PCWSTR wszInstanceName,
// O instance information
__out PLocalDBInstanceInfo pInfo,
_Out_ PLocalDBInstanceInfo pInfo,
// I Size of LocalDBInstanceInfo structure in bytes
__in DWORD cbInfo
_In_ DWORD cbInfo
)
{
LOCALDB_PROXY(LocalDBGetInstanceInfo)(wszInstanceName, pInfo, cbInfo);
@ -1767,13 +1767,13 @@ LocalDBStopTracing()
HRESULT __cdecl
LocalDBShareInstance(
// I the SID of the LocalDB instance owner
__in_opt PSID pOwnerSID,
_In_opt_ PSID pOwnerSID,
// I the private name of LocalDB instance which should be shared
__in_z PCWSTR wszLocalDBInstancePrivateName,
_In_z_ PCWSTR wszLocalDBInstancePrivateName,
// I the public shared name
__in_z PCWSTR wszSharedName,
_In_z_ PCWSTR wszSharedName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags)
_In_ DWORD dwFlags)
{
LOCALDB_PROXY(LocalDBShareInstance)(pOwnerSID, wszLocalDBInstancePrivateName, wszSharedName, dwFlags);
}
@ -1781,10 +1781,10 @@ LocalDBShareInstance(
HRESULT __cdecl
LocalDBGetVersions(
// O buffer for installed LocalDB versions
__out PTLocalDBVersion pVersions,
_Out_ PTLocalDBVersion pVersions,
// I/O on input has the number slots for versions in the pVersions buffer. On output,
// has the number of existing LocalDB versions
__inout LPDWORD lpdwNumberOfVersions
_Inout_ LPDWORD lpdwNumberOfVersions
)
{
LOCALDB_PROXY(LocalDBGetVersions)(pVersions, lpdwNumberOfVersions);
@ -1793,9 +1793,9 @@ LocalDBGetVersions(
HRESULT __cdecl
LocalDBUnshareInstance(
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags)
_In_ DWORD dwFlags)
{
LOCALDB_PROXY(LocalDBUnshareInstance)(pInstanceName, dwFlags);
}
@ -1803,11 +1803,11 @@ LocalDBUnshareInstance(
HRESULT __cdecl
LocalDBGetVersionInfo(
// I LocalDB version string
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// O version information
__out PLocalDBVersionInfo pVersionInfo,
_Out_ PLocalDBVersionInfo pVersionInfo,
// I Size of LocalDBVersionInfo structure in bytes
__in DWORD cbVersionInfo)
_In_ DWORD cbVersionInfo)
{
LOCALDB_PROXY(LocalDBGetVersionInfo)(wszVersion, pVersionInfo, cbVersionInfo);
}

View file

@ -137,7 +137,7 @@ struct pdo_bool_conn_attr_func {
// statement options related functions
void add_stmt_option_key( sqlsrv_context& ctx, size_t key, HashTable* options_ht,
zval** data TSRMLS_DC );
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, __inout HashTable* pdo_stmt_options_ht TSRMLS_DC );
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC );
} // namespace
@ -404,6 +404,7 @@ int pdo_sqlsrv_db_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
zval* temp_server_z = NULL;
sqlsrv_malloc_auto_ptr<conn_string_parser> dsn_parser;
zval server_z;
ZVAL_UNDEF( &server_z );
try {
@ -460,11 +461,11 @@ int pdo_sqlsrv_db_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
}
catch( core::CoreException& ) {
if ( Z_TYPE( server_z ) == IS_STRING ) {
zend_string_release( Z_STR( server_z ));
}
dbh->error_mode = prev_err_mode; // reset the error mode
g_henv_cp->invalidate();
return 0;
}
catch( ... ) {
@ -1095,7 +1096,7 @@ int pdo_sqlsrv_dbh_return_error( pdo_dbh_t *dbh, pdo_stmt_t *stmt,
// len - Length of the name.
// Return:
// Returns the last insert id as a string.
char * pdo_sqlsrv_dbh_last_id( pdo_dbh_t *dbh, const char *name, __out size_t* len TSRMLS_DC )
char * pdo_sqlsrv_dbh_last_id( pdo_dbh_t *dbh, const char *name, _Out_ size_t* len TSRMLS_DC )
{
PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN;
@ -1305,7 +1306,7 @@ void add_stmt_option_key( sqlsrv_context& ctx, size_t key, HashTable* options_ht
// ctx - The current context.
// stmt_options - The user provided list of statement options.
// pdo_stmt_options_ht - Output hashtable of statement options.
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, __inout HashTable* pdo_stmt_options_ht TSRMLS_DC )
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC )
{
try {

View file

@ -22,7 +22,7 @@
#include "pdo_sqlsrv.h"
// Constructor
conn_string_parser:: conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, __inout HashTable* conn_options_ht )
conn_string_parser:: conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, _Inout_ HashTable* conn_options_ht )
{
this->conn_str = dsn;
this->len = len;
@ -142,7 +142,7 @@ void conn_string_parser::validate_key(const char *key, int key_len TSRMLS_DC )
// encountered an invalid key, throw error.
sqlsrv_malloc_auto_ptr<char> key_name;
key_name = static_cast<char*>( sqlsrv_malloc( new_len + 1 ));
memcpy( key_name, key, new_len );
memcpy_s( key_name, new_len + 1 ,key, new_len );
key_name[ new_len ] = '\0';
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_KEY, key_name );

View file

@ -158,7 +158,7 @@ class conn_string_parser
void add_key_value_pair( const char* value, int len TSRMLS_DC );
public:
conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, __inout HashTable* conn_options_ht );
conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, _Inout_ HashTable* conn_options_ht );
void parse_conn_string( TSRMLS_D );
};

View file

@ -202,6 +202,9 @@ void set_stmt_encoding( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
// internal helper function to free meta data structures allocated
void meta_data_free( field_meta_data* meta )
{
if( meta->field_name ) {
meta->field_name.reset();
}
sqlsrv_free( meta );
}
@ -431,7 +434,7 @@ int pdo_sqlsrv_stmt_describe_col(pdo_stmt_t *stmt, int colno TSRMLS_DC)
// Set the name
column_data->name = zend_string_init( (const char*)core_meta_data->field_name.get(), core_meta_data->field_name_len, 0 );
core_meta_data->field_name.transferred();
core_meta_data->field_name.reset();
// Set the maxlen
column_data->maxlen = ( core_meta_data->field_precision > 0 ) ? core_meta_data->field_precision : core_meta_data->field_size;

View file

@ -599,11 +599,16 @@ void pdo_sqlsrv_throw_exception( sqlsrv_error_const* error TSRMLS_DC )
add_next_index_string( &ex_error_info, reinterpret_cast<char*>( error->sqlstate ));
add_next_index_long( &ex_error_info, error->native_code );
add_next_index_string( &ex_error_info, reinterpret_cast<char*>( error->native_message ));
//zend_update_property makes an entry in the properties_table in ex_obj point to the Z_ARRVAL( ex_error_info )
//and the refcount of the zend_array is incremented by 1
zend_update_property( ex_class, &ex_obj, EXCEPTION_PROPERTY_ERRORINFO, sizeof( EXCEPTION_PROPERTY_ERRORINFO ) - 1,
&ex_error_info TSRMLS_CC );
//DELREF ex_error_info here to decrement the refcount of the zend_array is 1
//the global hashtable EG(exception) then points to the zend_object in ex_obj in zend_throw_exception_object;
//this ensure when EG(exception) cleans itself at php shutdown, the zend_array allocated is properly destroyed
Z_DELREF( ex_error_info );
zend_throw_exception_object( &ex_obj TSRMLS_CC );
ex_msg.transferred();
}
}

View file

@ -1 +1 @@
Microsoft Drivers 4.0.0 for PHP for SQL Server (SQLSRV driver)
Microsoft Drivers 4.0.0 for PHP for SQL Server (PDO driver)

View file

@ -133,9 +133,9 @@ struct bool_conn_attr_func {
//// *** internal functions ***
void sqlsrv_conn_close_stmts( ss_sqlsrv_conn* conn TSRMLS_DC );
void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, __out char** uid, __out char** pwd,
__inout HashTable* ss_conn_options_ht TSRMLS_DC );
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, __inout HashTable* ss_stmt_options_ht TSRMLS_DC );
void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, _Out_ char** uid, _Out_ char** pwd,
_Inout_ HashTable* ss_conn_options_ht TSRMLS_DC );
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC );
void add_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len,
HashTable* options_ht, zval* data TSRMLS_DC );
void add_stmt_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, HashTable* options_ht, zval* data TSRMLS_DC );
@ -1218,7 +1218,7 @@ void add_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len,
// against the list of supported statement options by this driver. After validation
// creates a Hashtable of statement options to be sent to the core layer for processing.
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, __inout HashTable* ss_stmt_options_ht TSRMLS_DC )
void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC )
{
try {
@ -1258,7 +1258,7 @@ void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, __inout Has
// against the predefined list of supported connection options by this driver. After validation
// creates a Hashtable of connection options to be sent to the core layer for processing.
void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, __out char** uid, __out char** pwd, __inout HashTable* ss_conn_options_ht TSRMLS_DC )
void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, _Out_ char** uid, _Out_ char** pwd, _Inout_ HashTable* ss_conn_options_ht TSRMLS_DC )
{
try {

View file

@ -57,7 +57,7 @@ const char CONNECTION_OPTION_MARS_ON[] = "MARS_Connection={Yes};";
void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* server, const char* uid, const char* pwd,
HashTable* options_ht, const connection_option valid_conn_opts[],
void* driver,__inout std::string& connection_string TSRMLS_DC );
void* driver,_Inout_ std::string& connection_string TSRMLS_DC );
void determine_server_version( sqlsrv_conn* conn TSRMLS_DC );
const char* get_processor_arch( void );
void get_server_version( sqlsrv_conn* conn, char** server_version, SQLSMALLINT& len TSRMLS_DC );
@ -377,7 +377,7 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
// conn - The connection resource by which the client and server are connected.
// *server_version - zval for returning results.
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, __out zval *server_version TSRMLS_DC )
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_version TSRMLS_DC )
{
try {
@ -404,7 +404,7 @@ void core_sqlsrv_get_server_version( sqlsrv_conn* conn, __out zval *server_versi
// conn - The connection resource by which the client and server are connected.
// *server_info - zval for returning results.
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, __out zval *server_info TSRMLS_DC )
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval *server_info TSRMLS_DC )
{
try {
@ -443,7 +443,7 @@ void core_sqlsrv_get_server_info( sqlsrv_conn* conn, __out zval *server_info TSR
// conn - The connection resource by which the client and server are connected.
// *client_info - zval for returning the results.
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, __out zval *client_info TSRMLS_DC )
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC )
{
try {
@ -534,7 +534,7 @@ connection_option const* get_connection_option( sqlsrv_conn* conn, SQLULEN key,
void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* server, const char* uid, const char* pwd,
HashTable* options, const connection_option valid_conn_opts[],
void* driver,__inout std::string& connection_string TSRMLS_DC )
void* driver,_Inout_ std::string& connection_string TSRMLS_DC )
{
bool credentials_mentioned = false;
bool mars_mentioned = false;
@ -689,7 +689,7 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC )
errno = 0;
char version_major_str[ 3 ];
SERVER_VERSION version_major;
memcpy( version_major_str, p, 2 );
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 ));

View file

@ -145,14 +145,14 @@ void core_sqlsrv_mshutdown( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp )
if( henv_ncp != SQL_NULL_HANDLE ) {
henv_ncp.invalidate();
delete &henv_ncp;
}
delete &henv_ncp;
if( henv_cp != SQL_NULL_HANDLE ) {
henv_cp.invalidate();
delete &henv_cp;
}
delete &henv_cp;
return;
}

View file

@ -85,7 +85,7 @@ void cache_row_dtor(zval* data);
// There is an extra copy here, but given the size is short (usually <20 bytes) and the complications of
// subclassing a new streambuf just to avoid the copy, it's easier to do the copy
template <typename Char, typename Number>
SQLRETURN number_to_string( Number* number_data, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
SQLRETURN number_to_string( Number* number_data, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
sqlsrv_error_auto_ptr& last_error )
{
std::basic_ostringstream<Char> os;
@ -107,14 +107,14 @@ SQLRETURN number_to_string( Number* number_data, __out void* buffer, SQLLEN buff
}
*out_buffer_length = str_num.size() * sizeof(Char) + sizeof(Char); // include NULL terminator
memcpy( buffer, str_num.c_str(), *out_buffer_length );
memcpy_s( buffer, buffer_length, str_num.c_str(), *out_buffer_length );
return SQL_SUCCESS;
}
template <typename Number, typename Char>
SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error )
SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error )
{
Number* number_data = reinterpret_cast<Number*>( buffer );
std::locale loc; // default locale should match system
@ -214,7 +214,7 @@ SQLRETURN sqlsrv_odbc_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset
}
SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ SQLPOINTER buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )
{
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
@ -222,8 +222,8 @@ SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLIN
}
SQLRETURN sqlsrv_odbc_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC )
{
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length,
@ -596,7 +596,7 @@ SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN off
}
SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ SQLPOINTER buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )
{
last_error = NULL;
@ -632,8 +632,8 @@ SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMA
}
SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC )
{
SQLSRV_ASSERT( record_number == 1, "Only record number 1 can be fetched by sqlsrv_buffered_result_set::get_diag_field" );
SQLSRV_ASSERT( diag_identifier == SQL_DIAG_SQLSTATE,
@ -648,7 +648,7 @@ SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number,
SQLSRV_ASSERT( last_error->sqlstate != NULL,
"Must have a SQLSTATE in a valid last_error in sqlsrv_buffered_result_set::get_diag_field" );
memcpy( diag_info_buffer, last_error->sqlstate, min( buffer_length, SQL_SQLSTATE_BUFSIZE ));
memcpy_s( diag_info_buffer, buffer_length, last_error->sqlstate, min( buffer_length, SQL_SQLSTATE_BUFSIZE ));
return SQL_SUCCESS;
}
@ -684,8 +684,8 @@ SQLLEN sqlsrv_buffered_result_set::row_count( TSRMLS_D )
// private functions
template <typename Char>
SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, __out void* buffer,
SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, _Out_ void* buffer,
SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
sqlsrv_error_auto_ptr& out_error )
{
// hex characters for the conversion loop below
@ -745,8 +745,8 @@ SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, __out voi
return r;
}
SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLCHAR* row = get_row();
SQLCHAR* field_data = NULL;
@ -763,8 +763,8 @@ SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field
return binary_to_string<char>( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLCHAR* row = get_row();
SQLCHAR* field_data = NULL;
@ -782,8 +782,8 @@ SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_i
}
SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to long" );
SQLSRV_ASSERT( buffer_length >= sizeof(SQLLEN), "Buffer length must be able to find a long in "
@ -811,8 +811,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, _
return SQL_SUCCESS;
}
SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to system string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_system_string" );
@ -823,8 +823,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field
return number_to_string<char>( double_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to wide string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_wide_string" );
@ -835,8 +835,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_i
return number_to_string<WCHAR>( double_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to long" );
SQLSRV_ASSERT( buffer_length >= sizeof(double), "Buffer length must be able to find a long in sqlsrv_buffered_result_set::double_to_long" );
@ -850,8 +850,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, _
return SQL_SUCCESS;
}
SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to system string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_system_string" );
@ -862,8 +862,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_i
return number_to_string<char>( long_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to wide string" );
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_wide_string" );
@ -874,8 +874,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_ind
return number_to_string<WCHAR>( long_data, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to double" );
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
@ -886,8 +886,8 @@ SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index,
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to double" );
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
@ -898,8 +898,8 @@ SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to long" );
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
@ -910,8 +910,8 @@ SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, _
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to long" );
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
@ -922,8 +922,8 @@ SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index,
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
}
SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::system_to_wide_string" );
SQLSRV_ASSERT( buffer_length % 2 == 0, "Odd buffer length passed to sqlsrv_buffered_result_set::system_to_wide_string" );
@ -1015,8 +1015,8 @@ SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_i
return r;
}
SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::to_same_string" );
@ -1074,19 +1074,19 @@ SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, _
SQLSRV_ASSERT( to_copy >= 0, "Negative field length calculated in buffered result set" );
if( to_copy > 0 ) {
memcpy( buffer, field_data + read_so_far, to_copy );
memcpy_s( buffer, buffer_length, field_data + read_so_far, to_copy );
read_so_far += to_copy;
}
if( extra ) {
OACR_WARNING_SUPPRESS( 26001, "Buffer length verified above" );
memcpy( reinterpret_cast<SQLCHAR*>( buffer ) + to_copy, L"\0", extra );
memcpy_s( reinterpret_cast<SQLCHAR*>( buffer ) + to_copy, buffer_length, L"\0", extra );
}
return r;
}
SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::wide_to_system_string" );
@ -1159,7 +1159,7 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i
if( to_copy > 0 ) {
memcpy( buffer, temp_string.get() + read_so_far, to_copy );
memcpy_s( buffer, buffer_length, temp_string.get() + read_so_far, to_copy );
}
SQLSRV_ASSERT( to_copy >= 0, "Invalid field copy length" );
OACR_WARNING_SUPPRESS( BUFFER_UNDERFLOW, "Buffer length verified above" );
@ -1170,14 +1170,14 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i
}
SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
return to_same_string( field_index, buffer, buffer_length, out_buffer_length );
}
SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invlid conversion to long" );
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer too small for SQL_C_LONG" ); // technically should ignore this
@ -1185,14 +1185,14 @@ SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, __out vo
unsigned char* row = get_row();
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
memcpy( buffer, long_data, sizeof( LONG ));
memcpy_s( buffer, buffer_length, long_data, sizeof( LONG ));
*out_buffer_length = sizeof( LONG );
return SQL_SUCCESS;
}
SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length )
SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length )
{
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invlid conversion to double" );
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer too small for SQL_C_DOUBLE" ); // technically should ignore this
@ -1200,7 +1200,7 @@ SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, __out
unsigned char* row = get_row();
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
memcpy( buffer, double_data, sizeof( double ));
memcpy_s( buffer, buffer_length, double_data, sizeof( double ));
*out_buffer_length = sizeof( double );
return SQL_SUCCESS;
@ -1226,6 +1226,7 @@ void cache_row_dtor( zval* data )
}
sqlsrv_free( row );
sqlsrv_free( cl );
}
SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta,

View file

@ -889,6 +889,8 @@ class sqlsrv_context {
{
if( handle_ != SQL_NULL_HANDLE ) {
::SQLFreeHandle( handle_type_, handle_ );
last_error_.reset();
}
handle_ = SQL_NULL_HANDLE;
}
@ -1136,9 +1138,9 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
void core_sqlsrv_begin_transaction( sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_commit( sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_rollback( sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, __out zval* server_info TSRMLS_DC );
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, __out zval *server_version TSRMLS_DC );
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, __out zval *client_info TSRMLS_DC );
void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval* server_info TSRMLS_DC );
void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_version TSRMLS_DC );
void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC );
bool core_is_conn_opt_value_escaped( const char* value, size_t value_len );
size_t core_str_zval_is_true( zval* str_zval );
@ -1197,7 +1199,7 @@ struct sqlsrv_stream {
};
// close any active stream
void close_active_stream( __inout sqlsrv_stmt* stmt TSRMLS_DC );
void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC );
extern php_stream_wrapper g_sqlsrv_stream_wrapper;
@ -1323,8 +1325,8 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql = NULL, i
field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT colno TSRMLS_DC );
bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULEN fetch_offset TSRMLS_DC );
void core_sqlsrv_get_field(sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_phptype, bool prefer_string,
__out void*& field_value, __out SQLLEN* field_length, bool cache_field,
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC);
_Out_ void*& field_value, _Out_ SQLLEN* field_length, bool cache_field,
_Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC);
bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC );
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true, bool throw_on_errors = true );
void core_sqlsrv_post_param( sqlsrv_stmt* stmt, zend_ulong paramno, zval* param_z TSRMLS_DC );
@ -1359,11 +1361,11 @@ struct sqlsrv_result_set {
virtual bool cached( int field_index ) = 0;
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ) = 0;
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )= 0;
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0;
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0;
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ) = 0;
virtual SQLLEN row_count( TSRMLS_D ) = 0;
};
@ -1376,11 +1378,11 @@ struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
virtual bool cached( int field_index ) { return false; }
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC );
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC );
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
virtual SQLLEN row_count( TSRMLS_D );
@ -1414,11 +1416,11 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
virtual bool cached( int field_index ) { return true; }
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC );
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC );
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
virtual SQLLEN row_count( TSRMLS_D );
@ -1449,55 +1451,55 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
sqlsrv_malloc_auto_ptr<SQLCHAR> temp_string; // temp buffer to hold a converted field while in use
SQLLEN temp_length; // number of bytes in the temp conversion buffer
typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
typedef std::map< SQLINTEGER, std::map< SQLINTEGER, conv_fn > > conv_matrix_t;
// two dimentional sparse matrix that holds the [from][to] functions that do conversions
static conv_matrix_t conv_matrix;
// string conversion functions
SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN binary_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN system_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN to_binary_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN to_same_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN wide_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// long conversion functions
SQLRETURN to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
SQLRETURN long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length );
SQLRETURN long_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN long_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN long_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// double conversion functions
SQLRETURN to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
SQLRETURN double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length );
SQLRETURN double_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN double_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN double_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// string to number conversion functions
// Future: See if these can be converted directly to template member functions
SQLRETURN string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
__out SQLLEN* out_buffer_length );
SQLRETURN string_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN string_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN wstring_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
SQLRETURN wstring_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length,
_Out_ SQLLEN* out_buffer_length );
// utility functions for conversions
unsigned char* get_row( void );
@ -1520,7 +1522,7 @@ bool convert_zval_string_from_utf16(SQLSRV_ENCODING encoding, zval* value_z, SQL
bool validate_string(char* string, SQLLEN& len);
bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const wchar_t* inString, SQLINTEGER cchInLen, char** outString, SQLLEN& cchOutLen );
wchar_t* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const char* mbcs_string,
unsigned int mbcs_len, __out unsigned int* utf16_len );
unsigned int mbcs_len, _Out_ unsigned int* utf16_len );
//*********************************************************************************************************************************
// Error handling routines and Predefined Errors
@ -1598,7 +1600,7 @@ enum error_handling_flags {
// 2/code) driver specific error code
// 3/message) driver specific error message
// The fetch type determines if the indices are numeric, associative, or both.
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, __out sqlsrv_error_auto_ptr& error,
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, _Out_ sqlsrv_error_auto_ptr& error,
logging_severity severity TSRMLS_DC );
// format and return a driver specfic error
@ -1754,8 +1756,7 @@ namespace core {
throw CoreException();
}
std::size_t driver_version = stmt->conn->driver_version;
if(( len == sizeof( CONNECTION_BUSY_ODBC_ERROR[driver_version] ) - 1 ) &&
!strcmp( reinterpret_cast<const char*>( err_msg ), CONNECTION_BUSY_ODBC_ERROR[driver_version] )) {
if( !strcmp( reinterpret_cast<const char*>( err_msg ), CONNECTION_BUSY_ODBC_ERROR[driver_version] )) {
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_MARS_OFF );
}
@ -1771,8 +1772,8 @@ namespace core {
// the context to hold the error, they are not passed as const.
inline SQLRETURN SQLGetDiagField( sqlsrv_context* ctx, SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
_Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC )
{
SQLRETURN r = ::SQLGetDiagField( ctx->handle_type(), ctx->handle(), record_number, diag_identifier,
diag_info_buffer, buffer_length, out_buffer_length );
@ -1785,7 +1786,7 @@ namespace core {
}
inline void SQLAllocHandle( SQLSMALLINT HandleType, sqlsrv_context& InputHandle,
__out_ecount(1) SQLHANDLE* OutputHandlePtr TSRMLS_DC )
_Out_writes_(1) SQLHANDLE* OutputHandlePtr TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLAllocHandle( HandleType, InputHandle.handle(), OutputHandlePtr );
@ -1801,9 +1802,9 @@ namespace core {
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
__inout SQLPOINTER ParameterValuePtr,
_Inout_ SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
__inout SQLLEN * StrLen_Or_IndPtr
_Inout_ SQLLEN * StrLen_Or_IndPtr
TSRMLS_DC )
{
SQLRETURN r;
@ -1817,8 +1818,8 @@ namespace core {
inline void SQLColAttribute( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLUSMALLINT field_identifier,
__out SQLPOINTER field_type_char, SQLSMALLINT buffer_length,
__out SQLSMALLINT* out_buffer_length, __out SQLLEN* field_type_num TSRMLS_DC )
_Out_ SQLPOINTER field_type_char, SQLSMALLINT buffer_length,
_Out_ SQLSMALLINT* out_buffer_length, _Out_ SQLLEN* field_type_num TSRMLS_DC )
{
SQLRETURN r = ::SQLColAttribute( stmt->handle(), field_index, field_identifier, field_type_char,
buffer_length, out_buffer_length, field_type_num );
@ -1829,9 +1830,9 @@ namespace core {
}
inline void SQLDescribeCol( sqlsrv_stmt* stmt, SQLSMALLINT colno, __out_z SQLCHAR* col_name, SQLSMALLINT col_name_length,
__out SQLSMALLINT* col_name_length_out, SQLSMALLINT* data_type, __out SQLULEN* col_size,
__out SQLSMALLINT* decimal_digits, __out SQLSMALLINT* nullable TSRMLS_DC )
inline void SQLDescribeCol( sqlsrv_stmt* stmt, SQLSMALLINT colno, _Out_ SQLCHAR* col_name, SQLSMALLINT col_name_length,
_Out_ SQLSMALLINT* col_name_length_out, SQLSMALLINT* data_type, _Out_ SQLULEN* col_size,
_Out_ SQLSMALLINT* decimal_digits, _Out_ SQLSMALLINT* nullable TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLDescribeCol( stmt->handle(), colno, col_name, col_name_length, col_name_length_out,
@ -1914,7 +1915,7 @@ namespace core {
}
inline SQLRETURN SQLGetData( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLSMALLINT target_type,
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
_Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )
{
SQLRETURN r = ::SQLGetData( stmt->handle(), field_index, target_type, buffer, buffer_length, out_buffer_length );
@ -1936,8 +1937,8 @@ namespace core {
}
inline void SQLGetInfo( sqlsrv_conn* conn, SQLUSMALLINT info_type, __out SQLPOINTER info_value, SQLSMALLINT buffer_len,
__out SQLSMALLINT* str_len TSRMLS_DC )
inline void SQLGetInfo( sqlsrv_conn* conn, SQLUSMALLINT info_type, _Out_ SQLPOINTER info_value, SQLSMALLINT buffer_len,
_Out_ SQLSMALLINT* str_len TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLGetInfo( conn->handle(), info_type, info_value, buffer_len, str_len );
@ -1986,7 +1987,7 @@ namespace core {
// SQLParamData returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA when there are more
// parameters or when the parameters are all processed.
inline SQLRETURN SQLParamData( sqlsrv_stmt* stmt, __out SQLPOINTER* value_ptr_ptr TSRMLS_DC )
inline SQLRETURN SQLParamData( sqlsrv_stmt* stmt, _Out_ SQLPOINTER* value_ptr_ptr TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLParamData( stmt->handle(), value_ptr_ptr );
@ -2141,7 +2142,7 @@ namespace core {
}
}
inline void sqlsrv_array_init( sqlsrv_context& ctx, __out zval* new_array TSRMLS_DC)
inline void sqlsrv_array_init( sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC)
{
int zr = ::array_init(new_array);
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2158,7 +2159,7 @@ namespace core {
}
}
inline void sqlsrv_zend_hash_get_current_data(sqlsrv_context& ctx, HashTable* ht, __out zval*& output_data TSRMLS_DC)
inline void sqlsrv_zend_hash_get_current_data(sqlsrv_context& ctx, HashTable* ht, _Out_ zval*& output_data TSRMLS_DC)
{
int zr = (output_data = ::zend_hash_get_current_data(ht)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2166,7 +2167,7 @@ namespace core {
}
}
inline void sqlsrv_zend_hash_get_current_data_ptr(sqlsrv_context& ctx, HashTable* ht, __out void*& output_data TSRMLS_DC)
inline void sqlsrv_zend_hash_get_current_data_ptr(sqlsrv_context& ctx, HashTable* ht, _Out_ void*& output_data TSRMLS_DC)
{
int zr = (output_data = ::zend_hash_get_current_data_ptr(ht)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {

View file

@ -35,7 +35,7 @@ struct field_cache {
// if the value is NULL, then just record a NULL pointer
if( field_value != NULL ) {
value = sqlsrv_malloc( field_len );
memcpy( value, field_value, field_len );
memcpy_s( value, field_len, field_value, field_len );
len = field_len;
}
else {
@ -76,23 +76,23 @@ const size_t DATE_FORMAT_LEN = sizeof( DATE_FORMAT );
// *** internal functions ***
// Only declarations are put here. Functions contain the documentation they need at their definition sites.
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, __out SQLLEN& size TSRMLS_DC );
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, _Out_ SQLLEN& size TSRMLS_DC );
size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_end TSRMLS_DC );
bool check_for_next_stream_parameter( sqlsrv_stmt* stmt TSRMLS_DC );
bool convert_input_param_to_utf16( zval* input_param_z, zval* convert_param_z );
void core_get_field_common(__inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, __out void*& field_value, __out SQLLEN* field_len TSRMLS_DC);
void core_get_field_common(_Inout_ sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC);
// returns the ODBC C type constant that matches the PHP type and encoding given
SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* param_z, SQLSRV_ENCODING encoding TSRMLS_DC );
void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLULEN& column_size, __out SQLSMALLINT& decimal_digits TSRMLS_DC );
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC );
// given a zval and encoding, determine the appropriate sql type, column size, and decimal scale (if appropriate)
void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLSMALLINT& sql_type TSRMLS_DC );
_Out_ SQLSMALLINT& sql_type TSRMLS_DC );
void field_cache_dtor( zval* data_z );
void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC );
void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type,
__out void*& field_value, __out SQLLEN* field_len TSRMLS_DC );
_Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC );
stmt_option const* get_stmt_option( sqlsrv_conn const* conn, zend_ulong key, const stmt_option stmt_opts[] TSRMLS_DC );
bool is_valid_sqlsrv_phptype( sqlsrv_phptype type );
// assure there is enough space for the output parameter string
@ -607,6 +607,8 @@ void core_sqlsrv_bind_param(sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALLI
// This is equivalent to the PHP code: $param_z->format( $format_z ); where param_z is the
// DateTime object and $format_z is the format string.
int zr = call_user_function( EG( function_table ), param_z, &function_z, &buffer_z, 1, params TSRMLS_CC );
zend_string_release( Z_STR( format_z ));
zend_string_release( Z_STR( function_z ));
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
throw core::CoreException();
}
@ -706,7 +708,11 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_
catch( core::CoreException& e ) {
// if the statement executed but failed in a subsequent operation before returning,
// we need to cancel the statement
// we need to cancel the statement and deref the output and stream parameters
if ( stmt->send_streams_at_exec ) {
zend_hash_clean( Z_ARRVAL( stmt->output_params ));
zend_hash_clean( Z_ARRVAL( stmt->param_streams ));
}
if( stmt->executed ) {
SQLCancel( stmt->handle() );
// stmt->executed = false; should this be reset if something fails?
@ -864,8 +870,8 @@ field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT coln
// Nothing, excpetion thrown if an error occurs
void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type_in, bool prefer_string,
__out void*& field_value, __out SQLLEN* field_len, bool cache_field,
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC)
_Out_ void*& field_value, _Out_ SQLLEN* field_len, bool cache_field,
_Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC)
{
try {
@ -884,7 +890,7 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
else {
field_value = sqlsrv_malloc( cached->len, sizeof( char ), 1 );
memcpy( field_value, cached->value, cached->len );
memcpy_s( field_value, ( cached->len * sizeof( char )), cached->value, cached->len );
if( cached->type.typeinfo.type == SQLSRV_PHPTYPE_STRING) {
// prevent the 'string not null terminated' warning
reinterpret_cast<char*>( field_value )[ cached->len ] = '\0';
@ -1329,7 +1335,7 @@ void stmt_option_buffered_query_limit:: operator()( sqlsrv_stmt* stmt, stmt_opti
// internal function to release the active stream. Called by each main API function
// that will alter the statement and cancel any retrieval of data from a stream.
void close_active_stream( __inout sqlsrv_stmt* stmt TSRMLS_DC )
void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
{
// if there is no active stream, return
if( Z_TYPE( stmt->active_stream ) == IS_UNDEF ) {
@ -1372,7 +1378,7 @@ bool is_streamable_type( SQLLEN sql_type )
return false;
}
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, __out SQLLEN& size TSRMLS_DC )
void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, _Out_ SQLLEN& size TSRMLS_DC )
{
try {
@ -1468,8 +1474,8 @@ size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_e
// The memory allocation has to happen in the core layer because otherwise
// the driver layer would have to calculate size of the field_value
// to decide the amount of memory allocation.
void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, __out void*& field_value, __out SQLLEN* field_len TSRMLS_DC )
void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype
sqlsrv_php_type, _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC )
{
try {
@ -1554,13 +1560,10 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
zval params[1];
zval field_value_temp_z;
zval function_z;
zval_auto_ptr return_value_z;
ZVAL_UNDEF( &field_value_temp_z );
ZVAL_UNDEF( &function_z );
ZVAL_UNDEF( params );
return_value_z = (zval *)sqlsrv_malloc( sizeof( zval ));
ZVAL_UNDEF( return_value_z );
SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_CHAR, field_value_temp,
MAX_DATETIME_STRING_LEN, field_len, true TSRMLS_CC );
@ -1569,6 +1572,10 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
throw core::CoreException();
}
zval_auto_ptr return_value_z;
return_value_z = ( zval * )sqlsrv_malloc( sizeof( zval ));
ZVAL_UNDEF( return_value_z );
if( *field_len == SQL_NULL_DATA ) {
ZVAL_NULL( return_value_z );
field_value = reinterpret_cast<void*>( return_value_z.get());
@ -1599,9 +1606,6 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
case SQLSRV_PHPTYPE_STREAM:
{
zval_auto_ptr return_value_z;
return_value_z = (zval *)sqlsrv_malloc(sizeof(zval));
ZVAL_UNDEF(return_value_z);
php_stream* stream = NULL;
sqlsrv_stream* ss = NULL;
SQLLEN sql_type;
@ -1627,6 +1631,10 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
ss->sql_type = static_cast<SQLUSMALLINT>( sql_type );
ss->encoding = static_cast<SQLSRV_ENCODING>( sqlsrv_php_type.typeinfo.encoding );
zval_auto_ptr return_value_z;
return_value_z = ( zval * )sqlsrv_malloc( sizeof( zval ));
ZVAL_UNDEF( return_value_z );
// turn our stream into a zval to be returned
php_stream_to_zval( stream, return_value_z );
@ -1659,7 +1667,7 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
// check_for_next_stream_parameter
// see if there is another stream to be sent. Returns true and sets the stream as current in the statement structure, otherwise
// returns false
bool check_for_next_stream_parameter( __inout sqlsrv_stmt* stmt TSRMLS_DC )
bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
{
int stream_index = 0;
SQLRETURN r = SQL_SUCCESS;
@ -1810,7 +1818,7 @@ SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* para
// given a zval and encoding, determine the appropriate sql type
void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLSMALLINT& sql_type TSRMLS_DC )
_Out_ SQLSMALLINT& sql_type TSRMLS_DC )
{
sql_type = SQL_UNKNOWN_TYPE;
int php_type = Z_TYPE_P(param_z);
@ -1880,7 +1888,7 @@ void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV
// given a zval and encoding, determine the appropriate column size, and decimal scale (if appropriate)
void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z, SQLSRV_ENCODING encoding,
__out SQLULEN& column_size, __out SQLSMALLINT& decimal_digits TSRMLS_DC )
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC )
{
int php_type = Z_TYPE_P( param_z );
column_size = 0;
@ -1933,11 +1941,12 @@ void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval*
void field_cache_dtor( zval* data_z )
{
field_cache* cache = reinterpret_cast<field_cache*>(Z_PTR_P(data_z));
field_cache* cache = static_cast<field_cache*>( Z_PTR_P( data_z ));
if( cache->value )
{
sqlsrv_free( cache->value );
}
sqlsrv_free( cache );
}
@ -1968,6 +1977,7 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC )
char* str = Z_STRVAL_P( value_z );
SQLLEN str_len = stmt->param_ind_ptrs[ output_param->param_num ];
if( str_len == SQL_NULL_DATA ) {
zend_string_release( Z_STR_P( value_z ));
ZVAL_NULL( value_z );
continue;
}
@ -2044,7 +2054,7 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC )
}
void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type,
__out void*& field_value, __out SQLLEN* field_len TSRMLS_DC )
_Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC )
{
SQLRETURN r;
SQLSMALLINT c_type;
@ -2433,6 +2443,7 @@ void sqlsrv_output_param_dtor( zval* data )
{
sqlsrv_output_param *output_param = static_cast<sqlsrv_output_param*>( Z_PTR_P( data ));
zval_ptr_dtor( output_param->param_z ); // undo the reference to the string we will no longer hold
sqlsrv_free( output_param );
}
// called by Zend for each stream in the sqlsrv_stmt::param_streams hash table when it is cleaned/destroyed
@ -2440,6 +2451,7 @@ void sqlsrv_stream_dtor( zval* data )
{
sqlsrv_stream* stream_encoding = static_cast<sqlsrv_stream*>( Z_PTR_P( data ));
zval_ptr_dtor( stream_encoding->stream_z ); // undo the reference to the stream we will no longer hold
sqlsrv_free( stream_encoding );
}
}

View file

@ -45,7 +45,7 @@ int sqlsrv_stream_close( php_stream* stream, int /*close_handle*/ TSRMLS_DC )
// read from a sqlsrv stream into the buffer provided by Zend. The parameters for binary vs. char are
// set when sqlsrv_get_field is called by the user specifying which field type they want.
size_t sqlsrv_stream_read( php_stream* stream, __out_bcount(count) char* buf, size_t count TSRMLS_DC )
size_t sqlsrv_stream_read( php_stream* stream, _Out_writes_bytes_(count) char* buf, size_t count TSRMLS_DC )
{
SQLLEN read = 0;
SQLSMALLINT c_type = SQL_C_CHAR;
@ -203,8 +203,8 @@ php_stream_ops sqlsrv_stream_ops = {
// open a stream and return the sqlsrv_stream_ops function table as part of the
// return value. There is only one valid way to open a stream, using sqlsrv_get_field on
// certain field types. A sqlsrv stream may only be opened in read mode.
static php_stream* sqlsrv_stream_opener( php_stream_wrapper* wrapper, __in const char*, __in const char* mode,
int options, __in zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC )
static php_stream* sqlsrv_stream_opener( php_stream_wrapper* wrapper, _In_ const char*, _In_ const char* mode,
int options, _In_ zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC )
{
#if ZEND_DEBUG

View file

@ -33,9 +33,9 @@ SQLCHAR INTERNAL_FORMAT_ERROR[] = "An internal error occurred. FormatMessage fa
char last_err_msg[ 2048 ]; // 2k to hold the error messages
// routine used by utf16_string_from_mbcs_string
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, __in_bcount(mbcs_len) char const* mbcs_in_string,
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string,
unsigned int mbcs_len,
__out_ecount(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
_Out_writes_(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
unsigned int utf16_len );
}
@ -370,8 +370,8 @@ namespace {
// returned in utf16_out_string. An empty string passed in will result as
// a failure since MBTWC returns 0 for both an empty string and failure
// to convert.
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, __in_bcount(mbcs_len) char const* mbcs_in_string,
unsigned int mbcs_len, __out_ecount(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string,
unsigned int mbcs_len, _Out_writes_(utf16_len) __transfer( mbcs_in_string ) wchar_t* utf16_out_string,
unsigned int utf16_len )
{
unsigned int win_encoding = CP_ACP;

View file

@ -10,30 +10,28 @@
#define __msodbcsql_h__
#if !defined(SQLODBC_VER)
#define SQLODBC_VER 1300
#define SQLODBC_VER 1100
#endif
#if SQLODBC_VER >= 1300
#if SQLODBC_VER >= 1100
#define SQLODBC_PRODUCT_NAME_FULL_VER_ANSI "Microsoft ODBC Driver 13 for SQL Server"
#define SQLODBC_PRODUCT_NAME_FULL_VER_ANSI "Microsoft ODBC Driver 11 for SQL Server"
#define SQLODBC_PRODUCT_NAME_FULL_ANSI "Microsoft ODBC Driver for SQL Server"
#define SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI "ODBC Driver 13 for SQL Server"
#define SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI "ODBC Driver 11 for SQL Server"
#define SQLODBC_PRODUCT_NAME_SHORT_ANSI "ODBC Driver for SQL Server"
#define SQLODBC_FILE_NAME_ANSI "msodbcsql"
#define SQLODBC_FILE_NAME_VER_ANSI "msodbcsql13"
#define SQLODBC_FILE_NAME_FULL_ANSI "msodbcsql13.dll"
#define SQLODBC_FILE_NAME_VER_ANSI "msodbcsql11"
#define SQLODBC_FILE_NAME_FULL_ANSI "msodbcsql11.dll"
#define SQLODBC_PRODUCT_NAME_FULL_VER_UNICODE L"Microsoft ODBC Driver 13 for SQL Server"
#define SQLODBC_PRODUCT_NAME_FULL_VER_UNICODE L"Microsoft ODBC Driver 11 for SQL Server"
#define SQLODBC_PRODUCT_NAME_FULL_UNICODE L"Microsoft ODBC Driver for SQL Server"
#define SQLODBC_PRODUCT_NAME_SHORT_VER_UNICODE L"ODBC Driver 13 for SQL Server"
#define SQLODBC_PRODUCT_NAME_SHORT_VER_UNICODE L"ODBC Driver 11 for SQL Server"
#define SQLODBC_PRODUCT_NAME_SHORT_UNICODE L"ODBC Driver for SQL Server"
#define SQLODBC_FILE_NAME_UNICODE L"msodbcsql"
#define SQLODBC_FILE_NAME_VER_UNICODE L"msodbcsql13"
#define SQLODBC_FILE_NAME_FULL_UNICODE L"msodbcsql13.dll"
#define SQLODBC_FILE_NAME_VER_UNICODE L"msodbcsql11"
#define SQLODBC_FILE_NAME_FULL_UNICODE L"msodbcsql11.dll"
// define the character type agnostic constants
#if defined(_UNICODE) || defined(UNICODE)
@ -205,10 +203,6 @@ extern "C" {
#define SQL_COPT_SS_INTEGRATED_AUTHENTICATION_METHOD (SQL_COPT_SS_BASE+31) // The integrated authentication method used for the connection
#define SQL_COPT_SS_MUTUALLY_AUTHENTICATED (SQL_COPT_SS_BASE+32) // Used to decide if the connection is mutually authenticated
#define SQL_COPT_SS_CLIENT_CONNECTION_ID (SQL_COPT_SS_BASE+33) // Post connection attribute used to get the ConnectionID
#define SQL_COPT_SS_CLIENT_CERTIFICATE (SQL_COPT_SS_BASE+36) // Client certificate
#define SQL_COPT_SS_CLIENT_CERTIFICATE_FALLBACK (SQL_COPT_SS_BASE+37) // Client certificate fallback
// Define old names
#define SQL_REMOTE_PWD SQL_COPT_SS_REMOTE_PWD
#define SQL_USE_PROCEDURE_FOR_PREPARE SQL_COPT_SS_USE_PROC_FOR_PREP
@ -231,8 +225,7 @@ extern "C" {
#define SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS (SQL_SOPT_SS_BASE+10)// SQL service broker name
#define SQL_SOPT_SS_PARAM_FOCUS (SQL_SOPT_SS_BASE+11)// Direct subsequent calls to parameter related methods to set properties on constituent columns/parameters of container types
#define SQL_SOPT_SS_NAME_SCOPE (SQL_SOPT_SS_BASE+12)// Sets name scope for subsequent catalog function calls
#define SQL_SOPT_SS_COLUMN_ENCRYPTION (SQL_SOPT_SS_BASE+13)// Sets the column encryption mode
#define SQL_SOPT_SS_MAX_USED SQL_SOPT_SS_COLUMN_ENCRYPTION
#define SQL_SOPT_SS_MAX_USED SQL_SOPT_SS_NAME_SCOPE
// Define old names
#define SQL_TEXTPTR_LOGGING SQL_SOPT_SS_TEXTPTR_LOGGING
#define SQL_COPT_SS_BASE_EX 1240
@ -244,13 +237,7 @@ extern "C" {
#define SQL_COPT_SS_RESET_CONNECTION (SQL_COPT_SS_BASE_EX+6) // When this option is set, we will perform connection reset on next packet
#define SQL_COPT_SS_APPLICATION_INTENT (SQL_COPT_SS_BASE_EX+7) // Application Intent
#define SQL_COPT_SS_MULTISUBNET_FAILOVER (SQL_COPT_SS_BASE_EX+8) // Multi-subnet Failover
#define SQL_COPT_SS_TNIR (SQL_COPT_SS_BASE_EX+9) // Transparent Network IP Resolution
#define SQL_COPT_SS_COLUMN_ENCRYPTION (SQL_COPT_SS_BASE_EX+10) // Always Encrypted Enabled or Disabled
#define SQL_COPT_SS_AEKEYSTOREPROVIDER (SQL_COPT_SS_BASE_EX+11) // Used to load a keystore provider DLL
#define SQL_COPT_SS_AEKEYSTOREDATA (SQL_COPT_SS_BASE_EX+12) // Used to communicate with keystore providers
#define SQL_COPT_SS_AETRUSTEDCMKPATHS (SQL_COPT_SS_BASE_EX+13) // List of trusted CMK paths
#define SQL_COPT_SS_AECEKCACHETTL (SQL_COPT_SS_BASE_EX+14)// Symmetric Key Cache TTL
#define SQL_COPT_SS_EX_MAX_USED SQL_COPT_SS_AECEKCACHETTL
#define SQL_COPT_SS_EX_MAX_USED SQL_COPT_SS_MULTISUBNET_FAILOVER
// SQLColAttributes driver specific defines.
// SQLSetDescField/SQLGetDescField driver specific defines.
@ -300,10 +287,7 @@ extern "C" {
// Legacy datetime related metadata
#define SQL_CA_SS_SERVER_TYPE (SQL_CA_SS_BASE+35) // column type to send on the wire for datetime types
// force column encryption
#define SQL_CA_SS_FORCE_ENCRYPT (SQL_CA_SS_BASE+36) // indicate mandatory encryption for this parameter
#define SQL_CA_SS_MAX_USED (SQL_CA_SS_BASE+37)
#define SQL_CA_SS_MAX_USED (SQL_CA_SS_BASE+36)
// Defines returned by SQL_ATTR_CURSOR_TYPE/SQL_CURSOR_TYPE
#define SQL_CURSOR_FAST_FORWARD_ONLY 8 // Only returned by SQLGetStmtAttr/Option
@ -315,8 +299,6 @@ extern "C" {
// Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only
#define SQL_IS_OFF 0L // Integrated security isn't used
#define SQL_IS_ON 1L // Integrated security is used
#define SQL_IS_AD_OFF 2L // Active Directory integrated security isn't used
#define SQL_IS_AD_ON 3L // Active Directory integrated security is used
#define SQL_IS_DEFAULT SQL_IS_OFF
// Defines for use with SQL_COPT_SS_PRESERVE_CURSORS
#define SQL_PC_OFF 0L // Cursors are closed on SQLTransact
@ -371,16 +353,6 @@ extern "C" {
#define SQL_CO_FFO_AF (SQL_CO_FFO|SQL_CO_AF) // Fast-forward cursor with autofetch
#define SQL_CO_FIREHOSE_AF 4L // Auto fetch on fire-hose cursors
#define SQL_CO_DEFAULT SQL_CO_OFF
// Defines for use with SQL_SOPT_SS_COLUMN_ENCRYPTION
#define SQL_CE_DISABLED 0L // Disabled
#define SQL_CE_RESULTSETONLY 1L // Decryption Only (resultsets and return values)
#define SQL_CE_ENABLED 3L // Enabled (both encryption and decryption)
// Defines for use with SQL_COPT_SS_COLUMN_ENCRYPTION
#define SQL_COLUMN_ENCRYPTION_DISABLE 0L
#define SQL_COLUMN_ENCRYPTION_ENABLE 1L
#define SQL_COLUMN_ENCRYPTION_DEFAULT SQL_COLUMN_ENCRYPTION_DISABLE
// Defines for use with SQL_COPT_SS_AECEKCACHETTL
#define SQL_AECEKCACHETTL_DEFAULT 7200L // TTL value in seconds (2 hours)
//SQL_SOPT_SS_NOCOUNT_STATUS
#define SQL_NC_OFF 0L
#define SQL_NC_ON 1L
@ -916,7 +888,7 @@ extern "C" {
RETCODE SQL_API bcp_readfmtA (HDBC, LPCSTR);
RETCODE SQL_API bcp_readfmtW (HDBC, LPCWSTR);
RETCODE SQL_API bcp_sendrow (HDBC);
RETCODE SQL_API bcp_setbulkmode(HDBC, INT, __in_bcount(cbField) void*, INT cbField, __in_bcount(cbRow) void *, INT cbRow);
RETCODE SQL_API bcp_setbulkmode (HDBC, INT, _In_reads_bytes_(cbField) void*, INT cbField, _In_reads_bytes_(cbRow) void *, INT cbRow);
RETCODE SQL_API bcp_setcolfmt (HDBC, INT, INT, void *, INT);
RETCODE SQL_API bcp_writefmtA (HDBC, LPCSTR);
RETCODE SQL_API bcp_writefmtW (HDBC, LPCWSTR);
@ -955,60 +927,6 @@ extern "C" {
#define SQL_AO_DEFAULT SQL_AO_OFF
#define SQL_CA_SS_BASE_COLUMN_NAME SQL_DESC_BASE_COLUMN_NAME
// Keystore Provider interface definition
typedef void errFunc(void *ctx, const wchar_t *msg, ...);
#define IDS_MSG(x) ((const wchar_t*)(x))
typedef struct AEKeystoreProvider
{
wchar_t *Name;
int (*Init)(void *ctx, errFunc *onError);
int (*Read)(void *ctx, errFunc *onError, void *data, unsigned int *len);
int (*Write)(void *ctx, errFunc *onError, void *data, unsigned int len);
int (*DecryptCEK)(
void *ctx,
errFunc *onError,
const wchar_t *keyPath,
const wchar_t *alg,
unsigned char *ecek,
unsigned short ecek_len,
unsigned char **cek_out,
unsigned short *cek_len);
void (*Free)();
} AEKEYSTOREPROVIDER;
/* Data is defined to be past the end of the structure header.
This is accepted by MSVC, GCC, and C99 standard but former emits
unnecessary warning, hence it has to be disabled.
*/
#pragma warning(push)
#pragma warning(disable:4200)
typedef struct AEKeystoreData
{
wchar_t *Name;
unsigned int dataSize;
char Data[];
} AEKEYSTOREPROVIDERDATA;
#pragma warning(pop)
// The following constants are for the Azure Key Vault configuration interface
#define AKV_CONFIG_FLAGS 0
#define AKVCFG_USECLIENTID 0x00000001
#define AKVCFG_AUTORENEW 0x00000002
#define AKV_CONFIG_CLIENTID 1
#define AKV_CONFIG_CLIENTKEY 2
#define AKV_CONFIG_ACCESSTOKEN 3
#define AKV_CONFIG_TOKENEXPIRY 4
#define AKV_CONFIG_MAXRETRIES 5
#define AKV_CONFIG_RETRYTIMEOUT 6
#define AKV_CONFIG_RETRYWAIT 7
#ifdef __cplusplus
} // extern "C"
@ -1040,7 +958,7 @@ extern "C" {
LPCWSTR FilestreamPath,
SQL_FILESTREAM_DESIRED_ACCESS DesiredAccess,
ULONG OpenOptions,
__in_bcount(FilestreamTransactionContextLength)
_In_reads_bytes_(FilestreamTransactionContextLength)
LPBYTE FilestreamTransactionContext,
SSIZE_T FilestreamTransactionContextLength,
PLARGE_INTEGER AllocationSize);
@ -1055,13 +973,10 @@ extern "C" {
#define SQL_COPT_SS_CONNECT_RETRY_COUNT (SQL_COPT_SS_BASE+34) // Post connection attribute used to get ConnectRetryCount
#define SQL_COPT_SS_CONNECT_RETRY_INTERVAL (SQL_COPT_SS_BASE+35) // Post connection attribute used to get ConnectRetryInterval
#define SQL_COPT_SS_CLIENT_CERTIFICATE (SQL_COPT_SS_BASE+36) // Client certificate
#define SQL_COPT_SS_CLIENT_CERTIFICATE_FALLBACK (SQL_COPT_SS_BASE+37) // Client certificate fallback
#ifdef SQL_COPT_SS_MAX_USED
#undef SQL_COPT_SS_MAX_USED
#endif // SQL_COPT_SS_MAX_USED
#define SQL_COPT_SS_MAX_USED SQL_COPT_SS_CLIENT_CERTIFICATE_FALLBACK
#define SQL_COPT_SS_MAX_USED SQL_COPT_SS_CONNECT_RETRY_INTERVAL
#ifndef _SQLUSERINSTANCE_H_
@ -1073,19 +988,6 @@ extern "C" {
extern "C" {
#endif
struct _CERT_CONTEXT;
typedef _CERT_CONTEXT CERT_CONTEXT;
typedef const CERT_CONTEXT *PCCERT_CONTEXT;
// type definition for client certificate fallback function
typedef DWORD(WINAPI *PFnClientCertificateFallback)(
__in BOOL fHash,
__in_z LPCWSTR pszCertificate,
__out PCCERT_CONTEXT *ppCertContext,
__out DWORD *pdwFlags,
__out ULONG cchKeyContainer,
__out_ecount(cchKeyContainer) WCHAR *pwchKeyContainer
);
// Recommended buffer size to store a LocalDB connection string
#define LOCALDB_MAX_SQLCONNECTION_BUFFER_SIZE 260
@ -1093,11 +995,11 @@ extern "C" {
// type definition for LocalDBCreateInstance function
typedef HRESULT __cdecl FnLocalDBCreateInstance (
// I the LocalDB version (e.g. 11.0 or 11.0.1094.2)
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
);
// type definition for pointer to LocalDBCreateInstance function
@ -1106,14 +1008,14 @@ extern "C" {
// type definition for LocalDBStartInstance function
typedef HRESULT __cdecl FnLocalDBStartInstance (
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// O the buffer to store the connection string to the LocalDB instance
__out_ecount_z_opt(*lpcchSqlConnection) LPWSTR wszSqlConnection,
_Out_writes_opt_z_(*lpcchSqlConnection) LPWSTR wszSqlConnection,
// I/O on input has the size of the wszSqlConnection buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null.
__inout_opt LPDWORD lpcchSqlConnection
_Inout_opt_ LPDWORD lpcchSqlConnection
);
// type definition for pointer to LocalDBStartInstance function
@ -1125,19 +1027,19 @@ extern "C" {
// type definition for LocalDBFormatMessage function
typedef HRESULT __cdecl FnLocalDBFormatMessage(
// I the LocalDB error code
__in HRESULT hrLocalDB,
_In_ HRESULT hrLocalDB,
// I Available flags:
// LOCALDB_TRUNCATE_ERR_MESSAGE - if the input buffer is too short,
// the error message will be truncated to fit into the buffer
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I Language desired (LCID) or 0 (in which case Win32 FormatMessage order is used)
__in DWORD dwLanguageId,
_In_ DWORD dwLanguageId,
// O the buffer to store the LocalDB error message
__out_ecount_z(*lpcchMessage) LPWSTR wszMessage,
_Out_writes_z_(*lpcchMessage) LPWSTR wszMessage,
// I/O on input has the size of the wszMessage buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null. If the function succeeds
// contains the number of characters in the message, excluding the trailing null
__inout LPDWORD lpcchMessage
_Inout_ LPDWORD lpcchMessage
);
// type definition for function pointer to LocalDBFormatMessage function
@ -1210,14 +1112,14 @@ extern "C" {
// type definition for LocalDBStopInstance function
typedef HRESULT __cdecl FnLocalDBStopInstance (
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I Available flags:
// LOCALDB_SHUTDOWN_KILL_PROCESS - force the instance to stop immediately
// LOCALDB_SHUTDOWN_WITH_NOWAIT - shutdown the instance with NOWAIT option
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I the time in seconds to wait this operation to complete. If this value is 0, this function will return immediately
// without waiting for LocalDB instance to stop
__in ULONG ulTimeout
_In_ ULONG ulTimeout
);
// type definition for pointer to LocalDBStopInstance function
@ -1247,9 +1149,9 @@ extern "C" {
// type definition for LocalDBDeleteInstance function
typedef HRESULT __cdecl FnLocalDBDeleteInstance (
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
);
// type definition for pointer to LocalDBDeleteInstance function
@ -1300,10 +1202,10 @@ extern "C" {
// type definition for LocalDBGetInstances function
typedef HRESULT __cdecl FnLocalDBGetInstances(
// O buffer for a LocalDB instance names
__out PTLocalDBInstanceName pInstanceNames,
_Out_ PTLocalDBInstanceName pInstanceNames,
// I/O on input has the number slots for instance names in the pInstanceNames buffer. On output,
// has the number of existing LocalDB instances
__inout LPDWORD lpdwNumberOfInstances
_Inout_ LPDWORD lpdwNumberOfInstances
);
// type definition for pointer to LocalDBGetInstances function
@ -1365,11 +1267,11 @@ extern "C" {
// type definition for LocalDBGetInstanceInfo function
typedef HRESULT __cdecl FnLocalDBGetInstanceInfo(
// I the LocalDB instance name
__in_z PCWSTR wszInstanceName,
_In_z_ PCWSTR wszInstanceName,
// O instance information
__out PLocalDBInstanceInfo pInfo,
_Out_ PLocalDBInstanceInfo pInfo,
// I Size of LocalDBInstanceInfo structure in bytes
__in DWORD cbInfo);
_In_ DWORD cbInfo);
// type definition for pointer to LocalDBGetInstances function
typedef FnLocalDBGetInstanceInfo* PFnLocalDBGetInstanceInfo;
@ -1396,10 +1298,10 @@ extern "C" {
// type definition for LocalDBGetVersions function
typedef HRESULT __cdecl FnLocalDBGetVersions(
// O buffer for installed LocalDB versions
__out PTLocalDBVersion pVersions,
_Out_ PTLocalDBVersion pVersions,
// I/O on input has the number slots for versions in the pVersions buffer. On output,
// has the number of existing LocalDB versions
__inout LPDWORD lpdwNumberOfVersions
_Inout_ LPDWORD lpdwNumberOfVersions
);
// type definition for pointer to LocalDBGetVersions function
@ -1450,11 +1352,11 @@ extern "C" {
// type definition for LocalDBGetVersionInfo function
typedef HRESULT __cdecl FnLocalDBGetVersionInfo(
// I LocalDB version string
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// O version information
__out PLocalDBVersionInfo pVersionInfo,
_Out_ PLocalDBVersionInfo pVersionInfo,
// I Size of LocalDBVersionInfo structure in bytes
__in DWORD cbVersionInfo
_In_ DWORD cbVersionInfo
);
// type definition for pointer to LocalDBGetVersionInfo function
@ -1500,13 +1402,13 @@ extern "C" {
// type definition for LocalDBShareInstance function
typedef HRESULT __cdecl FnLocalDBShareInstance(
// I the SID of the LocalDB instance owner
__in_opt PSID pOwnerSID,
_In_opt_ PSID pOwnerSID,
// I the private name of LocalDB instance which should be shared
__in_z PCWSTR wszPrivateLocalDBInstanceName,
_In_z_ PCWSTR wszPrivateLocalDBInstanceName,
// I the public shared name
__in_z PCWSTR wszSharedName,
_In_z_ PCWSTR wszSharedName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags);
_In_ DWORD dwFlags);
// type definition for pointer to LocalDBShareInstance function
typedef FnLocalDBShareInstance* PFnLocalDBShareInstance;
@ -1524,9 +1426,9 @@ extern "C" {
// type definition for LocalDBUnshareInstance function
typedef HRESULT __cdecl FnLocalDBUnshareInstance(
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags);
_In_ DWORD dwFlags);
// type definition for pointer to LocalDBUnshareInstance function
typedef FnLocalDBUnshareInstance* PFnLocalDBUnshareInstance;
@ -1751,11 +1653,11 @@ static HRESULT LocalDBGetPFn(LPCSTR szLocalDBFn, FARPROC *pfnLocalDBFn)
HRESULT __cdecl
LocalDBCreateInstance (
// I the LocalDB version (e.g. 11.0 or 11.0.1094.2)
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
)
{
LOCALDB_PROXY(LocalDBCreateInstance)(wszVersion, pInstanceName, dwFlags);
@ -1764,14 +1666,14 @@ LocalDBCreateInstance(
HRESULT __cdecl
LocalDBStartInstance(
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// O the buffer to store the connection string to the LocalDB instance
__out_ecount_z_opt(*lpcchSqlConnection) LPWSTR wszSqlConnection,
_Out_writes_z__opt(*lpcchSqlConnection) LPWSTR wszSqlConnection,
// I/O on input has the size of the wszSqlConnection buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null.
__inout_opt LPDWORD lpcchSqlConnection
_Inout_opt_ LPDWORD lpcchSqlConnection
)
{
LOCALDB_PROXY(LocalDBStartInstance)(pInstanceName, dwFlags, wszSqlConnection, lpcchSqlConnection);
@ -1780,14 +1682,14 @@ LocalDBStartInstance(
HRESULT __cdecl
LocalDBStopInstance (
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I Available flags:
// LOCALDB_SHUTDOWN_KILL_PROCESS - force the instance to stop immediately
// LOCALDB_SHUTDOWN_WITH_NOWAIT - shutdown the instance with NOWAIT option
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I the time in seconds to wait this operation to complete. If this value is 0, this function will return immediately
// without waiting for LocalDB instance to stop
__in ULONG ulTimeout
_In_ ULONG ulTimeout
)
{
LOCALDB_PROXY(LocalDBStopInstance)(pInstanceName, dwFlags, ulTimeout);
@ -1796,9 +1698,9 @@ LocalDBStopInstance(
HRESULT __cdecl
LocalDBDeleteInstance (
// I the instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags
_In_ DWORD dwFlags
)
{
LOCALDB_PROXY(LocalDBDeleteInstance)(pInstanceName, dwFlags);
@ -1807,19 +1709,19 @@ LocalDBDeleteInstance(
HRESULT __cdecl
LocalDBFormatMessage(
// I the LocalDB error code
__in HRESULT hrLocalDB,
_In_ HRESULT hrLocalDB,
// I Available flags:
// LOCALDB_TRUNCATE_ERR_MESSAGE - if the input buffer is too short,
// the error message will be truncated to fit into the buffer
__in DWORD dwFlags,
_In_ DWORD dwFlags,
// I Language desired (LCID) or 0 (in which case Win32 FormatMessage order is used)
__in DWORD dwLanguageId,
_In_ DWORD dwLanguageId,
// O the buffer to store the LocalDB error message
__out_ecount_z(*lpcchMessage) LPWSTR wszMessage,
_Out_writes_z_(*lpcchMessage) LPWSTR wszMessage,
// I/O on input has the size of the wszMessage buffer in characters. On output, if the given buffer size is
// too small, has the buffer size required, in characters, including trailing null. If the function succeeds
// contains the number of characters in the message, excluding the trailing null
__inout LPDWORD lpcchMessage
_Inout_ LPDWORD lpcchMessage
)
{
LOCALDB_PROXY(LocalDBFormatMessage)(hrLocalDB, dwFlags, dwLanguageId, wszMessage, lpcchMessage);
@ -1828,10 +1730,10 @@ LocalDBFormatMessage(
HRESULT __cdecl
LocalDBGetInstances(
// O buffer with instance names
__out PTLocalDBInstanceName pInstanceNames,
_Out_ PTLocalDBInstanceName pInstanceNames,
// I/O on input has the number slots for instance names in the pInstanceNames buffer. On output,
// has the number of existing LocalDB instances
__inout LPDWORD lpdwNumberOfInstances
_Inout_ LPDWORD lpdwNumberOfInstances
)
{
LOCALDB_PROXY(LocalDBGetInstances)(pInstanceNames, lpdwNumberOfInstances);
@ -1840,11 +1742,11 @@ LocalDBGetInstances(
HRESULT __cdecl
LocalDBGetInstanceInfo(
// I the instance name
__in_z PCWSTR wszInstanceName,
_In_z_ PCWSTR wszInstanceName,
// O instance information
__out PLocalDBInstanceInfo pInfo,
_Out_ PLocalDBInstanceInfo pInfo,
// I Size of LocalDBInstanceInfo structure in bytes
__in DWORD cbInfo
_In_ DWORD cbInfo
)
{
LOCALDB_PROXY(LocalDBGetInstanceInfo)(wszInstanceName, pInfo, cbInfo);
@ -1865,13 +1767,13 @@ LocalDBStopTracing()
HRESULT __cdecl
LocalDBShareInstance(
// I the SID of the LocalDB instance owner
__in_opt PSID pOwnerSID,
_In_opt_ PSID pOwnerSID,
// I the private name of LocalDB instance which should be shared
__in_z PCWSTR wszLocalDBInstancePrivateName,
_In_z_ PCWSTR wszLocalDBInstancePrivateName,
// I the public shared name
__in_z PCWSTR wszSharedName,
_In_z_ PCWSTR wszSharedName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags)
_In_ DWORD dwFlags)
{
LOCALDB_PROXY(LocalDBShareInstance)(pOwnerSID, wszLocalDBInstancePrivateName, wszSharedName, dwFlags);
}
@ -1879,10 +1781,10 @@ LocalDBShareInstance(
HRESULT __cdecl
LocalDBGetVersions(
// O buffer for installed LocalDB versions
__out PTLocalDBVersion pVersions,
_Out_ PTLocalDBVersion pVersions,
// I/O on input has the number slots for versions in the pVersions buffer. On output,
// has the number of existing LocalDB versions
__inout LPDWORD lpdwNumberOfVersions
_Inout_ LPDWORD lpdwNumberOfVersions
)
{
LOCALDB_PROXY(LocalDBGetVersions)(pVersions, lpdwNumberOfVersions);
@ -1891,9 +1793,9 @@ LocalDBGetVersions(
HRESULT __cdecl
LocalDBUnshareInstance(
// I the LocalDB instance name
__in_z PCWSTR pInstanceName,
_In_z_ PCWSTR pInstanceName,
// I reserved for the future use. Currently should be set to 0.
__in DWORD dwFlags)
_In_ DWORD dwFlags)
{
LOCALDB_PROXY(LocalDBUnshareInstance)(pInstanceName, dwFlags);
}
@ -1901,11 +1803,11 @@ LocalDBUnshareInstance(
HRESULT __cdecl
LocalDBGetVersionInfo(
// I LocalDB version string
__in_z PCWSTR wszVersion,
_In_z_ PCWSTR wszVersion,
// O version information
__out PLocalDBVersionInfo pVersionInfo,
_Out_ PLocalDBVersionInfo pVersionInfo,
// I Size of LocalDBVersionInfo structure in bytes
__in DWORD cbVersionInfo)
_In_ DWORD cbVersionInfo)
{
LOCALDB_PROXY(LocalDBGetVersionInfo)(wszVersion, pVersionInfo, cbVersionInfo);
}

View file

@ -368,13 +368,13 @@ PHP_FUNCTION(sqlsrv_errors);
// bytes. The return is the number of UTF-16 characters in the string
// returned in utf16_out_string.
unsigned int convert_string_from_default_encoding( unsigned int php_encoding, char const* mbcs_in_string,
unsigned int mbcs_len, __out wchar_t* utf16_out_string,
unsigned int mbcs_len, _Out_ wchar_t* utf16_out_string,
unsigned int utf16_len );
// create a wide char string from the passed in mbcs string. NULL is returned if the string
// could not be created. No error is posted by this function. utf16_len is the number of
// wchar_t characters, not the number of bytes.
wchar_t* utf16_string_from_mbcs_string( unsigned int php_encoding, const char* mbcs_string,
unsigned int mbcs_len, __out unsigned int* utf16_len );
unsigned int mbcs_len, _Out_ unsigned int* utf16_len );
// *** internal error macros and functions ***
bool handle_error( sqlsrv_context const* ctx, int log_subsystem, const char* function,
@ -604,7 +604,7 @@ namespace ss {
}
};
inline void zend_register_resource(__out zval& rsrc_result, void* rsrc_pointer, int rsrc_type, char* rsrc_name TSRMLS_DC)
inline void zend_register_resource(_Out_ zval& rsrc_result, void* rsrc_pointer, int rsrc_type, char* rsrc_name TSRMLS_DC)
{
int zr = (NULL != (Z_RES(rsrc_result) = ::zend_register_resource(rsrc_pointer, rsrc_type)) ? SUCCESS : FAILURE);
CHECK_CUSTOM_ERROR(( zr == FAILURE ), reinterpret_cast<sqlsrv_context*>( rsrc_pointer ), SS_SQLSRV_ERROR_REGISTER_RESOURCE,

View file

@ -90,21 +90,21 @@ const char SS_SQLSRV_WARNING_PARAM_VAR_NOT_REF[] = "Variable parameter %d not pa
void convert_to_zval( sqlsrv_stmt* stmt, SQLSRV_PHPTYPE sqlsrv_php_type, void* in_val, SQLLEN field_len, zval& out_zval );
void fetch_fields_common( __inout ss_sqlsrv_stmt* stmt, zend_long fetch_type, __out zval& fields, bool allow_empty_field_names
void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, zend_long fetch_type, _Out_ zval& fields, bool allow_empty_field_names
TSRMLS_DC );
bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype sqlsrv_type, __out SQLULEN* column_size,
__out SQLSMALLINT* decimal_digits );
bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype sqlsrv_type, _Out_ SQLULEN* column_size,
_Out_ SQLSMALLINT* decimal_digits );
sqlsrv_phptype determine_sqlsrv_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string );
void determine_stmt_has_rows( ss_sqlsrv_stmt* stmt TSRMLS_DC );
bool is_valid_sqlsrv_phptype( sqlsrv_phptype type );
bool is_valid_sqlsrv_sqltype( sqlsrv_sqltype type );
void parse_param_array( ss_sqlsrv_stmt* stmt, __inout zval* param_array, zend_ulong index, __out SQLSMALLINT& direction,
__out SQLSRV_PHPTYPE& php_out_type, __out SQLSRV_ENCODING& encoding, __out SQLSMALLINT& sql_type,
__out SQLULEN& column_size, __out SQLSMALLINT& decimal_digits TSRMLS_DC );
void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction,
_Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC );
void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, int type );
void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, int type );
void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, int type );
bool verify_and_set_encoding( const char* encoding_string, __out sqlsrv_phptype& phptype_encoding TSRMLS_DC );
bool verify_and_set_encoding( const char* encoding_string, _Out_ sqlsrv_phptype& phptype_encoding TSRMLS_DC );
}
@ -814,6 +814,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
zend_class_entry* class_entry = NULL;
zend_string* class_name_str_z = zend_string_init( class_name, class_name_len, 0 );
int zr = ( NULL != ( class_entry = zend_lookup_class( class_name_str_z TSRMLS_CC ))) ? SUCCESS : FAILURE;
zend_string_release( class_name_str_z );
CHECK_ZEND_ERROR( zr, stmt, SS_SQLSRV_ERROR_ZEND_BAD_CLASS, class_name ) {
throw ss::SSException();
}
@ -831,6 +832,8 @@ PHP_FUNCTION( sqlsrv_fetch_object )
// default parameters directly in the object, meaning the default property value is changed when
// the object's property is changed.
zend_merge_properties( &retval_z, properties_ht TSRMLS_CC );
zend_hash_destroy( properties_ht );
FREE_HASHTABLE( properties_ht );
// find and call the object's constructor
@ -907,6 +910,10 @@ PHP_FUNCTION( sqlsrv_fetch_object )
zend_hash_destroy( properties_ht );
FREE_HASHTABLE( properties_ht );
}
else if ( Z_TYPE( retval_z ) == IS_ARRAY ) {
zend_hash_destroy( Z_ARRVAL( retval_z ));
FREE_HASHTABLE( Z_ARRVAL( retval_z ));
}
RETURN_FALSE;
}
@ -1277,6 +1284,7 @@ void bind_params( ss_sqlsrv_stmt* stmt TSRMLS_DC )
catch( core::CoreException& ) {
SQLFreeStmt( stmt->handle(), SQL_RESET_PARAMS );
zval_ptr_dtor( stmt->params_z );
sqlsrv_free( stmt->params_z );
stmt->params_z = NULL;
throw;
}
@ -1536,8 +1544,8 @@ void convert_to_zval(sqlsrv_stmt* stmt, SQLSRV_PHPTYPE sqlsrv_php_type, void* in
// put in the column size and scale/decimal digits of the sql server type
// these values are taken from the MSDN page at http://msdn2.microsoft.com/en-us/library/ms711786(VS.85).aspx
bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype sqlsrv_type, __out SQLULEN* column_size,
__out SQLSMALLINT* decimal_digits )
bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype sqlsrv_type, _Out_ SQLULEN* column_size,
_Out_ SQLSMALLINT* decimal_digits )
{
*decimal_digits = 0;
@ -1785,7 +1793,7 @@ void determine_stmt_has_rows( ss_sqlsrv_stmt* stmt TSRMLS_DC )
}
}
void fetch_fields_common( __inout ss_sqlsrv_stmt* stmt, zend_long fetch_type, __out zval& fields, bool allow_empty_field_names
void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, zend_long fetch_type, _Out_ zval& fields, bool allow_empty_field_names
TSRMLS_DC )
{
void* field_value = NULL;
@ -1815,7 +1823,7 @@ void fetch_fields_common( __inout ss_sqlsrv_stmt* stmt, zend_long fetch_type, __
core::SQLColAttribute(stmt, i + 1, SQL_DESC_NAME, field_name_temp, SS_MAXCOLNAMELEN + 1, &field_name_len, NULL
TSRMLS_CC);
field_names[i].name = static_cast<char*>( sqlsrv_malloc( field_name_len, sizeof(char), 1 ));
memcpy(( void* )field_names[i].name, field_name_temp, field_name_len);
memcpy_s(( void* )field_names[i].name, ( field_name_len * sizeof( char )) ,field_name_temp, field_name_len);
field_names[i].name[field_name_len] = '\0'; // null terminate the field name since SQLColAttribute doesn't.
field_names[i].len = field_name_len + 1;
}
@ -1864,7 +1872,7 @@ void fetch_fields_common( __inout ss_sqlsrv_stmt* stmt, zend_long fetch_type, __
}
}
//only addref when the fetch_type is BOTH because this is the only case when fields(hashtable)
//has 2 elements pointing to field. Do not addref if the type is NUMBERIC or ASSOC because
//has 2 elements pointing to field. Do not addref if the type is NUMERIC or ASSOC because
//fields now only has 1 element pointing to field and we want the ref count to be only 1
if (fetch_type == SQLSRV_FETCH_BOTH) {
Z_TRY_ADDREF(field);
@ -1873,9 +1881,9 @@ void fetch_fields_common( __inout ss_sqlsrv_stmt* stmt, zend_long fetch_type, __
}
void parse_param_array( ss_sqlsrv_stmt* stmt, __inout zval* param_array, zend_ulong index, __out SQLSMALLINT& direction,
__out SQLSRV_PHPTYPE& php_out_type, __out SQLSRV_ENCODING& encoding, __out SQLSMALLINT& sql_type,
__out SQLULEN& column_size, __out SQLSMALLINT& decimal_digits TSRMLS_DC )
void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction,
_Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC )
{
zval* var_or_val = NULL;
@ -2109,7 +2117,7 @@ bool is_valid_sqlsrv_sqltype( sqlsrv_sqltype sql_type )
// verify an encoding given to type_and_encoding by looking through the list
// of standard encodings created at module initialization time
bool verify_and_set_encoding( const char* encoding_string, __out sqlsrv_phptype& phptype_encoding TSRMLS_DC )
bool verify_and_set_encoding( const char* encoding_string, _Out_ sqlsrv_phptype& phptype_encoding TSRMLS_DC )
{
void* encoding_temp = NULL;
zend_ulong index = -1;

View file

@ -43,7 +43,7 @@ bool handle_errors_and_warnings( sqlsrv_context& ctx, zval* reported_chain, zval
unsigned int sqlsrv_error_code, bool warning, va_list* print_args TSRMLS_DC );
int sqlsrv_merge_zend_hash_dtor( zval* dest TSRMLS_DC );
bool sqlsrv_merge_zend_hash( __inout zval* dest_z, zval const* src_z TSRMLS_DC );
bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z TSRMLS_DC );
}
@ -300,8 +300,8 @@ ss_error SS_ERRORS[] = {
{
SQLSRV_ERROR_DRIVER_NOT_INSTALLED,
{ IMSSP, (SQLCHAR*) "This extension requires the Microsoft ODBC Driver 11 for SQL Server. "
"Access the following URL to download the ODBC Driver 11 for SQL Server for %1!s!: "
{ IMSSP, (SQLCHAR*) "This extension requires the Microsoft ODBC Driver 11 or 13 for SQL Server. "
"Access the following URL to download the ODBC Driver 11 or 13 for SQL Server for %1!s!: "
"http://go.microsoft.com/fwlink/?LinkId=163712", -49, true }
},
@ -478,18 +478,18 @@ PHP_FUNCTION( sqlsrv_errors )
}
if( flags == SQLSRV_ERR_ALL || flags == SQLSRV_ERR_ERRORS ) {
if( Z_TYPE( SQLSRV_G( errors )) == IS_ARRAY && !sqlsrv_merge_zend_hash( &err_z, &SQLSRV_G( errors ) TSRMLS_CC )) {
zval_ptr_dtor(&err_z);
RETURN_FALSE;
}
}
if( flags == SQLSRV_ERR_ALL || flags == SQLSRV_ERR_WARNINGS ) {
if( Z_TYPE( SQLSRV_G( warnings )) == IS_ARRAY && !sqlsrv_merge_zend_hash( &err_z, &SQLSRV_G( warnings ) TSRMLS_CC )) {
zval_ptr_dtor(&err_z);
RETURN_FALSE;
}
}
if( zend_hash_num_elements( Z_ARRVAL_P( &err_z )) == 0 ) {
zval_ptr_dtor(&err_z);
RETURN_NULL();
}
RETURN_ZVAL( &err_z, 1, 1 );
@ -888,7 +888,7 @@ int sqlsrv_merge_zend_hash_dtor( zval* dest TSRMLS_DC )
// sqlsrv_merge_zend_hash
// merge a source hash into a dest hash table and return any errors.
bool sqlsrv_merge_zend_hash( __inout zval* dest_z, zval const* src_z TSRMLS_DC )
bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z TSRMLS_DC )
{
if( Z_TYPE_P( dest_z ) != IS_ARRAY && Z_TYPE_P( dest_z ) != IS_NULL ) DIE( "dest_z must be an array or null" );
if( Z_TYPE_P( src_z ) != IS_ARRAY && Z_TYPE_P( src_z ) != IS_NULL ) DIE( "src_z must be an array or null" );