1999-09-28 20:08:34 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| PHP version 4.0 |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-01-01 09:32:05 +08:00
| Copyright ( c ) 1997 , 1998 , 1999 , 2000 The PHP Group |
1999-09-28 20:08:34 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-05-18 23:34:45 +08:00
| This source file is subject to version 2.02 of the PHP license , |
1999-09-28 20:08:34 +08:00
| that is bundled with this package in the file LICENSE , and is |
| available at through the world - wide - web at |
2000-05-18 23:34:45 +08:00
| http : //www.php.net/license/2_02.txt. |
1999-09-28 20:08:34 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-04-19 23:21:22 +08:00
| Authors : Zeev Suraski < zeev @ zend . com > |
| Zeus Support : Ben Mansell < ben @ zeus . com > |
1999-09-28 20:08:34 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2000-02-19 01:59:44 +08:00
# ifdef PHP_WIN32
1999-09-28 20:08:34 +08:00
# include <windows.h>
2000-02-19 01:59:44 +08:00
# include <process.h>
2000-04-12 17:48:26 +08:00
# define SEPARATOR '\\'
2000-02-19 01:59:44 +08:00
# else
# define __try
# define __except(val)
2000-04-12 17:48:26 +08:00
# define __declspec(foo)
# define SEPARATOR ' / '
1999-09-28 20:08:34 +08:00
# endif
2000-02-19 01:59:44 +08:00
1999-09-28 00:34:28 +08:00
# include <httpext.h>
# include <httpfilt.h>
# include <httpext.h>
# include "php.h"
2000-06-06 07:24:42 +08:00
# include "php_main.h"
1999-09-28 00:34:28 +08:00
# include "SAPI.h"
# include "php_globals.h"
# include "ext/standard/info.h"
2000-01-29 01:24:53 +08:00
# include "php_variables.h"
2000-02-19 01:59:44 +08:00
# include "php_ini.h"
1999-09-28 00:34:28 +08:00
1999-11-15 03:46:31 +08:00
# ifdef WITH_ZEUS
2000-04-12 17:48:26 +08:00
# include "httpext.h"
# include <errno.h>
# define GetLastError() errno
1999-11-15 03:46:31 +08:00
# endif
1999-09-28 20:08:34 +08:00
1999-09-28 00:34:28 +08:00
# define MAX_STATUS_LENGTH sizeof("xxxx LONGEST STATUS DESCRIPTION")
# define ISAPI_SERVER_VAR_BUF_SIZE 1024
# define ISAPI_POST_DATA_BUF 1024
2000-02-17 00:46:01 +08:00
static zend_bool bFilterLoaded = 0 ;
2000-02-19 01:59:44 +08:00
static zend_bool bTerminateThreadsOnError = 0 ;
1999-09-28 00:34:28 +08:00
static char * isapi_server_variables [ ] = {
" ALL_HTTP " ,
" APPL_MD_PATH " ,
" APPL_PHYSICAL_PATH " ,
" AUTH_PASSWORD " ,
" AUTH_TYPE " ,
" AUTH_USER " ,
" CERT_COOKIE " ,
" CERT_FLAGS " ,
" CERT_ISSUER " ,
" CERT_KEYSIZE " ,
" CERT_SECRETKEYSIZE " ,
" CERT_SERIALNUMBER " ,
" CERT_SERVER_ISSUER " ,
" CERT_SERVER_SUBJECT " ,
" CERT_SUBJECT " ,
" CONTENT_LENGTH " ,
" CONTENT_TYPE " ,
" LOGON_USER " ,
" HTTP_COOKIE " ,
" HTTPS " ,
" HTTPS_KEYSIZE " ,
" HTTPS_SECRETKEYSIZE " ,
" HTTPS_SERVER_ISSUER " ,
" HTTPS_SERVER_SUBJECT " ,
" INSTANCE_ID " ,
" INSTANCE_META_PATH " ,
" PATH_INFO " ,
" PATH_TRANSLATED " ,
" QUERY_STRING " ,
" REMOTE_ADDR " ,
" REMOTE_HOST " ,
" REMOTE_USER " ,
" REQUEST_METHOD " ,
" SCRIPT_NAME " ,
" SERVER_NAME " ,
" SERVER_PORT " ,
" SERVER_PORT_SECURE " ,
" SERVER_PROTOCOL " ,
" SERVER_SOFTWARE " ,
" URL " ,
NULL
} ;
static void php_info_isapi ( ZEND_MODULE_INFO_FUNC_ARGS )
{
char * * p = isapi_server_variables ;
char variable_buf [ ISAPI_SERVER_VAR_BUF_SIZE ] ;
DWORD variable_len ;
LPEXTENSION_CONTROL_BLOCK lpECB ;
SLS_FETCH ( ) ;
lpECB = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
2000-04-08 00:50:55 +08:00
php_info_print_table_start ( ) ;
1999-09-28 00:34:28 +08:00
php_info_print_table_header ( 2 , " Server Variable " , " Value " ) ;
while ( * p ) {
variable_len = ISAPI_SERVER_VAR_BUF_SIZE ;
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , * p , variable_buf , & variable_len )
& & variable_buf [ 0 ] ) {
php_info_print_table_row ( 2 , * p , variable_buf ) ;
} else if ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) {
char * tmp_variable_buf ;
tmp_variable_buf = ( char * ) emalloc ( variable_len ) ;
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , * p , tmp_variable_buf , & variable_len )
& & variable_buf [ 0 ] ) {
php_info_print_table_row ( 2 , * p , tmp_variable_buf ) ;
}
efree ( tmp_variable_buf ) ;
}
p + + ;
}
2000-04-08 00:50:55 +08:00
php_info_print_table_end ( ) ;
1999-09-28 00:34:28 +08:00
}
static zend_module_entry php_isapi_module = {
" ISAPI " ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
php_info_isapi ,
STANDARD_MODULE_PROPERTIES
} ;
2000-01-14 01:37:25 +08:00
static int sapi_isapi_ub_write ( const char * str , uint str_length )
1999-09-28 00:34:28 +08:00
{
DWORD num_bytes = str_length ;
LPEXTENSION_CONTROL_BLOCK ecb ;
SLS_FETCH ( ) ;
ecb = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
2000-02-16 21:34:07 +08:00
if ( ecb - > WriteClient ( ecb - > ConnID , ( char * ) str , & num_bytes , HSE_IO_SYNC ) = = FALSE ) {
2000-02-19 01:59:44 +08:00
zend_bailout ( ) ;
2000-02-16 21:34:07 +08:00
}
1999-09-28 00:34:28 +08:00
return num_bytes ;
}
static int sapi_isapi_header_handler ( sapi_header_struct * sapi_header , sapi_headers_struct * sapi_headers SLS_DC )
{
return SAPI_HEADER_ADD ;
}
static void accumulate_header_length ( sapi_header_struct * sapi_header , uint * total_length )
{
* total_length + = sapi_header - > header_len + 2 ;
}
static void concat_header ( sapi_header_struct * sapi_header , char * * combined_headers_ptr )
{
memcpy ( * combined_headers_ptr , sapi_header - > header , sapi_header - > header_len ) ;
* combined_headers_ptr + = sapi_header - > header_len ;
* * combined_headers_ptr = ' \r ' ;
( * combined_headers_ptr ) + + ;
* * combined_headers_ptr = ' \n ' ;
( * combined_headers_ptr ) + + ;
}
static int sapi_isapi_send_headers ( sapi_headers_struct * sapi_headers SLS_DC )
{
uint total_length = 2 ; /* account for the trailing \r\n */
char * combined_headers , * combined_headers_ptr ;
LPEXTENSION_CONTROL_BLOCK lpECB = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
HSE_SEND_HEADER_EX_INFO header_info ;
char status_buf [ MAX_STATUS_LENGTH ] ;
2000-02-26 13:03:41 +08:00
sapi_header_struct default_content_type ;
1999-09-28 00:34:28 +08:00
PLS_FETCH ( ) ;
/* Obtain headers length */
if ( SG ( sapi_headers ) . send_default_content_type ) {
2000-02-26 13:03:41 +08:00
sapi_get_default_content_type_header ( & default_content_type SLS_CC ) ;
1999-09-28 00:34:28 +08:00
accumulate_header_length ( & default_content_type , ( void * ) & total_length ) ;
}
zend_llist_apply_with_argument ( & SG ( sapi_headers ) . headers , ( void ( * ) ( void * , void * ) ) accumulate_header_length , ( void * ) & total_length ) ;
/* Generate headers */
combined_headers = ( char * ) emalloc ( total_length + 1 ) ;
combined_headers_ptr = combined_headers ;
if ( SG ( sapi_headers ) . send_default_content_type ) {
concat_header ( & default_content_type , ( void * ) & combined_headers_ptr ) ;
2000-02-26 13:03:41 +08:00
sapi_free_header ( & default_content_type ) ; /* we no longer need it */
1999-09-28 00:34:28 +08:00
}
zend_llist_apply_with_argument ( & SG ( sapi_headers ) . headers , ( void ( * ) ( void * , void * ) ) concat_header , ( void * ) & combined_headers_ptr ) ;
* combined_headers_ptr + + = ' \r ' ;
* combined_headers_ptr + + = ' \n ' ;
* combined_headers_ptr = 0 ;
switch ( SG ( sapi_headers ) . http_response_code ) {
case 200 :
header_info . pszStatus = " 200 OK " ;
break ;
case 302 :
header_info . pszStatus = " 302 Moved Temporarily " ;
break ;
case 401 :
header_info . pszStatus = " 401 Authorization Required " ;
break ;
default :
snprintf ( status_buf , MAX_STATUS_LENGTH , " %d Undescribed " , SG ( sapi_headers ) . http_response_code ) ;
header_info . pszStatus = status_buf ;
break ;
}
header_info . cchStatus = strlen ( header_info . pszStatus ) ;
header_info . pszHeader = combined_headers ;
header_info . cchHeader = total_length ;
lpECB - > dwHttpStatusCode = SG ( sapi_headers ) . http_response_code ;
lpECB - > ServerSupportFunction ( lpECB - > ConnID , HSE_REQ_SEND_RESPONSE_HEADER_EX , & header_info , NULL , NULL ) ;
efree ( combined_headers ) ;
if ( SG ( sapi_headers ) . http_status_line ) {
efree ( SG ( sapi_headers ) . http_status_line ) ;
}
return SAPI_HEADER_SENT_SUCCESSFULLY ;
}
static int php_isapi_startup ( sapi_module_struct * sapi_module )
{
if ( php_module_startup ( sapi_module ) = = FAILURE
2000-02-03 01:19:36 +08:00
| | zend_startup_module ( & php_isapi_module ) = = FAILURE ) {
1999-09-28 00:34:28 +08:00
return FAILURE ;
} else {
2000-02-19 01:59:44 +08:00
bTerminateThreadsOnError = ( zend_bool ) INI_INT ( " isapi.terminate_threads_on_error " ) ;
1999-09-28 00:34:28 +08:00
return SUCCESS ;
}
}
static int sapi_isapi_read_post ( char * buffer , uint count_bytes SLS_DC )
{
LPEXTENSION_CONTROL_BLOCK lpECB = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
DWORD read_from_buf = 0 ;
DWORD read_from_input = 0 ;
DWORD total_read = 0 ;
2000-04-06 02:06:13 +08:00
if ( ( DWORD ) SG ( read_post_bytes ) < lpECB - > cbAvailable ) {
1999-09-28 00:34:28 +08:00
read_from_buf = MIN ( lpECB - > cbAvailable - SG ( read_post_bytes ) , count_bytes ) ;
memcpy ( buffer , lpECB - > lpbData + SG ( read_post_bytes ) , read_from_buf ) ;
total_read + = read_from_buf ;
}
if ( read_from_buf < count_bytes
& & ( SG ( read_post_bytes ) + read_from_buf ) < lpECB - > cbTotalBytes ) {
DWORD cbRead = 0 , cbSize ;
read_from_input = MIN ( count_bytes - read_from_buf , lpECB - > cbTotalBytes - SG ( read_post_bytes ) - read_from_buf ) ;
while ( cbRead < read_from_input ) {
cbSize = read_from_input - cbRead ;
if ( ! lpECB - > ReadClient ( lpECB - > ConnID , buffer + read_from_buf + cbRead , & cbSize ) | | cbSize = = 0 ) {
break ;
}
cbRead + = cbSize ;
}
total_read + = cbRead ;
}
return total_read ;
}
static char * sapi_isapi_read_cookies ( SLS_D )
{
LPEXTENSION_CONTROL_BLOCK lpECB = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
char variable_buf [ ISAPI_SERVER_VAR_BUF_SIZE ] ;
DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE ;
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , " HTTP_COOKIE " , variable_buf , & variable_len ) ) {
return estrndup ( variable_buf , variable_len ) ;
} else if ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) {
char * tmp_variable_buf = ( char * ) emalloc ( variable_len + 1 ) ;
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , " HTTP_COOKIE " , tmp_variable_buf , & variable_len ) ) {
tmp_variable_buf [ variable_len ] = 0 ;
return tmp_variable_buf ;
} else {
efree ( tmp_variable_buf ) ;
}
}
return NULL ;
}
2000-01-29 01:24:53 +08:00
static void sapi_isapi_register_server_variables ( zval * track_vars_array ELS_DC SLS_DC PLS_DC )
{
char static_variable_buf [ ISAPI_SERVER_VAR_BUF_SIZE ] ;
char * variable_buf ;
DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE ;
char * variable ;
char * strtok_buf = NULL ;
LPEXTENSION_CONTROL_BLOCK lpECB ;
2000-02-13 09:14:45 +08:00
char * * p = isapi_server_variables ;
2000-01-29 01:24:53 +08:00
lpECB = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
2000-02-13 09:14:45 +08:00
/* Register the standard ISAPI variables */
while ( * p ) {
variable_len = ISAPI_SERVER_VAR_BUF_SIZE ;
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , * p , static_variable_buf , & variable_len )
& & static_variable_buf [ 0 ] ) {
php_register_variable ( * p , static_variable_buf , track_vars_array ELS_CC PLS_CC ) ;
} else if ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) {
variable_buf = ( char * ) emalloc ( variable_len ) ;
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , * p , variable_buf , & variable_len )
& & variable_buf [ 0 ] ) {
php_register_variable ( * p , variable_buf , track_vars_array ELS_CC PLS_CC ) ;
}
efree ( variable_buf ) ;
}
p + + ;
}
2000-04-19 23:15:33 +08:00
/* PHP_SELF support */
2000-05-15 20:40:12 +08:00
# ifdef WITH_ZEUS
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , " PATH_INFO " , static_variable_buf , & variable_len )
# else
2000-04-19 23:15:33 +08:00
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , " SCRIPT_NAME " , static_variable_buf , & variable_len )
2000-05-15 20:40:12 +08:00
# endif
2000-04-19 23:15:33 +08:00
& & static_variable_buf [ 0 ] ) {
php_register_variable ( " PHP_SELF " , static_variable_buf , track_vars_array ELS_CC PLS_CC ) ;
}
2000-02-13 09:14:45 +08:00
/* Register the internal bits of ALL_HTTP */
variable_len = ISAPI_SERVER_VAR_BUF_SIZE ;
2000-01-29 01:24:53 +08:00
if ( lpECB - > GetServerVariable ( lpECB - > ConnID , " ALL_HTTP " , static_variable_buf , & variable_len ) ) {
variable_buf = static_variable_buf ;
} else {
if ( GetLastError ( ) = = ERROR_INSUFFICIENT_BUFFER ) {
variable_buf = ( char * ) emalloc ( variable_len ) ;
if ( ! lpECB - > GetServerVariable ( lpECB - > ConnID , " ALL_HTTP " , variable_buf , & variable_len ) ) {
efree ( variable_buf ) ;
return ;
}
} else {
return ;
}
}
2000-05-04 18:38:17 +08:00
variable = php_strtok_r ( variable_buf , " \r \n " , & strtok_buf ) ;
2000-01-29 01:24:53 +08:00
while ( variable ) {
char * colon = strchr ( variable , ' : ' ) ;
if ( colon ) {
char * value = colon + 1 ;
while ( * value = = ' ' ) {
value + + ;
}
* colon = 0 ;
2000-01-29 19:55:44 +08:00
php_register_variable ( variable , value , track_vars_array ELS_CC PLS_CC ) ;
2000-01-29 01:24:53 +08:00
* colon = ' : ' ;
}
2000-05-04 18:38:17 +08:00
variable = php_strtok_r ( NULL , " \r \n " , & strtok_buf ) ;
2000-01-29 01:24:53 +08:00
}
2000-08-07 19:51:21 +08:00
# ifdef PHP_WIN32
{
HSE_URL_MAPEX_INFO humi ;
DWORD plen = 1 ;
if ( lpECB - > ServerSupportFunction ( lpECB - > ConnID , HSE_REQ_MAP_URL_TO_PATH_EX , " / " , & plen , ( LPDWORD ) & humi ) ) {
/* Remove trailing \ */
if ( humi . lpszPath [ strlen ( humi . lpszPath ) - 1 ] = = ' \\ ' ) {
humi . lpszPath [ strlen ( humi . lpszPath ) - 1 ] = ' \0 ' ;
}
php_register_variable ( " DOCUMENT_ROOT " , humi . lpszPath , track_vars_array ELS_CC PLS_CC ) ;
}
}
# endif
2000-01-29 01:24:53 +08:00
if ( variable_buf ! = static_variable_buf ) {
efree ( variable_buf ) ;
}
}
1999-09-28 00:34:28 +08:00
static sapi_module_struct sapi_module = {
2000-06-27 02:05:55 +08:00
" isapi " , /* name */
" ISAPI " , /* pretty name */
1999-09-28 00:34:28 +08:00
php_isapi_startup , /* startup */
php_module_shutdown_wrapper , /* shutdown */
2000-02-11 00:44:59 +08:00
NULL , /* activate */
NULL , /* deactivate */
2000-01-14 01:37:25 +08:00
sapi_isapi_ub_write , /* unbuffered write */
NULL , /* flush */
2000-02-11 01:26:57 +08:00
NULL , /* get uid */
2000-02-11 01:55:01 +08:00
NULL , /* getenv */
1999-09-28 00:34:28 +08:00
php_error , /* error handler */
sapi_isapi_header_handler , /* header handler */
sapi_isapi_send_headers , /* send headers handler */
NULL , /* send header handler */
sapi_isapi_read_post , /* read POST data */
sapi_isapi_read_cookies , /* read Cookies */
2000-01-29 01:24:53 +08:00
sapi_isapi_register_server_variables , /* register server variables */
2000-02-10 23:55:10 +08:00
NULL , /* Log message */
2000-01-29 01:24:53 +08:00
2000-02-11 02:44:33 +08:00
NULL , /* Block interruptions */
NULL , /* Unblock interruptions */
1999-09-28 00:34:28 +08:00
STANDARD_SAPI_MODULE_PROPERTIES
} ;
BOOL WINAPI GetFilterVersion ( PHTTP_FILTER_VERSION pFilterVersion )
{
2000-02-17 00:46:01 +08:00
bFilterLoaded = 1 ;
1999-09-28 00:34:28 +08:00
pFilterVersion - > dwFilterVersion = HTTP_FILTER_REVISION ;
2000-06-27 02:05:55 +08:00
strcpy ( pFilterVersion - > lpszFilterDesc , sapi_module . pretty_name ) ;
1999-09-28 00:34:28 +08:00
pFilterVersion - > dwFlags = ( SF_NOTIFY_AUTHENTICATION | SF_NOTIFY_PREPROC_HEADERS ) ;
return TRUE ;
}
DWORD WINAPI HttpFilterProc ( PHTTP_FILTER_CONTEXT pfc , DWORD notificationType , LPVOID pvNotification )
{
2000-02-17 00:46:01 +08:00
SLS_FETCH ( ) ;
1999-09-28 00:34:28 +08:00
switch ( notificationType ) {
case SF_NOTIFY_PREPROC_HEADERS :
2000-02-17 00:46:01 +08:00
SG ( request_info ) . auth_user = NULL ;
SG ( request_info ) . auth_password = NULL ;
1999-09-28 00:34:28 +08:00
break ;
case SF_NOTIFY_AUTHENTICATION : {
char * auth_user = ( ( HTTP_FILTER_AUTHENT * ) pvNotification ) - > pszUser ;
char * auth_password = ( ( HTTP_FILTER_AUTHENT * ) pvNotification ) - > pszPassword ;
if ( auth_user & & auth_user [ 0 ] ) {
2000-02-17 00:46:01 +08:00
SG ( request_info ) . auth_user = estrdup ( auth_user ) ;
1999-09-28 00:34:28 +08:00
}
if ( auth_password & & auth_password [ 0 ] ) {
2000-02-17 00:46:01 +08:00
SG ( request_info ) . auth_password = estrdup ( auth_password ) ;
1999-09-28 00:34:28 +08:00
}
auth_user [ 0 ] = 0 ;
auth_password [ 0 ] = 0 ;
return SF_STATUS_REQ_HANDLED_NOTIFICATION ;
}
break ;
}
return SF_STATUS_REQ_NEXT_NOTIFICATION ;
}
static void init_request_info ( sapi_globals_struct * sapi_globals , LPEXTENSION_CONTROL_BLOCK lpECB )
{
SG ( request_info ) . request_method = lpECB - > lpszMethod ;
SG ( request_info ) . query_string = lpECB - > lpszQueryString ;
SG ( request_info ) . path_translated = lpECB - > lpszPathTranslated ;
SG ( request_info ) . request_uri = lpECB - > lpszPathInfo ;
SG ( request_info ) . content_type = lpECB - > lpszContentType ;
SG ( request_info ) . content_length = lpECB - > cbTotalBytes ;
2000-08-03 06:48:45 +08:00
SG ( sapi_headers ) . http_response_code = 200 ; /* I think dwHttpStatusCode is invalid at this stage -RL */
if ( ! strcmp ( lpECB - > lpszMethod , " HEAD " ) ) {
SG ( request_info ) . headers_only = 1 ;
} else {
SG ( request_info ) . headers_only = 0 ;
}
1999-09-28 00:34:28 +08:00
{
2000-04-12 17:48:26 +08:00
char * path_end = strrchr ( SG ( request_info ) . path_translated , SEPARATOR ) ;
1999-09-28 00:34:28 +08:00
if ( path_end ) {
* path_end = 0 ;
2000-04-15 22:28:48 +08:00
V_CHDIR ( SG ( request_info ) . path_translated ) ;
2000-04-12 17:48:26 +08:00
* path_end = SEPARATOR ;
1999-09-28 00:34:28 +08:00
}
}
2000-02-17 00:46:01 +08:00
if ( ! bFilterLoaded ) { /* we don't have valid ISAPI Filter information */
SG ( request_info ) . auth_user = SG ( request_info ) . auth_password = NULL ;
2000-02-16 07:31:10 +08:00
}
1999-09-28 00:34:28 +08:00
}
2000-02-13 09:24:51 +08:00
static void php_isapi_report_exception ( char * message , int message_len SLS_DC )
{
if ( ! SG ( headers_sent ) ) {
HSE_SEND_HEADER_EX_INFO header_info ;
LPEXTENSION_CONTROL_BLOCK lpECB = ( LPEXTENSION_CONTROL_BLOCK ) SG ( server_context ) ;
header_info . pszStatus = " 500 Internal Server Error " ;
header_info . cchStatus = strlen ( header_info . pszStatus ) ;
header_info . pszHeader = " Content-Type: text/html \r \n \r \n " ;
header_info . cchHeader = strlen ( header_info . pszHeader ) ;
lpECB - > dwHttpStatusCode = 500 ;
lpECB - > ServerSupportFunction ( lpECB - > ConnID , HSE_REQ_SEND_RESPONSE_HEADER_EX , & header_info , NULL , NULL ) ;
SG ( headers_sent ) = 1 ;
}
sapi_isapi_ub_write ( message , message_len ) ;
}
1999-09-28 00:34:28 +08:00
BOOL WINAPI GetExtensionVersion ( HSE_VERSION_INFO * pVer )
{
pVer - > dwExtensionVersion = HSE_VERSION ;
2000-04-12 17:48:26 +08:00
# ifdef WITH_ZEUS
strncpy ( pVer - > lpszExtensionDesc , sapi_module . name , HSE_MAX_EXT_DLL_NAME_LEN ) ;
# else
1999-09-28 00:34:28 +08:00
lstrcpyn ( pVer - > lpszExtensionDesc , sapi_module . name , HSE_MAX_EXT_DLL_NAME_LEN ) ;
2000-04-12 17:48:26 +08:00
# endif
1999-09-28 00:34:28 +08:00
return TRUE ;
}
2000-02-19 01:59:44 +08:00
static void my_endthread ( )
{
# ifdef PHP_WIN32
if ( bTerminateThreadsOnError ) {
_endthread ( ) ;
}
# endif
}
2000-03-20 02:22:11 +08:00
# ifdef PHP_WIN32
2000-06-17 02:24:02 +08:00
/*
___except can only call a function , so we have to do this
to retrieve the pointer .
*/
2000-03-20 01:59:05 +08:00
BOOL exceptionhandler ( LPEXCEPTION_POINTERS * e , LPEXCEPTION_POINTERS ep )
{
* e = ep ;
return TRUE ;
}
2000-03-20 02:22:11 +08:00
# endif
2000-02-19 01:59:44 +08:00
1999-09-28 00:34:28 +08:00
DWORD WINAPI HttpExtensionProc ( LPEXTENSION_CONTROL_BLOCK lpECB )
{
zend_file_handle file_handle ;
2000-02-07 05:59:58 +08:00
zend_bool stack_overflown = 0 ;
1999-09-28 00:34:28 +08:00
SLS_FETCH ( ) ;
CLS_FETCH ( ) ;
ELS_FETCH ( ) ;
PLS_FETCH ( ) ;
2000-03-20 02:22:11 +08:00
# ifdef PHP_WIN32
2000-03-20 01:59:05 +08:00
LPEXCEPTION_POINTERS e ;
2000-03-20 02:22:11 +08:00
# endif
1999-09-28 00:34:28 +08:00
if ( setjmp ( EG ( bailout ) ) ! = 0 ) {
2000-02-07 05:59:58 +08:00
php_request_shutdown ( NULL ) ;
1999-09-28 00:34:28 +08:00
return HSE_STATUS_ERROR ;
}
2000-02-07 05:59:58 +08:00
__try {
init_request_info ( sapi_globals , lpECB ) ;
SG ( server_context ) = lpECB ;
1999-09-28 00:34:28 +08:00
2000-02-07 05:59:58 +08:00
file_handle . filename = sapi_globals - > request_info . path_translated ;
file_handle . free_filename = 0 ;
file_handle . type = ZEND_HANDLE_FILENAME ;
1999-09-28 00:34:28 +08:00
2000-02-07 05:59:58 +08:00
php_request_startup ( CLS_C ELS_CC PLS_CC SLS_CC ) ;
php_execute_script ( & file_handle CLS_CC ELS_CC PLS_CC ) ;
if ( SG ( request_info ) . cookie_data ) {
efree ( SG ( request_info ) . cookie_data ) ;
}
2000-03-20 02:22:11 +08:00
# ifdef PHP_WIN32
2000-03-20 01:59:05 +08:00
} __except ( exceptionhandler ( & e , GetExceptionInformation ( ) ) ) {
2000-03-20 02:22:11 +08:00
# else
} __except ( EXCEPTION_EXECUTE_HANDLER ) {
# endif
2000-02-19 01:59:44 +08:00
# ifdef PHP_WIN32
2000-03-20 01:59:05 +08:00
char buf [ 1024 ] ;
2000-02-07 05:59:58 +08:00
if ( _exception_code ( ) = = EXCEPTION_STACK_OVERFLOW ) {
LPBYTE lpPage ;
static SYSTEM_INFO si ;
static MEMORY_BASIC_INFORMATION mi ;
static DWORD dwOldProtect ;
GetSystemInfo ( & si ) ;
/* Get page ESP is pointing to */
_asm mov lpPage , esp ;
/* Get stack allocation base */
VirtualQuery ( lpPage , & mi , sizeof ( mi ) ) ;
/* Go to the page below the current page */
lpPage = ( LPBYTE ) ( mi . BaseAddress ) - si . dwPageSize ;
/* Free pages below current page */
if ( ! VirtualFree ( mi . AllocationBase , ( LPBYTE ) lpPage - ( LPBYTE ) mi . AllocationBase , MEM_DECOMMIT ) ) {
2000-02-19 01:59:44 +08:00
_endthread ( ) ;
2000-02-07 05:59:58 +08:00
}
/* Restore the guard page */
if ( ! VirtualProtect ( lpPage , si . dwPageSize , PAGE_GUARD | PAGE_READWRITE , & dwOldProtect ) ) {
2000-02-19 01:59:44 +08:00
_endthread ( ) ;
2000-02-07 05:59:58 +08:00
}
CG ( unclean_shutdown ) = 1 ;
2000-03-20 01:59:05 +08:00
_snprintf ( buf , sizeof ( buf ) - 1 , " PHP has encountered a Stack overflow " ) ;
2000-03-20 02:24:09 +08:00
php_isapi_report_exception ( buf , strlen ( buf ) SLS_CC ) ;
2000-02-13 09:24:51 +08:00
} else if ( _exception_code ( ) = = EXCEPTION_ACCESS_VIOLATION ) {
2000-03-20 01:59:05 +08:00
_snprintf ( buf , sizeof ( buf ) - 1 , " PHP has encountered an Access Violation at %p " , e - > ExceptionRecord - > ExceptionAddress ) ;
2000-03-20 02:24:09 +08:00
php_isapi_report_exception ( buf , strlen ( buf ) SLS_CC ) ;
2000-02-19 01:59:44 +08:00
my_endthread ( ) ;
2000-02-07 05:59:58 +08:00
} else {
2000-03-20 01:59:05 +08:00
_snprintf ( buf , sizeof ( buf ) - 1 , " PHP has encountered an Unhandled Exception Code %d at %p " , e - > ExceptionRecord - > ExceptionCode , e - > ExceptionRecord - > ExceptionAddress ) ;
2000-03-20 02:24:09 +08:00
php_isapi_report_exception ( buf , strlen ( buf ) SLS_CC ) ;
2000-02-19 01:59:44 +08:00
my_endthread ( ) ;
2000-02-07 05:59:58 +08:00
}
2000-02-19 01:59:44 +08:00
# endif
2000-02-07 05:59:58 +08:00
}
__try {
php_request_shutdown ( NULL ) ;
} __except ( EXCEPTION_EXECUTE_HANDLER ) {
2000-02-19 01:59:44 +08:00
my_endthread ( ) ;
1999-09-28 00:34:28 +08:00
}
2000-02-07 05:59:58 +08:00
1999-09-28 00:34:28 +08:00
return HSE_STATUS_SUCCESS ;
}
__declspec ( dllexport ) BOOL WINAPI DllMain ( HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpvReserved )
{
switch ( fdwReason ) {
case DLL_PROCESS_ATTACH :
tsrm_startup ( 1 , 1 , 0 ) ;
sapi_startup ( & sapi_module ) ;
if ( sapi_module . startup ) {
sapi_module . startup ( & sapi_module ) ;
}
break ;
case DLL_THREAD_ATTACH :
break ;
case DLL_THREAD_DETACH :
ts_free_thread ( ) ;
break ;
case DLL_PROCESS_DETACH :
if ( sapi_module . shutdown ) {
sapi_module . shutdown ( & sapi_module ) ;
}
tsrm_shutdown ( ) ;
break ;
}
return TRUE ;
1999-09-28 20:08:34 +08:00
}
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
*/