Commit 6c112ea7 authored by Bill Stoddard's avatar Bill Stoddard
Browse files

Win32: First cut at getting mod_isapi working under 2.0

Submitted by:	William Rowe


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@84976 13f79535-47bb-0310-9956-ffa450edef68
parent 28ffcb96
Loading
Loading
Loading
Loading
+4 −0
Changes for ApacheCore.dsp: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -196,6 +196,10 @@ SOURCE=.\modules\standard\mod_include.c
# End Source File
# Begin Source File

SOURCE=.\os\win32\mod_isapi.c
# End Source File
# Begin Source File

SOURCE=.\modules\standard\mod_log_config.c
# End Source File
# Begin Source File
+4 −0
Changes for httpd.dsp: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -196,6 +196,10 @@ SOURCE=.\modules\standard\mod_include.c
# End Source File
# Begin Source File

SOURCE=.\os\win32\mod_isapi.c
# End Source File
# Begin Source File

SOURCE=.\modules\standard\mod_log_config.c
# End Source File
# Begin Source File
+44 −32
Changes for modules/arch/win32/mod_isapi.c: 44 added lines, 32 removed lines.
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@
 * the ISA is in.
 */

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
@@ -82,6 +83,7 @@
#include "http_request.h"
#include "http_log.h"
#include "util_script.h"
#include "apr_portable.h"

/* We use the exact same header file as the original */
#include <HttpExt.h>
@@ -119,7 +121,10 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
*/
#pragma optimize("y",off)

int isapi_handler (request_rec *r) {
int isapi_handler (request_rec *r)
{
    ap_status_t rv;

    LPEXTENSION_CONTROL_BLOCK ecb =
        ap_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));
    HSE_VERSION_INFO *pVer = ap_pcalloc(r->pool, sizeof(HSE_VERSION_INFO));
@@ -138,44 +143,51 @@ int isapi_handler (request_rec *r) {
    if (!(ap_allow_options(r) & OPT_EXECCGI))
        return FORBIDDEN;

    if (r->finfo.st_mode == 0)
    if (r->finfo.protection == 0)
            return NOT_FOUND;

    if (S_ISDIR(r->finfo.st_mode))
    if (S_ISDIR(r->finfo.protection))
            return FORBIDDEN;

    /* Load the module */

    if (!(isapi_handle = LoadLibraryEx(r->filename, NULL,
                                       LOAD_WITH_ALTERED_SEARCH_PATH))) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
            rv = GetLastError();
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                              "Could not load DLL: %s", r->filename);
            return SERVER_ERROR;
    }

    if (!(isapi_version =
          (void *)(GetProcAddress(isapi_handle, "GetExtensionVersion")))) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
		    "DLL could not load GetExtensionVersion(): %s", r->filename);
            rv = GetLastError();
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                              "Could not load DLL %s symbol GetExtensionVersion()",
                      r->filename);
            FreeLibrary(isapi_handle);
            return SERVER_ERROR;
    }

    if (!(isapi_entry =
          (void *)(GetProcAddress(isapi_handle, "HttpExtensionProc")))) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
		    "DLL could not load HttpExtensionProc(): %s", r->filename);
            rv = GetLastError();
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                              "Could not load DLL %s symbol HttpExtensionProc()",
                      r->filename);
            FreeLibrary(isapi_handle);
            return SERVER_ERROR;
    }

    /* TerminateExtension() is an optional interface */

    isapi_term = (void *)(GetProcAddress(isapi_handle, "TerminateExtension"));

    /* Run GetExtensionVersion() */

    if (!(*isapi_version)(pVer)) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
		    "ISAPI GetExtensionVersion() failed: %s", r->filename);
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, SERVER_ERROR, r,
                    "ISAPI %s GetExtensionVersion() call failed", r->filename);
            FreeLibrary(isapi_handle);
            return SERVER_ERROR;
    }
@@ -265,8 +277,8 @@ int isapi_handler (request_rec *r) {

    /* Check for a log message - and log it */
    if (ecb->lpszLogData && strcmp(ecb->lpszLogData, ""))
	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
		    "%s: %s", ecb->lpszLogData, r->filename);
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                      "ISAPI %s: %s", r->filename, ecb->lpszLogData);

    /* All done with the DLL... get rid of it */
    if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
@@ -283,11 +295,14 @@ int isapi_handler (request_rec *r) {
                return cid->status;

            return OK;

    case HSE_STATUS_PENDING:    /* We don't support this */
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
        rv = APR_ENOTIMPL;
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, SERVER_ERROR, r,
                    "ISAPI asynchronous I/O not supported: %s", r->filename);
    case HSE_STATUS_ERROR:
    default:

        return SERVER_ERROR;
    }

@@ -295,7 +310,8 @@ int isapi_handler (request_rec *r) {
#pragma optimize("",on)

BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
			       LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer) {
                               LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer)
{
    request_rec *r = ((isapi_cid *)hConn)->r;
    ap_table_t *e = r->subprocess_env;
    const char *result;
@@ -340,20 +356,21 @@ BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
}

BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
			 DWORD dwReserved) {
                                 DWORD dwReserved)
{
    request_rec *r = ((isapi_cid *)ConnID)->r;
    int writ;   /* written, actually, but why shouldn't I make up words? */

    /* We only support synchronous writing */
    if (dwReserved && dwReserved != HSE_IO_SYNC) {
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, ERROR_INVALID_PARAMETER, r,
                      "ISAPI asynchronous I/O not supported: %s", r->filename);
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
    }

    if ((writ = ap_rwrite(Buffer, *lpwdwBytes, r)) == EOF) {
	SetLastError(ERROR); /* XXX: Find the right error code */
            SetLastError(ERROR); /* TODO: Find the right error code */
            return FALSE;
    }

@@ -361,7 +378,8 @@ BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
    return TRUE;
}

BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) {
BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize)
{
    /* Doesn't need to do anything; we've read all the data already */
    return TRUE;
}
@@ -369,7 +387,8 @@ BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) {
/* XXX: There is an O(n^2) attack possible here. */
BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
                                                   LPVOID lpvBuffer, LPDWORD lpdwSize,
				   LPDWORD lpdwDataType) {
                                                   LPDWORD lpdwDataType)
{
    isapi_cid *cid = (isapi_cid *)hConn;
    request_rec *subreq, *r = cid->r;
    char *data;
@@ -454,8 +473,8 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
                }

                if (!(value = strchr(data, ':'))) {
		SetLastError(ERROR);	/* XXX: Find right error */
		ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
                        SetLastError(ERROR);    /* TODO: Find right error */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, SERVER_ERROR, r,
                                          "ISA sent invalid headers", r->filename);
                        return FALSE;
                }
@@ -520,7 +539,7 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,

            /* IIS puts a trailing slash on directories, Apache doesn't */

	if (S_ISDIR (subreq->finfo.st_mode)) {
            if (S_ISDIR (subreq->finfo.protection)) {
                    int l = strlen((char *)lpvBuffer);

                    ((char *)lpvBuffer)[l] = '\\';
@@ -538,7 +557,7 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
    /* We don't support all this async I/O, Microsoft-specific stuff */
    case HSE_REQ_IO_COMPLETION:
    case HSE_REQ_TRANSMIT_FILE:
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, SERVER_ERROR, r,
                        "ISAPI asynchronous I/O not supported: %s", r->filename);
    default:
            SetLastError(ERROR_INVALID_PARAMETER);
@@ -552,19 +571,12 @@ handler_rec isapi_handlers[] = {
};

module isapi_module = {
   STANDARD_MODULE_STUFF,
   NULL,			/* initializer */
   STANDARD20_MODULE_STUFF,
   NULL,                        /* create per-dir config */
   NULL,                        /* merge per-dir config */
   NULL,                        /* server config */
   NULL,                        /* merge server config */
   NULL,                        /* command ap_table_t */
   isapi_handlers,      /* handlers */
   NULL,			/* filename translation */
   NULL,			/* check_user_id */
   NULL,			/* check auth */
   NULL,			/* check access */
   NULL,			/* type_checker */
   NULL,			/* logger */
   NULL				/* header parser */
   NULL                         /* register hooks */
};
+44 −32
Changes for os/win32/mod_isapi.c: 44 added lines, 32 removed lines.
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@
 * the ISA is in.
 */

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
@@ -82,6 +83,7 @@
#include "http_request.h"
#include "http_log.h"
#include "util_script.h"
#include "apr_portable.h"

/* We use the exact same header file as the original */
#include <HttpExt.h>
@@ -119,7 +121,10 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
*/
#pragma optimize("y",off)

int isapi_handler (request_rec *r) {
int isapi_handler (request_rec *r)
{
    ap_status_t rv;

    LPEXTENSION_CONTROL_BLOCK ecb =
        ap_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));
    HSE_VERSION_INFO *pVer = ap_pcalloc(r->pool, sizeof(HSE_VERSION_INFO));
@@ -138,44 +143,51 @@ int isapi_handler (request_rec *r) {
    if (!(ap_allow_options(r) & OPT_EXECCGI))
        return FORBIDDEN;

    if (r->finfo.st_mode == 0)
    if (r->finfo.protection == 0)
            return NOT_FOUND;

    if (S_ISDIR(r->finfo.st_mode))
    if (S_ISDIR(r->finfo.protection))
            return FORBIDDEN;

    /* Load the module */

    if (!(isapi_handle = LoadLibraryEx(r->filename, NULL,
                                       LOAD_WITH_ALTERED_SEARCH_PATH))) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
            rv = GetLastError();
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                              "Could not load DLL: %s", r->filename);
            return SERVER_ERROR;
    }

    if (!(isapi_version =
          (void *)(GetProcAddress(isapi_handle, "GetExtensionVersion")))) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
		    "DLL could not load GetExtensionVersion(): %s", r->filename);
            rv = GetLastError();
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                              "Could not load DLL %s symbol GetExtensionVersion()",
                      r->filename);
            FreeLibrary(isapi_handle);
            return SERVER_ERROR;
    }

    if (!(isapi_entry =
          (void *)(GetProcAddress(isapi_handle, "HttpExtensionProc")))) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
		    "DLL could not load HttpExtensionProc(): %s", r->filename);
            rv = GetLastError();
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
                              "Could not load DLL %s symbol HttpExtensionProc()",
                      r->filename);
            FreeLibrary(isapi_handle);
            return SERVER_ERROR;
    }

    /* TerminateExtension() is an optional interface */

    isapi_term = (void *)(GetProcAddress(isapi_handle, "TerminateExtension"));

    /* Run GetExtensionVersion() */

    if (!(*isapi_version)(pVer)) {
	ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
		    "ISAPI GetExtensionVersion() failed: %s", r->filename);
        ap_log_rerror(APLOG_MARK, APLOG_ALERT, SERVER_ERROR, r,
                    "ISAPI %s GetExtensionVersion() call failed", r->filename);
            FreeLibrary(isapi_handle);
            return SERVER_ERROR;
    }
@@ -265,8 +277,8 @@ int isapi_handler (request_rec *r) {

    /* Check for a log message - and log it */
    if (ecb->lpszLogData && strcmp(ecb->lpszLogData, ""))
	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
		    "%s: %s", ecb->lpszLogData, r->filename);
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                      "ISAPI %s: %s", r->filename, ecb->lpszLogData);

    /* All done with the DLL... get rid of it */
    if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
@@ -283,11 +295,14 @@ int isapi_handler (request_rec *r) {
                return cid->status;

            return OK;

    case HSE_STATUS_PENDING:    /* We don't support this */
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
        rv = APR_ENOTIMPL;
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, SERVER_ERROR, r,
                    "ISAPI asynchronous I/O not supported: %s", r->filename);
    case HSE_STATUS_ERROR:
    default:

        return SERVER_ERROR;
    }

@@ -295,7 +310,8 @@ int isapi_handler (request_rec *r) {
#pragma optimize("",on)

BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
			       LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer) {
                               LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer)
{
    request_rec *r = ((isapi_cid *)hConn)->r;
    ap_table_t *e = r->subprocess_env;
    const char *result;
@@ -340,20 +356,21 @@ BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
}

BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
			 DWORD dwReserved) {
                                 DWORD dwReserved)
{
    request_rec *r = ((isapi_cid *)ConnID)->r;
    int writ;   /* written, actually, but why shouldn't I make up words? */

    /* We only support synchronous writing */
    if (dwReserved && dwReserved != HSE_IO_SYNC) {
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, ERROR_INVALID_PARAMETER, r,
                      "ISAPI asynchronous I/O not supported: %s", r->filename);
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
    }

    if ((writ = ap_rwrite(Buffer, *lpwdwBytes, r)) == EOF) {
	SetLastError(ERROR); /* XXX: Find the right error code */
            SetLastError(ERROR); /* TODO: Find the right error code */
            return FALSE;
    }

@@ -361,7 +378,8 @@ BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
    return TRUE;
}

BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) {
BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize)
{
    /* Doesn't need to do anything; we've read all the data already */
    return TRUE;
}
@@ -369,7 +387,8 @@ BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) {
/* XXX: There is an O(n^2) attack possible here. */
BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
                                                   LPVOID lpvBuffer, LPDWORD lpdwSize,
				   LPDWORD lpdwDataType) {
                                                   LPDWORD lpdwDataType)
{
    isapi_cid *cid = (isapi_cid *)hConn;
    request_rec *subreq, *r = cid->r;
    char *data;
@@ -454,8 +473,8 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
                }

                if (!(value = strchr(data, ':'))) {
		SetLastError(ERROR);	/* XXX: Find right error */
		ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
                        SetLastError(ERROR);    /* TODO: Find right error */
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, SERVER_ERROR, r,
                                          "ISA sent invalid headers", r->filename);
                        return FALSE;
                }
@@ -520,7 +539,7 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,

            /* IIS puts a trailing slash on directories, Apache doesn't */

	if (S_ISDIR (subreq->finfo.st_mode)) {
            if (S_ISDIR (subreq->finfo.protection)) {
                    int l = strlen((char *)lpvBuffer);

                    ((char *)lpvBuffer)[l] = '\\';
@@ -538,7 +557,7 @@ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
    /* We don't support all this async I/O, Microsoft-specific stuff */
    case HSE_REQ_IO_COMPLETION:
    case HSE_REQ_TRANSMIT_FILE:
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, SERVER_ERROR, r,
                        "ISAPI asynchronous I/O not supported: %s", r->filename);
    default:
            SetLastError(ERROR_INVALID_PARAMETER);
@@ -552,19 +571,12 @@ handler_rec isapi_handlers[] = {
};

module isapi_module = {
   STANDARD_MODULE_STUFF,
   NULL,			/* initializer */
   STANDARD20_MODULE_STUFF,
   NULL,                        /* create per-dir config */
   NULL,                        /* merge per-dir config */
   NULL,                        /* server config */
   NULL,                        /* merge server config */
   NULL,                        /* command ap_table_t */
   isapi_handlers,      /* handlers */
   NULL,			/* filename translation */
   NULL,			/* check_user_id */
   NULL,			/* check auth */
   NULL,			/* check access */
   NULL,			/* type_checker */
   NULL,			/* logger */
   NULL				/* header parser */
   NULL                         /* register hooks */
};
+3 −3
Changes for os/win32/modules.c: 3 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ extern module asis_module;
extern module imap_module;
extern module action_module;
extern module setenvif_module;
//extern module isapi_module;
extern module isapi_module;

module *ap_prelinked_modules[] = {
  &core_module,
@@ -47,7 +47,7 @@ module *ap_prelinked_modules[] = {
  &imap_module,
  &action_module,
  &setenvif_module,
//  &isapi_module,
  &isapi_module,
  NULL
};
module *ap_preloaded_modules[] = {
@@ -70,6 +70,6 @@ module *ap_preloaded_modules[] = {
  &imap_module,
  &action_module,
  &setenvif_module,
//  &isapi_module,
  &isapi_module,
  NULL
};