File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / sapi / isapi / php5isapi.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:35 2012 UTC (12 years, 2 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_17p0, HEAD
php 5.4.3+patches

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2012 The PHP Group                                |
    6:    +----------------------------------------------------------------------+
    7:    | This source file is subject to version 3.01 of the PHP license,      |
    8:    | that is bundled with this package in the file LICENSE, and is        |
    9:    | available through the world-wide-web at the following url:           |
   10:    | http://www.php.net/license/3_01.txt                                  |
   11:    | If you did not receive a copy of the PHP license and are unable to   |
   12:    | obtain it through the world-wide-web, please send a note to          |
   13:    | license@php.net so we can mail you a copy immediately.               |
   14:    +----------------------------------------------------------------------+
   15:    | Authors: Zeev Suraski <zeev@zend.com>                                |
   16:    |          Ben Mansell <ben@zeus.com> (Zeus Support)                   |
   17:    +----------------------------------------------------------------------+
   18:  */
   19: /* $Id: php5isapi.c,v 1.1.1.2 2012/05/29 12:34:35 misho Exp $ */
   20: 
   21: #include "php.h"
   22: #include <httpext.h>
   23: #include <httpfilt.h>
   24: #include <httpext.h>
   25: #include "php_main.h"
   26: #include "SAPI.h"
   27: #include "php_globals.h"
   28: #include "ext/standard/info.h"
   29: #include "php_variables.h"
   30: #include "php_ini.h"
   31: 
   32: #ifdef PHP_WIN32
   33: # include <process.h>
   34: #else
   35: # define __try
   36: # define __except(val)
   37: # define __declspec(foo)
   38: #endif
   39: 
   40: 
   41: #ifdef WITH_ZEUS
   42: # include "httpext.h"
   43: # include <errno.h>
   44: # define GetLastError() errno
   45: #endif
   46: 
   47: #ifdef PHP_WIN32
   48: #define PHP_ENABLE_SEH
   49: #endif
   50: 
   51: /* 
   52: uncomment the following lines to turn off 
   53: exception trapping when running under a debugger 
   54: 
   55: #ifdef _DEBUG
   56: #undef PHP_ENABLE_SEH
   57: #endif
   58: */
   59: 
   60: #define MAX_STATUS_LENGTH sizeof("xxxx LONGEST POSSIBLE STATUS DESCRIPTION")
   61: #define ISAPI_SERVER_VAR_BUF_SIZE 1024
   62: #define ISAPI_POST_DATA_BUF 1024
   63: 
   64: static zend_bool bFilterLoaded=0;
   65: static zend_bool bTerminateThreadsOnError=0;
   66: 
   67: static char *isapi_special_server_variable_names[] = {
   68: 	"ALL_HTTP",
   69: 	"HTTPS",
   70: #ifndef WITH_ZEUS
   71: 	"SCRIPT_NAME",
   72: #endif
   73: 	NULL
   74: };
   75: 
   76: #define NUM_SPECIAL_VARS		(sizeof(isapi_special_server_variable_names)/sizeof(char *))
   77: #define SPECIAL_VAR_ALL_HTTP	0
   78: #define SPECIAL_VAR_HTTPS		1
   79: #define SPECIAL_VAR_PHP_SELF	2
   80: 
   81: static char *isapi_server_variable_names[] = {
   82: 	"AUTH_PASSWORD",
   83: 	"AUTH_TYPE",
   84: 	"AUTH_USER",
   85: 	"CONTENT_LENGTH",
   86: 	"CONTENT_TYPE",
   87: 	"PATH_TRANSLATED",
   88: 	"QUERY_STRING",
   89: 	"REMOTE_ADDR",
   90: 	"REMOTE_HOST",
   91: 	"REMOTE_USER",
   92: 	"REQUEST_METHOD",
   93: 	"SERVER_NAME",
   94: 	"SERVER_PORT",
   95: 	"SERVER_PROTOCOL",
   96: 	"SERVER_SOFTWARE",
   97: #ifndef WITH_ZEUS
   98: 	"APPL_MD_PATH",
   99: 	"APPL_PHYSICAL_PATH",
  100: 	"INSTANCE_ID",
  101: 	"INSTANCE_META_PATH",
  102: 	"LOGON_USER",
  103: 	"REQUEST_URI",
  104: 	"URL",
  105: #else
  106: 	"DOCUMENT_ROOT",
  107: #endif
  108: 	NULL
  109: };
  110: 
  111: 
  112: static char *isapi_secure_server_variable_names[] = {
  113: 	"CERT_COOKIE",
  114: 	"CERT_FLAGS",
  115: 	"CERT_ISSUER",
  116: 	"CERT_KEYSIZE",
  117: 	"CERT_SECRETKEYSIZE",
  118: 	"CERT_SERIALNUMBER",
  119: 	"CERT_SERVER_ISSUER",
  120: 	"CERT_SERVER_SUBJECT",
  121: 	"CERT_SUBJECT",
  122: 	"HTTPS_KEYSIZE",
  123: 	"HTTPS_SECRETKEYSIZE",
  124: 	"HTTPS_SERVER_ISSUER",
  125: 	"HTTPS_SERVER_SUBJECT",
  126: 	"SERVER_PORT_SECURE",
  127: #ifdef WITH_ZEUS
  128: 	"SSL_CLIENT_CN",
  129: 	"SSL_CLIENT_EMAIL",
  130: 	"SSL_CLIENT_OU",
  131: 	"SSL_CLIENT_O",
  132: 	"SSL_CLIENT_L",
  133: 	"SSL_CLIENT_ST",
  134: 	"SSL_CLIENT_C",
  135: 	"SSL_CLIENT_I_CN",
  136: 	"SSL_CLIENT_I_EMAIL",
  137: 	"SSL_CLIENT_I_OU",
  138: 	"SSL_CLIENT_I_O",
  139: 	"SSL_CLIENT_I_L",
  140: 	"SSL_CLIENT_I_ST",
  141: 	"SSL_CLIENT_I_C",	
  142: #endif
  143: 	NULL
  144: };
  145: 
  146: 
  147: static void php_info_isapi(ZEND_MODULE_INFO_FUNC_ARGS)
  148: {
  149: 	char **p;
  150: 	char variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  151: 	DWORD variable_len;
  152: 	char **all_variables[] = {
  153: 		isapi_server_variable_names,
  154: 		isapi_special_server_variable_names,
  155: 		isapi_secure_server_variable_names,
  156: 		NULL
  157: 	};
  158: 	char ***server_variable_names;
  159: 	LPEXTENSION_CONTROL_BLOCK lpECB;
  160: 
  161: 	lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  162: 
  163: 	php_info_print_table_start();
  164: 	php_info_print_table_header(2, "Server Variable", "Value");
  165: 	server_variable_names = all_variables;
  166: 	while (*server_variable_names) {
  167: 		p = *server_variable_names;
  168: 		while (*p) {
  169: 			variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  170: 			if (lpECB->GetServerVariable(lpECB->ConnID, *p, variable_buf, &variable_len)
  171: 				&& variable_buf[0]) {
  172: 				php_info_print_table_row(2, *p, variable_buf);
  173: 			} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  174: 				char *tmp_variable_buf;
  175: 
  176: 				tmp_variable_buf = (char *) emalloc(variable_len);
  177: 				if (lpECB->GetServerVariable(lpECB->ConnID, *p, tmp_variable_buf, &variable_len)
  178: 					&& variable_buf[0]) {
  179: 					php_info_print_table_row(2, *p, tmp_variable_buf);
  180: 				}
  181: 				efree(tmp_variable_buf);
  182: 			}
  183: 			p++;
  184: 		}
  185: 		server_variable_names++;
  186: 	}
  187: 	php_info_print_table_end();
  188: }
  189: 
  190: 
  191: static zend_module_entry php_isapi_module = {
  192:     STANDARD_MODULE_HEADER,
  193: 	"ISAPI",
  194: 	NULL,
  195: 	NULL,
  196: 	NULL,
  197: 	NULL,
  198: 	NULL,
  199: 	php_info_isapi,
  200:     NULL,
  201: 	STANDARD_MODULE_PROPERTIES
  202: };
  203: 
  204: 
  205: static int sapi_isapi_ub_write(const char *str, uint str_length TSRMLS_DC)
  206: {
  207: 	DWORD num_bytes = str_length;
  208: 	LPEXTENSION_CONTROL_BLOCK ecb;
  209: 	
  210: 	ecb = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  211: 	if (ecb->WriteClient(ecb->ConnID, (char *) str, &num_bytes, HSE_IO_SYNC) == FALSE) {
  212: 		php_handle_aborted_connection();
  213: 	}
  214: 	return num_bytes;
  215: }
  216: 
  217: 
  218: static int sapi_isapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC)
  219: {
  220: 	return SAPI_HEADER_ADD;
  221: }
  222: 
  223: 
  224: 
  225: static void accumulate_header_length(sapi_header_struct *sapi_header, uint *total_length TSRMLS_DC)
  226: {
  227: 	*total_length += sapi_header->header_len+2;
  228: }
  229: 
  230: 
  231: static void concat_header(sapi_header_struct *sapi_header, char **combined_headers_ptr TSRMLS_DC)
  232: {
  233: 	memcpy(*combined_headers_ptr, sapi_header->header, sapi_header->header_len);
  234: 	*combined_headers_ptr += sapi_header->header_len;
  235: 	**combined_headers_ptr = '\r';
  236: 	(*combined_headers_ptr)++;
  237: 	**combined_headers_ptr = '\n';
  238: 	(*combined_headers_ptr)++;
  239: }
  240: 
  241: 
  242: static int sapi_isapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
  243: {
  244: 	uint total_length = 2;		/* account for the trailing \r\n */
  245: 	char *combined_headers, *combined_headers_ptr;
  246: 	LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  247: 	HSE_SEND_HEADER_EX_INFO header_info;
  248: 	sapi_header_struct default_content_type;
  249: 	char *status_buf = NULL;
  250: 
  251: 	/* Obtain headers length */
  252: 	if (SG(sapi_headers).send_default_content_type) {
  253: 		sapi_get_default_content_type_header(&default_content_type TSRMLS_CC);
  254: 		accumulate_header_length(&default_content_type, (void *) &total_length TSRMLS_CC);
  255: 	}
  256: 	zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) accumulate_header_length, (void *) &total_length TSRMLS_CC);
  257: 
  258: 	/* Generate headers */
  259: 	combined_headers = (char *) emalloc(total_length+1);
  260: 	combined_headers_ptr = combined_headers;
  261: 	if (SG(sapi_headers).send_default_content_type) {
  262: 		concat_header(&default_content_type, (void *) &combined_headers_ptr TSRMLS_CC);
  263: 		sapi_free_header(&default_content_type); /* we no longer need it */
  264: 	}
  265: 	zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) concat_header, (void *) &combined_headers_ptr TSRMLS_CC);
  266: 	*combined_headers_ptr++ = '\r';
  267: 	*combined_headers_ptr++ = '\n';
  268: 	*combined_headers_ptr = 0;
  269: 
  270: 	switch (SG(sapi_headers).http_response_code) {
  271: 		case 200:
  272: 			header_info.pszStatus = "200 OK";
  273: 			break;
  274: 		case 302:
  275: 			header_info.pszStatus = "302 Moved Temporarily";
  276: 			break;
  277: 		case 401:
  278: 			header_info.pszStatus = "401 Authorization Required";
  279: 			break;
  280: 		default: {
  281: 			const char *sline = SG(sapi_headers).http_status_line;
  282: 			int sline_len;
  283: 			
  284: 			/* httpd requires that r->status_line is set to the first digit of
  285: 			 * the status-code: */
  286: 			if (sline && ((sline_len = strlen(sline)) > 12) && strncmp(sline, "HTTP/1.", 7) == 0 && sline[8] == ' ') {
  287: 				if ((sline_len - 9) > MAX_STATUS_LENGTH) {
  288: 					status_buf = estrndup(sline + 9, MAX_STATUS_LENGTH);
  289: 				} else {
  290: 					status_buf = estrndup(sline + 9, sline_len - 9);
  291: 				}
  292: 			} else {
  293: 				status_buf = emalloc(MAX_STATUS_LENGTH + 1);
  294: 				snprintf(status_buf, MAX_STATUS_LENGTH, "%d Undescribed", SG(sapi_headers).http_response_code);
  295: 			}
  296: 			header_info.pszStatus = status_buf;
  297: 			break;
  298: 		}
  299: 	}
  300: 	header_info.cchStatus = strlen(header_info.pszStatus);
  301: 	header_info.pszHeader = combined_headers;
  302: 	header_info.cchHeader = total_length;
  303: 	header_info.fKeepConn = FALSE;
  304: 	lpECB->dwHttpStatusCode = SG(sapi_headers).http_response_code;
  305: 
  306: 	lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
  307: 
  308: 	efree(combined_headers);
  309: 	if (status_buf) {
  310: 		efree(status_buf);
  311: 	}
  312: 	return SAPI_HEADER_SENT_SUCCESSFULLY;
  313: }
  314: 
  315: 
  316: static int php_isapi_startup(sapi_module_struct *sapi_module)
  317: {
  318: 	if (php_module_startup(sapi_module, &php_isapi_module, 1)==FAILURE) {
  319: 		return FAILURE;
  320: 	} else {
  321: 		bTerminateThreadsOnError = (zend_bool) INI_INT("isapi.terminate_threads_on_error");
  322: 		return SUCCESS;
  323: 	}
  324: }
  325: 
  326: 
  327: static int sapi_isapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
  328: {
  329: 	LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  330: 	DWORD read_from_buf=0;
  331: 	DWORD read_from_input=0;
  332: 	DWORD total_read=0;
  333: 
  334: 	if ((DWORD) SG(read_post_bytes) < lpECB->cbAvailable) {
  335: 		read_from_buf = MIN(lpECB->cbAvailable-SG(read_post_bytes), count_bytes);
  336: 		memcpy(buffer, lpECB->lpbData+SG(read_post_bytes), read_from_buf);
  337: 		total_read += read_from_buf;
  338: 	}
  339: 	if (read_from_buf<count_bytes
  340: 		&& (SG(read_post_bytes)+read_from_buf) < lpECB->cbTotalBytes) {
  341: 		DWORD cbRead=0, cbSize;
  342: 
  343: 		read_from_input = MIN(count_bytes-read_from_buf, lpECB->cbTotalBytes-SG(read_post_bytes)-read_from_buf);
  344: 		while (cbRead < read_from_input) {
  345: 			cbSize = read_from_input - cbRead;
  346: 			if (!lpECB->ReadClient(lpECB->ConnID, buffer+read_from_buf+cbRead, &cbSize) || cbSize==0) {
  347: 				break;
  348: 			}
  349: 			cbRead += cbSize;
  350: 		}
  351: 		total_read += cbRead;
  352: 	}
  353: 	return total_read;
  354: }
  355: 
  356: 
  357: static char *sapi_isapi_read_cookies(TSRMLS_D)
  358: {
  359: 	LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  360: 	char variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  361: 	DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  362: 
  363: 	if (lpECB->GetServerVariable(lpECB->ConnID, "HTTP_COOKIE", variable_buf, &variable_len)) {
  364: 		return estrndup(variable_buf, variable_len);
  365: 	} else if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) {
  366: 		char *tmp_variable_buf = (char *) emalloc(variable_len+1);
  367: 
  368: 		if (lpECB->GetServerVariable(lpECB->ConnID, "HTTP_COOKIE", tmp_variable_buf, &variable_len)) {
  369: 			tmp_variable_buf[variable_len] = 0;
  370: 			return tmp_variable_buf;
  371: 		} else {
  372: 			efree(tmp_variable_buf);
  373: 		}
  374: 	}
  375: 	return STR_EMPTY_ALLOC();
  376: }
  377: 
  378: 
  379: #ifdef WITH_ZEUS
  380: 
  381: static void sapi_isapi_register_zeus_ssl_variables(LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array TSRMLS_DC)
  382: {
  383: 	char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  384: 	DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  385: 	char static_cons_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  386: 	/*
  387: 	 * We need to construct the /C=.../ST=...
  388: 	 * DN's for SSL_CLIENT_DN and SSL_CLIENT_I_DN
  389: 	 */
  390: 	strcpy( static_cons_buf, "/C=" );
  391: 	if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_C", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
  392: 		strlcat( static_cons_buf, static_variable_buf,  ISAPI_SERVER_VAR_BUF_SIZE);
  393: 	}
  394: 	strlcat( static_cons_buf, "/ST=",  ISAPI_SERVER_VAR_BUF_SIZE);
  395: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  396: 	if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_ST", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
  397: 		strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE );
  398: 	}
  399: 	php_register_variable( "SSL_CLIENT_DN", static_cons_buf, track_vars_array TSRMLS_CC );
  400: 	
  401: 	strcpy( static_cons_buf, "/C=" );
  402: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  403: 	if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_I_C", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
  404: 		strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE );
  405: 	}
  406: 	strlcat( static_cons_buf, "/ST=", ISAPI_SERVER_VAR_BUF_SIZE);
  407: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  408: 	if( lpECB->GetServerVariable( lpECB->ConnID, "SSL_CLIENT_I_ST", static_variable_buf, &variable_len ) && static_variable_buf[0] ) {
  409: 		strlcat( static_cons_buf, static_variable_buf, ISAPI_SERVER_VAR_BUF_SIZE );
  410: 	}
  411: 	php_register_variable( "SSL_CLIENT_I_DN", static_cons_buf, track_vars_array TSRMLS_CC );	
  412: }
  413: 
  414: static void sapi_isapi_register_zeus_variables(LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array TSRMLS_DC)
  415: {
  416: 	char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  417: 	DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  418: 	DWORD scriptname_len = ISAPI_SERVER_VAR_BUF_SIZE;
  419: 	DWORD pathinfo_len = 0;
  420: 	char *strtok_buf = NULL;
  421: 
  422: 	/* Get SCRIPT_NAME, we use this to work out which bit of the URL
  423: 	 * belongs in PHP's version of PATH_INFO
  424: 	 */
  425: 	lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_NAME", static_variable_buf, &scriptname_len);
  426: 
  427: 	/* Adjust Zeus' version of PATH_INFO, set PHP_SELF,
  428: 	 * and generate REQUEST_URI
  429: 	 */
  430: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_INFO", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
  431: 
  432: 		/* PHP_SELF is just PATH_INFO */
  433: 		php_register_variable( "PHP_SELF", static_variable_buf, track_vars_array TSRMLS_CC );
  434: 
  435: 		/* Chop off filename to get just the 'real' PATH_INFO' */
  436: 		pathinfo_len = variable_len - scriptname_len;
  437: 		php_register_variable( "PATH_INFO", static_variable_buf + scriptname_len - 1, track_vars_array TSRMLS_CC );
  438: 		/* append query string to give url... extra byte for '?' */
  439: 		if ( strlen(lpECB->lpszQueryString) + variable_len + 1 < ISAPI_SERVER_VAR_BUF_SIZE ) {
  440: 			/* append query string only if it is present... */
  441: 			if ( strlen(lpECB->lpszQueryString) ) {
  442: 				static_variable_buf[ variable_len - 1 ] = '?';
  443: 				strcpy( static_variable_buf + variable_len, lpECB->lpszQueryString );
  444: 			}
  445: 			php_register_variable( "URL", static_variable_buf, track_vars_array TSRMLS_CC );
  446: 			php_register_variable( "REQUEST_URI", static_variable_buf, track_vars_array TSRMLS_CC );
  447: 		}
  448: 	}
  449: 
  450: 	/* Get and adjust PATH_TRANSLATED to what PHP wants */
  451: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  452: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_TRANSLATED", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
  453: 		static_variable_buf[ variable_len - pathinfo_len - 1 ] = '\0';
  454: 		php_register_variable( "PATH_TRANSLATED", static_variable_buf, track_vars_array TSRMLS_CC );
  455: 	}
  456: 
  457: 	/* Bring in the AUTHENTICATION stuff as needed */
  458: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  459: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "AUTH_USER", static_variable_buf, &variable_len) && static_variable_buf[0] )  {
  460: 		php_register_variable( "PHP_AUTH_USER", static_variable_buf, track_vars_array TSRMLS_CC );
  461: 	}
  462: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  463: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "AUTH_PASSWORD", static_variable_buf, &variable_len) && static_variable_buf[0] )  {
  464: 		php_register_variable( "PHP_AUTH_PW", static_variable_buf, track_vars_array TSRMLS_CC );
  465: 	}
  466: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  467: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "AUTH_TYPE", static_variable_buf, &variable_len) && static_variable_buf[0] )  {
  468: 		php_register_variable( "AUTH_TYPE", static_variable_buf, track_vars_array TSRMLS_CC );
  469: 	}
  470: 	
  471: 	/* And now, for the SSL variables (if applicable) */
  472: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  473: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "CERT_COOKIE", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
  474: 		sapi_isapi_register_zeus_ssl_variables( lpECB, track_vars_array TSRMLS_CC );
  475: 	}
  476: 	/* Copy some of the variables we need to meet Apache specs */
  477: 	variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  478: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "SERVER_SOFTWARE", static_variable_buf, &variable_len) && static_variable_buf[0] )  {
  479: 		php_register_variable( "SERVER_SIGNATURE", static_variable_buf, track_vars_array TSRMLS_CC );
  480: 	}
  481: }
  482: #else
  483: 
  484: static void sapi_isapi_register_iis_variables(LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array TSRMLS_DC)
  485: {
  486: 	char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  487: 	char path_info_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  488: 	DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  489: 	DWORD scriptname_len = ISAPI_SERVER_VAR_BUF_SIZE;
  490: 	DWORD pathinfo_len = 0;
  491: 	HSE_URL_MAPEX_INFO humi;
  492: 
  493: 	/* Get SCRIPT_NAME, we use this to work out which bit of the URL
  494: 	 * belongs in PHP's version of PATH_INFO.  SCRIPT_NAME also becomes PHP_SELF.
  495: 	 */
  496: 	lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_NAME", static_variable_buf, &scriptname_len);
  497: 	php_register_variable("SCRIPT_FILENAME", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
  498: 
  499: 	/* Adjust IIS' version of PATH_INFO, set PHP_SELF,
  500: 	 * and generate REQUEST_URI
  501: 	 * Get and adjust PATH_TRANSLATED to what PHP wants
  502: 	 */
  503: 	if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_INFO", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
  504: 
  505: 		/* Chop off filename to get just the 'real' PATH_INFO' */
  506: 		php_register_variable( "ORIG_PATH_INFO", static_variable_buf, track_vars_array TSRMLS_CC );
  507: 		pathinfo_len = variable_len - scriptname_len;
  508: 		strncpy(path_info_buf, static_variable_buf + scriptname_len - 1, sizeof(path_info_buf)-1);
  509: 		php_register_variable( "PATH_INFO", path_info_buf, track_vars_array TSRMLS_CC );
  510: 		/* append query string to give url... extra byte for '?' */
  511: 		if ( strlen(lpECB->lpszQueryString) + variable_len + 1 < ISAPI_SERVER_VAR_BUF_SIZE ) {
  512: 			/* append query string only if it is present... */
  513: 			if ( strlen(lpECB->lpszQueryString) ) {
  514: 				static_variable_buf[ variable_len - 1 ] = '?';
  515: 				strcpy( static_variable_buf + variable_len, lpECB->lpszQueryString );
  516: 			}
  517: 			php_register_variable( "URL", static_variable_buf, track_vars_array TSRMLS_CC );
  518: 			php_register_variable( "REQUEST_URI", static_variable_buf, track_vars_array TSRMLS_CC );
  519: 		}
  520: 		variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  521: 		if ( lpECB->GetServerVariable(lpECB->ConnID, "PATH_TRANSLATED", static_variable_buf, &variable_len) && static_variable_buf[0] ) {
  522: 			php_register_variable( "ORIG_PATH_TRANSLATED", static_variable_buf, track_vars_array TSRMLS_CC );
  523: 		}
  524: 		if (lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_MAP_URL_TO_PATH_EX, path_info_buf, &pathinfo_len, (LPDWORD) &humi)) {
  525: 			/* Remove trailing \  */
  526: 			if (humi.lpszPath[variable_len-2] == '\\') {
  527: 				humi.lpszPath[variable_len-2] = 0;
  528: 			}
  529: 			php_register_variable("PATH_TRANSLATED", humi.lpszPath, track_vars_array TSRMLS_CC);
  530: 		}
  531: 	}
  532: 
  533: 	static_variable_buf[0] = '/';
  534: 	static_variable_buf[1] = 0;
  535: 	variable_len = 2;
  536: 	if (lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_MAP_URL_TO_PATH_EX, static_variable_buf, &variable_len, (LPDWORD) &humi)) {
  537: 		/* Remove trailing \  */
  538: 		if (humi.lpszPath[variable_len-2] == '\\') {
  539: 			humi.lpszPath[variable_len-2] = 0;
  540: 		}
  541: 		php_register_variable("DOCUMENT_ROOT", humi.lpszPath, track_vars_array TSRMLS_CC);
  542: 	}
  543: 
  544: 	if (!SG(request_info).auth_user || !SG(request_info).auth_password || 
  545: 		!SG(request_info).auth_user[0] || !SG(request_info).auth_password[0]) {
  546: 		variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  547: 		if (lpECB->GetServerVariable(lpECB->ConnID, "HTTP_AUTHORIZATION", static_variable_buf, &variable_len)
  548: 			&& static_variable_buf[0]) {
  549: 			php_handle_auth_data(static_variable_buf TSRMLS_CC);
  550: 		}
  551: 	}
  552: 
  553: 	if (SG(request_info).auth_user)  {
  554: 		php_register_variable("PHP_AUTH_USER", SG(request_info).auth_user, track_vars_array TSRMLS_CC );
  555: 	}
  556: 	if (SG(request_info).auth_password) {
  557: 		php_register_variable("PHP_AUTH_PW", SG(request_info).auth_password, track_vars_array TSRMLS_CC );
  558: 	}
  559: }
  560: #endif
  561: 
  562: static void sapi_isapi_register_server_variables2(char **server_variables, LPEXTENSION_CONTROL_BLOCK lpECB, zval *track_vars_array, char **recorded_values TSRMLS_DC)
  563: {
  564: 	char **p=server_variables;
  565: 	DWORD variable_len;
  566: 	char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  567: 	char *variable_buf;
  568: 
  569: 	while (*p) {
  570: 		variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  571: 		if (lpECB->GetServerVariable(lpECB->ConnID, *p, static_variable_buf, &variable_len)
  572: 			&& static_variable_buf[0]) {
  573: 			php_register_variable(*p, static_variable_buf, track_vars_array TSRMLS_CC);
  574: 			if (recorded_values) {
  575: 				recorded_values[p-server_variables] = estrndup(static_variable_buf, variable_len);
  576: 			}
  577: 		} else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  578: 			variable_buf = (char *) emalloc(variable_len+1);
  579: 			if (lpECB->GetServerVariable(lpECB->ConnID, *p, variable_buf, &variable_len)
  580: 				&& variable_buf[0]) {
  581: 				php_register_variable(*p, variable_buf, track_vars_array TSRMLS_CC);
  582: 			}
  583: 			if (recorded_values) {
  584: 				recorded_values[p-server_variables] = variable_buf;
  585: 			} else {
  586: 				efree(variable_buf);
  587: 			}
  588: 		} else { /* for compatibility with Apache SAPIs */
  589: 			php_register_variable(*p, "", track_vars_array TSRMLS_CC);
  590: 		}
  591: 		p++;
  592: 	}
  593: }
  594: 
  595: 
  596: static void sapi_isapi_register_server_variables(zval *track_vars_array TSRMLS_DC)
  597: {
  598: 	DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  599: 	char *variable;
  600: 	char *strtok_buf = NULL;
  601: 	char *isapi_special_server_variables[NUM_SPECIAL_VARS];
  602: 	LPEXTENSION_CONTROL_BLOCK lpECB;
  603: 
  604: 	lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  605: 
  606: 	/* Register the special ISAPI variables */
  607: 	memset(isapi_special_server_variables, 0, sizeof(isapi_special_server_variables));
  608: 	sapi_isapi_register_server_variables2(isapi_special_server_variable_names, lpECB, track_vars_array, isapi_special_server_variables TSRMLS_CC);
  609: 	if (SG(request_info).cookie_data) {
  610: 		php_register_variable("HTTP_COOKIE", SG(request_info).cookie_data, track_vars_array TSRMLS_CC);
  611: 	}
  612: 
  613: 	/* Register the standard ISAPI variables */
  614: 	sapi_isapi_register_server_variables2(isapi_server_variable_names, lpECB, track_vars_array, NULL TSRMLS_CC);
  615: 
  616: 	if (isapi_special_server_variables[SPECIAL_VAR_HTTPS]
  617: 		&& (atoi(isapi_special_server_variables[SPECIAL_VAR_HTTPS])
  618: 		|| !strcasecmp(isapi_special_server_variables[SPECIAL_VAR_HTTPS], "on"))
  619: 	) {
  620: 		/* Register SSL ISAPI variables */
  621: 		sapi_isapi_register_server_variables2(isapi_secure_server_variable_names, lpECB, track_vars_array, NULL TSRMLS_CC);
  622: 	}
  623: 
  624: 	if (isapi_special_server_variables[SPECIAL_VAR_HTTPS]) {
  625: 		efree(isapi_special_server_variables[SPECIAL_VAR_HTTPS]);
  626: 	}
  627: 
  628: 
  629: #ifdef WITH_ZEUS
  630: 	sapi_isapi_register_zeus_variables(lpECB, track_vars_array TSRMLS_CC);
  631: #else
  632: 	sapi_isapi_register_iis_variables(lpECB, track_vars_array TSRMLS_CC);
  633: #endif
  634: 
  635: 	/* PHP_SELF support */
  636: 	if (isapi_special_server_variables[SPECIAL_VAR_PHP_SELF]) {
  637: 		php_register_variable("PHP_SELF", isapi_special_server_variables[SPECIAL_VAR_PHP_SELF], track_vars_array TSRMLS_CC);
  638: 		efree(isapi_special_server_variables[SPECIAL_VAR_PHP_SELF]);
  639: 	}
  640: 
  641: 	if (isapi_special_server_variables[SPECIAL_VAR_ALL_HTTP]) {
  642: 		/* Register the internal bits of ALL_HTTP */
  643: 		variable = php_strtok_r(isapi_special_server_variables[SPECIAL_VAR_ALL_HTTP], "\r\n", &strtok_buf);
  644: 		while (variable) {
  645: 			char *colon = strchr(variable, ':');
  646: 
  647: 			if (colon) {
  648: 				char *value = colon+1;
  649: 
  650: 				while (*value==' ') {
  651: 					value++;
  652: 				}
  653: 				*colon = 0;
  654: 				php_register_variable(variable, value, track_vars_array TSRMLS_CC);
  655: 				*colon = ':';
  656: 			}
  657: 			variable = php_strtok_r(NULL, "\r\n", &strtok_buf);
  658: 		}
  659: 		efree(isapi_special_server_variables[SPECIAL_VAR_ALL_HTTP]);
  660: 	}
  661: }
  662: 
  663: 
  664: static sapi_module_struct isapi_sapi_module = {
  665: 	"isapi",						/* name */
  666: 	"ISAPI",						/* pretty name */
  667: 									
  668: 	php_isapi_startup,				/* startup */
  669: 	php_module_shutdown_wrapper,	/* shutdown */
  670: 
  671: 	NULL,							/* activate */
  672: 	NULL,							/* deactivate */
  673: 
  674: 	sapi_isapi_ub_write,			/* unbuffered write */
  675: 	NULL,							/* flush */
  676: 	NULL,							/* get uid */
  677: 	NULL,							/* getenv */
  678: 
  679: 	php_error,						/* error handler */
  680: 
  681: 	sapi_isapi_header_handler,		/* header handler */
  682: 	sapi_isapi_send_headers,		/* send headers handler */
  683: 	NULL,							/* send header handler */
  684: 
  685: 	sapi_isapi_read_post,			/* read POST data */
  686: 	sapi_isapi_read_cookies,		/* read Cookies */
  687: 
  688: 	sapi_isapi_register_server_variables,	/* register server variables */
  689: 	NULL,							/* Log message */
  690: 	NULL,							/* Get request time */
  691: 	NULL,							/* Child terminate */
  692: 
  693: 	STANDARD_SAPI_MODULE_PROPERTIES
  694: };
  695: 
  696: 
  697: BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pFilterVersion)
  698: {
  699: 	bFilterLoaded = 1;
  700: 	pFilterVersion->dwFilterVersion = HTTP_FILTER_REVISION;
  701: 	strcpy(pFilterVersion->lpszFilterDesc, isapi_sapi_module.pretty_name);
  702: 	pFilterVersion->dwFlags= (SF_NOTIFY_AUTHENTICATION | SF_NOTIFY_PREPROC_HEADERS);
  703: 	return TRUE;
  704: }
  705: 
  706: 
  707: DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)
  708: {
  709: 	TSRMLS_FETCH();
  710: 
  711: 	switch (notificationType) {
  712: 		case SF_NOTIFY_PREPROC_HEADERS:
  713: 			SG(request_info).auth_user = NULL;
  714: 			SG(request_info).auth_password = NULL;
  715: 			SG(request_info).auth_digest = NULL;
  716: 			break;
  717: 		case SF_NOTIFY_AUTHENTICATION: {
  718: 				char *auth_user = ((HTTP_FILTER_AUTHENT *) pvNotification)->pszUser;
  719: 				char *auth_password = ((HTTP_FILTER_AUTHENT *) pvNotification)->pszPassword;
  720: 
  721: 				if (auth_user && auth_user[0]) {
  722: 					SG(request_info).auth_user = estrdup(auth_user);
  723: 				}	
  724: 				if (auth_password && auth_password[0]) {
  725: 					SG(request_info).auth_password = estrdup(auth_password);
  726: 				}
  727: 				return SF_STATUS_REQ_HANDLED_NOTIFICATION;
  728: 			}
  729: 			break;
  730: 	}
  731: 	return SF_STATUS_REQ_NEXT_NOTIFICATION;
  732: }
  733: 
  734: 
  735: static void init_request_info(LPEXTENSION_CONTROL_BLOCK lpECB TSRMLS_DC)
  736: {
  737: 	DWORD variable_len = ISAPI_SERVER_VAR_BUF_SIZE;
  738: 	char static_variable_buf[ISAPI_SERVER_VAR_BUF_SIZE];
  739: #ifndef WITH_ZEUS
  740: 	HSE_URL_MAPEX_INFO humi;
  741: #endif
  742: 
  743: 	SG(request_info).request_method = lpECB->lpszMethod;
  744: 	SG(request_info).query_string = lpECB->lpszQueryString;
  745: 	SG(request_info).request_uri = lpECB->lpszPathInfo;
  746: 	SG(request_info).content_type = lpECB->lpszContentType;
  747: 	SG(request_info).content_length = lpECB->cbTotalBytes;
  748: 	SG(sapi_headers).http_response_code = 200;  /* I think dwHttpStatusCode is invalid at this stage -RL */
  749: 	if (!bFilterLoaded) { /* we don't have valid ISAPI Filter information */
  750: 		SG(request_info).auth_user = SG(request_info).auth_password = SG(request_info).auth_digest = NULL;
  751: 	}
  752: 
  753: #ifdef WITH_ZEUS
  754: 	/* PATH_TRANSLATED can contain extra PATH_INFO stuff after the
  755: 	 * file being loaded, so we must use SCRIPT_FILENAME instead
  756: 	 */
  757: 	if(lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_FILENAME", static_variable_buf, &variable_len)) {
  758: 		SG(request_info).path_translated = estrdup(static_variable_buf);
  759: 	} else 
  760: #else
  761: 	/* happily, IIS gives us SCRIPT_NAME which is correct (without PATH_INFO stuff)
  762: 	   so we can just map that to the physical path and we have our filename */
  763: 
  764: 	lpECB->GetServerVariable(lpECB->ConnID, "SCRIPT_NAME", static_variable_buf, &variable_len);
  765: 	if (lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_MAP_URL_TO_PATH_EX, static_variable_buf, &variable_len, (LPDWORD) &humi)) {
  766: 		SG(request_info).path_translated = estrdup(humi.lpszPath);
  767: 	} else 
  768: #endif
  769: 		/* if mapping fails, default to what the server tells us */
  770: 		SG(request_info).path_translated = estrdup(lpECB->lpszPathTranslated);
  771: 
  772: 	/* some server configurations allow '..' to slip through in the
  773: 	   translated path.   We'll just refuse to handle such a path. */
  774: 	if (strstr(SG(request_info).path_translated,"..")) {
  775: 		SG(sapi_headers).http_response_code = 404;
  776: 		efree(SG(request_info).path_translated);
  777: 		SG(request_info).path_translated = NULL;
  778: 	}
  779: }
  780: 
  781: 
  782: static void php_isapi_report_exception(char *message, int message_len TSRMLS_DC)
  783: {
  784: 	if (!SG(headers_sent)) {
  785: 		HSE_SEND_HEADER_EX_INFO header_info;
  786: 		LPEXTENSION_CONTROL_BLOCK lpECB = (LPEXTENSION_CONTROL_BLOCK) SG(server_context);
  787: 
  788: 		header_info.pszStatus = "500 Internal Server Error";
  789: 		header_info.cchStatus = strlen(header_info.pszStatus);
  790: 		header_info.pszHeader = "Content-Type: text/html\r\n\r\n";
  791: 		header_info.cchHeader = strlen(header_info.pszHeader);
  792: 
  793: 		lpECB->dwHttpStatusCode = 500;
  794: 		lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL);
  795: 		SG(headers_sent)=1;
  796: 	}
  797: 	sapi_isapi_ub_write(message, message_len TSRMLS_CC);
  798: }
  799: 
  800: 
  801: BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
  802: {
  803: 	pVer->dwExtensionVersion = HSE_VERSION;
  804: #ifdef WITH_ZEUS
  805: 	strncpy( pVer->lpszExtensionDesc, isapi_sapi_module.name, HSE_MAX_EXT_DLL_NAME_LEN);
  806: #else
  807: 	lstrcpyn(pVer->lpszExtensionDesc, isapi_sapi_module.name, HSE_MAX_EXT_DLL_NAME_LEN);
  808: #endif
  809: 	return TRUE;
  810: }
  811: 
  812: 
  813: static void my_endthread()
  814: {
  815: #ifdef PHP_WIN32
  816: 	if (bTerminateThreadsOnError) {
  817: 		_endthread();
  818: 	}
  819: #endif
  820: }
  821: 
  822: #ifdef PHP_WIN32
  823: /* ep is accessible only in the context of the __except expression,
  824:  * so we have to call this function to obtain it.
  825:  */
  826: BOOL exceptionhandler(LPEXCEPTION_POINTERS *e, LPEXCEPTION_POINTERS ep)
  827: {
  828: 	*e=ep;
  829: 	return TRUE;
  830: }
  831: #endif
  832: 
  833: DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
  834: {
  835: 	zend_file_handle file_handle;
  836: 	zend_bool stack_overflown=0;
  837: 	int retval = FAILURE;
  838: #ifdef PHP_ENABLE_SEH
  839: 	LPEXCEPTION_POINTERS e;
  840: #endif
  841: 	TSRMLS_FETCH();
  842: 
  843: 	zend_first_try {
  844: #ifdef PHP_ENABLE_SEH
  845: 		__try {
  846: #endif
  847: 			init_request_info(lpECB TSRMLS_CC);
  848: 			SG(server_context) = lpECB;
  849: 
  850: 			php_request_startup(TSRMLS_C);
  851: 
  852: 			file_handle.filename = SG(request_info).path_translated;
  853: 			file_handle.free_filename = 0;
  854: 			file_handle.type = ZEND_HANDLE_FILENAME;
  855: 			file_handle.opened_path = NULL;
  856: 
  857: 			/* open the script here so we can 404 if it fails */
  858: 			if (file_handle.filename)
  859: 				retval = php_fopen_primary_script(&file_handle TSRMLS_CC);
  860: 
  861: 			if (!file_handle.filename || retval == FAILURE) {
  862: 				SG(sapi_headers).http_response_code = 404;
  863: 				PUTS("No input file specified.\n");
  864: 			} else {
  865: 				php_execute_script(&file_handle TSRMLS_CC);
  866: 			}
  867: 
  868: 			if (SG(request_info).cookie_data) {
  869: 				efree(SG(request_info).cookie_data);
  870: 			}
  871: 			if (SG(request_info).path_translated)
  872: 				efree(SG(request_info).path_translated);
  873: #ifdef PHP_ENABLE_SEH
  874: 		} __except(exceptionhandler(&e, GetExceptionInformation())) {
  875: 			char buf[1024];
  876: 			if (_exception_code()==EXCEPTION_STACK_OVERFLOW) {
  877: 				LPBYTE lpPage;
  878: 				static SYSTEM_INFO si;
  879: 				static MEMORY_BASIC_INFORMATION mi;
  880: 				static DWORD dwOldProtect;
  881: 
  882: 				GetSystemInfo(&si);
  883: 
  884: 				/* Get page ESP is pointing to */
  885: 				_asm mov lpPage, esp;
  886: 
  887: 				/* Get stack allocation base */
  888: 				VirtualQuery(lpPage, &mi, sizeof(mi));
  889: 
  890: 				/* Go to the page below the current page */
  891: 				lpPage = (LPBYTE) (mi.BaseAddress) - si.dwPageSize;
  892: 
  893: 				/* Free pages below current page */
  894: 				if (!VirtualFree(mi.AllocationBase, (LPBYTE)lpPage - (LPBYTE) mi.AllocationBase, MEM_DECOMMIT)) {
  895: 					_endthread();
  896: 				}
  897: 
  898: 				/* Restore the guard page */
  899: 				if (!VirtualProtect(lpPage, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &dwOldProtect)) {
  900: 					_endthread();
  901: 				}
  902: 
  903: 				CG(unclean_shutdown)=1;
  904: 				_snprintf(buf, sizeof(buf)-1,"PHP has encountered a Stack overflow");
  905: 				php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
  906: 			} else if (_exception_code()==EXCEPTION_ACCESS_VIOLATION) {
  907: 				_snprintf(buf, sizeof(buf)-1,"PHP has encountered an Access Violation at %p", e->ExceptionRecord->ExceptionAddress);
  908: 				php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
  909: 				my_endthread();
  910: 			} else {
  911: 				_snprintf(buf, sizeof(buf)-1,"PHP has encountered an Unhandled Exception Code %d at %p", e->ExceptionRecord->ExceptionCode , e->ExceptionRecord->ExceptionAddress);
  912: 				php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
  913: 				my_endthread();
  914: 			}
  915: 		}
  916: #endif
  917: #ifdef PHP_ENABLE_SEH
  918: 		__try {
  919: 			php_request_shutdown(NULL);
  920: 		} __except(EXCEPTION_EXECUTE_HANDLER) {
  921: 			my_endthread();
  922: 		}
  923: #else
  924: 		php_request_shutdown(NULL);
  925: #endif
  926: 	} zend_catch {
  927: 		zend_try {
  928: 			php_request_shutdown(NULL);
  929: 		} zend_end_try();
  930: 		return HSE_STATUS_ERROR;
  931: 	} zend_end_try();
  932: 
  933: 	return HSE_STATUS_SUCCESS;
  934: }
  935: 
  936: 
  937: 
  938: __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  939: {
  940: 	switch (fdwReason) {
  941: 		case DLL_PROCESS_ATTACH:
  942: #ifdef WITH_ZEUS
  943: 			tsrm_startup(128, 1, TSRM_ERROR_LEVEL_CORE, "TSRM.log");
  944: #else
  945: 			tsrm_startup(128, 1, TSRM_ERROR_LEVEL_CORE, "C:\\TSRM.log");
  946: #endif
  947: 			sapi_startup(&isapi_sapi_module);
  948: 			if (isapi_sapi_module.startup) {
  949: 				isapi_sapi_module.startup(&sapi_module);
  950: 			}
  951: 			break;
  952: 		case DLL_THREAD_ATTACH:
  953: 			break;
  954: 		case DLL_THREAD_DETACH:
  955: 			ts_free_thread();
  956: 			break;
  957: 		case DLL_PROCESS_DETACH:
  958: 			if (isapi_sapi_module.shutdown) {
  959: 				isapi_sapi_module.shutdown(&sapi_module);
  960: 			}
  961: 			sapi_shutdown();
  962: 			tsrm_shutdown();
  963: 			break;
  964: 	}
  965: 	return TRUE;
  966: }
  967: 
  968: /*
  969:  * Local variables:
  970:  * tab-width: 4
  971:  * c-basic-offset: 4
  972:  * End:
  973:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>