]> granicus.if.org Git - apache/commitdiff
Moved to modules/arch/win32/
authorWilliam A. Rowe Jr <wrowe@apache.org>
Wed, 28 Feb 2001 16:10:00 +0000 (16:10 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Wed, 28 Feb 2001 16:10:00 +0000 (16:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88393 13f79535-47bb-0310-9956-ffa450edef68

libhttpd.dsp
os/win32/mod_isapi.c [deleted file]

index b85e149f07050e3b5d8128cbced11a74590320e1..370ccce6e861cb4aa5382fbd43a9c0a4a9f70e0d 100644 (file)
@@ -318,8 +318,7 @@ SOURCE=.\modules\filters\mod_include.h
 # End Source File
 # Begin Source File
 
-SOURCE=.\os\win32\mod_isapi.c
-# ADD CPP /I "."
+SOURCE=.\modules\arch\win32\mod_isapi.c
 # End Source File
 # Begin Source File
 
diff --git a/os/win32/mod_isapi.c b/os/win32/mod_isapi.c
deleted file mode 100644 (file)
index 2ce6bc2..0000000
+++ /dev/null
@@ -1,1295 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * Portions of this software are based upon public domain software
- * originally written at the National Center for Supercomputing Applications,
- * University of Illinois, Urbana-Champaign.
- */
-
-/*
- * mod_isapi.c - Internet Server Application (ISA) module for Apache
- * by Alexei Kosut <akosut@apache.org>
- *
- * This module implements Microsoft's ISAPI, allowing Apache (when running
- * under Windows) to load Internet Server Applications (ISAPI extensions).
- * It implements all of the ISAPI 2.0 specification, except for the 
- * "Microsoft-only" extensions dealing with asynchronous I/O. All ISAPI
- * extensions that use only synchronous I/O and are compatible with the
- * ISAPI 2.0 specification should work (most ISAPI 1.0 extensions should
- * function as well).
- *
- * To load, simply place the ISA in a location in the document tree.
- * Then add an "AddHandler isapi-isa dll" into your config file.
- * You should now be able to load ISAPI DLLs just be reffering to their
- * URLs. Make sure the ExecCGI option is active in the directory
- * the ISA is in.
- */
-
-#include "apr_strings.h"
-#include "apr_portable.h"
-#include "apr_buckets.h"
-#include "ap_config.h"
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_request.h"
-#include "http_log.h"
-#include "util_script.h"
-#include "mod_core.h"
-
-/* We use the exact same header file as the original */
-#include <HttpExt.h>
-
-#if !defined(HSE_REQ_MAP_URL_TO_PATH_EX) \
- || !defined(HSE_REQ_SEND_RESPONSE_HEADER_EX)
-#pragma message("WARNING: This build of Apache is missing the recent changes")
-#pragma message("in the Microsoft Win32 Platform SDK; some mod_isapi features")
-#pragma message("will be disabled.  To obtain the latest Platform SDK files,")
-#pragma message("please refer to:")
-#pragma message("http://msdn.microsoft.com/downloads/sdks/platform/platform.asp")
-#endif
-
-/* TODO: Unknown errors that must be researched for correct codes */
-
-#define TODO_ERROR 1
-
-/* Seems IIS does not enforce the requirement for \r\n termination on HSE_REQ_SEND_RESPONSE_HEADER,
-   define this to conform */
-#define RELAX_HEADER_RULE
-
-module isapi_module;
-
-/* Declare the ISAPI functions */
-
-BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
-                               LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer);
-BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
-                         DWORD dwReserved);
-BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize);
-BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
-                                   LPVOID lpvBuffer, LPDWORD lpdwSize,
-                                   LPDWORD lpdwDataType);
-
-/*
-    The optimiser blows it totally here. What happens is that autos are addressed relative to the
-    stack pointer, which, of course, moves around. The optimiser seems to lose track of it somewhere
-    between setting HttpExtensionProc's address and calling through it. We work around the problem by 
-    forcing it to use frame pointers.
-
-    The revisions below may eliminate this artifact.
-*/
-#pragma optimize("y",off)
-
-/* Our isapi server config structure */
-
-typedef struct {
-    HANDLE lock;
-    apr_array_header_t *loaded;
-    DWORD ReadAheadBuffer;
-    int LogNotSupported;
-    int AppendLogToErrors;
-    int AppendLogToQuery;
-} isapi_server_conf;
-
-/* Our loaded isapi module description structure */
-
-typedef struct {
-    const char *filename;
-    apr_dso_handle_t *handle;
-    HSE_VERSION_INFO *pVer;
-    PFN_GETEXTENSIONVERSION GetExtensionVersion;
-    PFN_HTTPEXTENSIONPROC   HttpExtensionProc;
-    PFN_TERMINATEEXTENSION  TerminateExtension;
-    int   refcount;
-    DWORD timeout;
-    BOOL  fakeasync;
-    DWORD reportversion;
-} isapi_loaded;
-
-/* Our "Connection ID" structure */
-
-typedef struct {
-    LPEXTENSION_CONTROL_BLOCK ecb;
-    isapi_server_conf *sconf;
-    isapi_loaded *isa;
-    request_rec  *r;
-    PFN_HSE_IO_COMPLETION completion;
-    PVOID  completion_arg;
-    HANDLE complete;
-} isapi_cid;
-
-static BOOL isapi_unload(isapi_loaded* isa, int force);
-
-static apr_status_t cleanup_isapi_server_config(void *sconfv)
-{
-    isapi_server_conf *sconf = sconfv;
-    size_t n;
-    isapi_loaded **isa;
-    n = sconf->loaded->nelts;
-    isa = (isapi_loaded **)sconf->loaded->elts;
-    while(n--) {
-        if ((*isa)->handle)
-            isapi_unload(*isa, TRUE); 
-        ++isa;
-    }
-    CloseHandle(sconf->lock);
-    return APR_SUCCESS;
-}
-
-static void *create_isapi_server_config(apr_pool_t *p, server_rec *s)
-{
-    isapi_server_conf *sconf = apr_palloc(p, sizeof(isapi_server_conf));
-    sconf->loaded = apr_array_make(p, 20, sizeof(isapi_loaded*));
-    sconf->lock = CreateMutex(NULL, FALSE, NULL);
-
-    sconf->ReadAheadBuffer = 49152;
-    sconf->LogNotSupported    = -1;
-    sconf->AppendLogToErrors   = 0;
-    sconf->AppendLogToQuery    = 0;
-
-    apr_pool_cleanup_register(p, sconf, cleanup_isapi_server_config, 
-                                   apr_pool_cleanup_null);
-
-    return sconf;
-}
-
-static int compare_loaded(const void *av, const void *bv)
-{
-    const isapi_loaded **a = av;
-    const isapi_loaded **b = bv;
-
-    return strcmp((*a)->filename, (*b)->filename);
-}
-
-static void isapi_post_config(apr_pool_t *p, apr_pool_t *plog,
-                              apr_pool_t *ptemp, server_rec *s)
-{
-    isapi_server_conf *sconf = ap_get_module_config(s->module_config, 
-                                                    &isapi_module);
-    isapi_loaded **elts = (isapi_loaded **)sconf->loaded->elts;
-    int nelts = sconf->loaded->nelts;
-
-    /* sort the elements of the main_server, by filename */
-    qsort(elts, nelts, sizeof(isapi_loaded*), compare_loaded);
-
-    /* and make the virtualhosts share the same thing */
-    for (s = s->next; s; s = s->next) {
-       ap_set_module_config(s->module_config, &isapi_module, sconf);
-    }
-}
-
-static apr_status_t isapi_load(apr_pool_t *p, isapi_server_conf *sconf, 
-                               request_rec *r, const char *fpath, 
-                               isapi_loaded** isa)
-{
-    isapi_loaded **found = (isapi_loaded **)sconf->loaded->elts;
-    apr_status_t rv;
-    int n;
-
-    for (n = 0; n < sconf->loaded->nelts; ++n) {
-        if (strcasecmp(fpath, (*found)->filename) == 0) {
-            break;
-        }
-        ++found;
-    }
-    
-    if (n < sconf->loaded->nelts) 
-    {
-        *isa = *found;
-        if ((*isa)->handle) 
-        {
-            ++(*isa)->refcount;
-            return APR_SUCCESS;
-        }
-        /* Otherwise we fall through and have to reload the resource
-         * into this existing mod_isapi cache bucket.
-         */
-    }
-    else
-    {
-        *isa = apr_pcalloc(p, sizeof(isapi_module));
-        (*isa)->filename = fpath;
-        (*isa)->pVer = apr_pcalloc(p, sizeof(HSE_VERSION_INFO));
-    
-        /* TODO: These need to become overrideable, so that we
-         * assure a given isapi can be fooled into behaving well.
-         */
-        (*isa)->timeout = INFINITE; /* microsecs */
-        (*isa)->fakeasync = TRUE;
-        (*isa)->reportversion = MAKELONG(0, 5); /* Revision 5.0 */
-    }
-    
-    rv = apr_dso_load(&(*isa)->handle, fpath, p);
-    if (rv)
-    {
-        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
-                      "ISAPI %s failed to load", fpath);
-        (*isa)->handle = NULL;
-        return rv;
-    }
-
-    rv = apr_dso_sym((void**)&(*isa)->GetExtensionVersion, (*isa)->handle,
-                     "GetExtensionVersion");
-    if (rv)
-    {
-        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
-                      "ISAPI %s is missing GetExtensionVersion()",
-                      fpath);
-        apr_dso_unload((*isa)->handle);
-        (*isa)->handle = NULL;
-        return rv;
-    }
-
-    rv = apr_dso_sym((void**)&(*isa)->HttpExtensionProc, (*isa)->handle,
-                     "HttpExtensionProc");
-    if (rv)
-    {
-        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
-                      "ISAPI %s is missing HttpExtensionProc()",
-                      fpath);
-        apr_dso_unload((*isa)->handle);
-        (*isa)->handle = NULL;
-        return rv;
-    }
-
-    /* TerminateExtension() is an optional interface */
-    rv = apr_dso_sym((void**)&(*isa)->TerminateExtension, (*isa)->handle,
-                     "TerminateExtension");
-    SetLastError(0);
-
-    /* Run GetExtensionVersion() */
-    if (!((*isa)->GetExtensionVersion)((*isa)->pVer)) {
-        apr_status_t rv = apr_get_os_error();
-        ap_log_rerror(APLOG_MARK, APLOG_ALERT, rv, r,
-                      "ISAPI %s call GetExtensionVersion() failed", 
-                      fpath);
-        apr_dso_unload((*isa)->handle);
-        (*isa)->handle = NULL;
-        return rv;
-    }
-
-    ++(*isa)->refcount;
-
-    return APR_SUCCESS;
-}
-
-static int isapi_unload(isapi_loaded* isa, int force)
-{
-    /* All done with the DLL... get rid of it...
-     *
-     * If optionally cached, pass HSE_TERM_ADVISORY_UNLOAD,
-     * and if it returns TRUE, unload, otherwise, cache it.
-     */
-    if ((--isa->refcount > 0) && !force)
-        return FALSE;
-    if (isa->TerminateExtension) {
-        if (force)
-            (*isa->TerminateExtension)(HSE_TERM_MUST_UNLOAD);
-        else if (!(*isa->TerminateExtension)(HSE_TERM_ADVISORY_UNLOAD))
-            return FALSE;
-    }
-    apr_dso_unload(isa->handle);
-    isa->handle = NULL;
-    return TRUE;
-}
-
-apr_status_t isapi_handler (request_rec *r)
-{
-    isapi_server_conf * sconf;
-    apr_table_t *e;
-    apr_status_t rv;
-    isapi_loaded *isa;
-    isapi_cid *cid;
-    DWORD read;
-    int res;
-    
-    if(strcmp(r->handler, "isapi-isa"))
-        return DECLINED;    
-
-    sconf = ap_get_module_config(r->server->module_config, &isapi_module);
-    e = r->subprocess_env;
-
-    /* Use similar restrictions as CGIs
-     *
-     * If this fails, it's pointless to load the isapi dll.
-     */
-    if (!(ap_allow_options(r) & OPT_EXECCGI))
-        return HTTP_FORBIDDEN;
-
-    if (r->finfo.filetype == APR_NOFILE)
-        return HTTP_NOT_FOUND;
-
-    if (r->finfo.filetype != APR_REG)
-        return HTTP_FORBIDDEN;
-
-    /* Load the isapi extention without caching (sconf == NULL) 
-     * but note that we will recover an existing cached module.
-     */
-    if (isapi_load(r->pool, sconf, r, r->filename, &isa) != APR_SUCCESS)
-        return HTTP_INTERNAL_SERVER_ERROR;
-        
-    /* Set up variables */
-    ap_add_common_vars(r);
-    ap_add_cgi_vars(r);
-    apr_table_setn(r->subprocess_env, "UNMAPPED_REMOTE_USER", "REMOTE_USER");
-    apr_table_setn(r->subprocess_env, "SERVER_PORT_SECURE", "0");
-    apr_table_setn(r->subprocess_env, "URL", r->uri);
-
-    /* Set up connection structure and ecb */
-    cid = apr_pcalloc(r->pool, sizeof(isapi_cid));
-    cid->sconf = ap_get_module_config(r->server->module_config, &isapi_module);
-
-    cid->ecb = apr_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));
-    cid->ecb->ConnID = (HCONN)cid;
-    cid->isa = isa;
-    cid->r = r;
-    cid->r->status = 0;
-    cid->complete = NULL;
-    cid->completion = NULL;
-    
-    cid->ecb->cbSize = sizeof(EXTENSION_CONTROL_BLOCK);
-    cid->ecb->dwVersion = isa->reportversion;
-    cid->ecb->dwHttpStatusCode = 0;
-    strcpy(cid->ecb->lpszLogData, "");
-    // TODO: are copies really needed here?
-    cid->ecb->lpszMethod = apr_pstrdup(r->pool, (char*) r->method);
-    cid->ecb->lpszQueryString = apr_pstrdup(r->pool, 
-                                (char*) apr_table_get(e, "QUERY_STRING"));
-    cid->ecb->lpszPathInfo = apr_pstrdup(r->pool, 
-                             (char*) apr_table_get(e, "PATH_INFO"));
-    cid->ecb->lpszPathTranslated = apr_pstrdup(r->pool, 
-                                   (char*) apr_table_get(e, "PATH_TRANSLATED"));
-    cid->ecb->lpszContentType = apr_pstrdup(r->pool, 
-                                (char*) apr_table_get(e, "CONTENT_TYPE"));
-    /* Set up the callbacks */
-    cid->ecb->GetServerVariable = GetServerVariable;
-    cid->ecb->WriteClient = WriteClient;
-    cid->ecb->ReadClient = ReadClient;
-    cid->ecb->ServerSupportFunction = ServerSupportFunction;
-
-    
-    /* Set up client input */
-    rv = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR);
-    if (rv) {
-        isapi_unload(isa, FALSE);
-        return HTTP_INTERNAL_SERVER_ERROR; /* XXX: The wrong error */
-    }
-
-    if (ap_should_client_block(r)) {
-        /* Time to start reading the appropriate amount of data,
-         * and allow the administrator to tweak the number
-         * TODO: add the httpd.conf option for ReadAheadBuffer.
-         */
-        if (r->remaining) {
-            cid->ecb->cbTotalBytes = r->remaining;
-            if (cid->ecb->cbTotalBytes > cid->sconf->ReadAheadBuffer)
-                cid->ecb->cbAvailable = cid->sconf->ReadAheadBuffer;
-            else
-                cid->ecb->cbAvailable = cid->ecb->cbTotalBytes;
-        }
-        else
-        {
-            cid->ecb->cbTotalBytes = 0xffffffff;
-            cid->ecb->cbAvailable = cid->sconf->ReadAheadBuffer;
-        }
-
-        cid->ecb->lpbData = apr_pcalloc(r->pool, cid->ecb->cbAvailable + 1);
-
-        read = 0;
-        while (read < cid->ecb->cbAvailable &&
-               ((res = ap_get_client_block(r, cid->ecb->lpbData + read,
-                                        cid->ecb->cbAvailable - read)) > 0)) {
-            read += res;
-        }
-
-        if (res < 0) {
-            isapi_unload(isa, FALSE);
-            return HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        /* Although its not to spec, IIS seems to null-terminate
-         * its lpdData string. So we will too.
-         */
-        if (res == 0)
-            cid->ecb->cbAvailable = cid->ecb->cbTotalBytes = read;
-        else
-            cid->ecb->cbAvailable = read;
-        cid->ecb->lpbData[read] = '\0';
-    }
-    else {
-        cid->ecb->cbTotalBytes = 0;
-        cid->ecb->cbAvailable = 0;
-        cid->ecb->lpbData = NULL;
-    }
-
-    /* All right... try and run the sucker */
-    rv = (*isa->HttpExtensionProc)(cid->ecb);
-
-    /* Check for a log message - and log it */
-    if (cid->ecb->lpszLogData && *cid->ecb->lpszLogData)
-        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
-                      "ISAPI %s: %s", r->filename, cid->ecb->lpszLogData);
-
-    switch(rv) {
-        case HSE_STATUS_SUCCESS:
-        case HSE_STATUS_SUCCESS_AND_KEEP_CONN:
-            /* Ignore the keepalive stuff; Apache handles it just fine without
-             * the ISA's "advice".
-             * Per Microsoft: "In IIS versions 4.0 and later, the return
-             * values HSE_STATUS_SUCCESS and HSE_STATUS_SUCCESS_AND_KEEP_CONN
-             * are functionally identical: Keep-Alive connections are
-             * maintained, if supported by the client."
-             * ... so we were pat all this time
-             */
-            break;
-            
-        case HSE_STATUS_PENDING:    
-            /* emulating async behavior...
-             *
-             * Create a cid->completed event and wait on it for some timeout
-             * so that the app thinks is it running async.
-             *
-             * All async ServerSupportFunction calls will be handled through
-             * the registered IO_COMPLETION hook.
-             */
-            
-            if (!isa->fakeasync) {
-                if (cid->sconf->LogNotSupported)
-                {
-                     ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                                   "ISAPI %s asynch I/O request refused", 
-                                   r->filename);
-                     cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
-                }
-            }
-            else {
-                cid->complete = CreateEvent(NULL, FALSE, FALSE, NULL);
-                if (WaitForSingleObject(cid->complete, isa->timeout)
-                        == WAIT_TIMEOUT) {
-                    /* TODO: Now what... if this hung, then do we kill our own
-                     * thread to force it's death?  For now leave timeout = -1
-                     */
-                }
-            }
-            break;
-
-        case HSE_STATUS_ERROR:    
-            /* end response if we have yet to do so.
-             */
-            cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
-            break;
-
-        default:
-            /* TODO: log unrecognized retval for debugging 
-             */
-            cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
-            break;
-    }
-
-    /* Set the status (for logging) */
-    if (cid->ecb->dwHttpStatusCode) {
-        cid->r->status = cid->ecb->dwHttpStatusCode;
-    }
-
-    /* All done with the DLL... get rid of it... */
-    isapi_unload(isa, FALSE);
-    
-    return OK;         /* NOT r->status, even if it has changed. */
-}
-#pragma optimize("",on)
-
-BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
-                               LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer)
-{
-    request_rec *r = ((isapi_cid *)hConn)->r;
-    const char *result;
-    DWORD len;
-
-    if (!strcmp(lpszVariableName, "ALL_HTTP")) 
-    {
-        /* lf delimited, colon split, comma seperated and 
-         * null terminated list of HTTP_ vars 
-         */
-        char **env = (char**) apr_table_elts(r->subprocess_env)->elts;
-        int nelts = 2 * apr_table_elts(r->subprocess_env)->nelts;
-        int i;
-
-        for (len = 0, i = 0; i < nelts; i += 2)
-            if (!strncmp(env[i], "HTTP_", 5))
-                len += strlen(env[i]) + strlen(env[i + 1]) + 2;
-  
-        if (*lpdwSizeofBuffer < len + 1) {
-            *lpdwSizeofBuffer = len + 1;
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            return FALSE;
-        }
-    
-        for (i = 0; i < nelts; i += 2)
-            if (!strncmp(env[i], "HTTP_", 5)) {
-                strcpy(lpvBuffer, env[i]);
-                ((char*)lpvBuffer) += strlen(env[i]);
-                *(((char*)lpvBuffer)++) = ':';
-                strcpy(lpvBuffer, env[i + 1]);
-                ((char*)lpvBuffer) += strlen(env[i + 1]);
-                *(((char*)lpvBuffer)++) = '\n';
-            }
-
-        *(((char*)lpvBuffer)++) = '\0';
-        *lpdwSizeofBuffer = len;
-        return TRUE;
-    }
-    
-    if (!strcmp(lpszVariableName, "ALL_RAW")) 
-    {
-        /* lf delimited, colon split, comma seperated and 
-         * null terminated list of the raw request header
-         */
-        char **raw = (char**) apr_table_elts(r->headers_in)->elts;
-        int nelts = 2 * apr_table_elts(r->headers_in)->nelts;
-        int i;
-
-        for (len = 0, i = 0; i < nelts; i += 2)
-            len += strlen(raw[i]) + strlen(raw[i + 1]) + 2;
-  
-        if (*lpdwSizeofBuffer < len + 1) {
-            *lpdwSizeofBuffer = len + 1;
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            return FALSE;
-        }
-    
-        for (i = 0; i < nelts; i += 2) {
-            strcpy(lpvBuffer, raw[i]);
-            ((char*)lpvBuffer) += strlen(raw[i]);
-            *(((char*)lpvBuffer)++) = ':';
-            *(((char*)lpvBuffer)++) = ' ';
-            strcpy(lpvBuffer, raw[i + 1]);
-            ((char*)lpvBuffer) += strlen(raw[i + 1]);
-            *(((char*)lpvBuffer)++) = '\n';
-            i += 2;
-        }
-        *(((char*)lpvBuffer)++) = '\0';
-        *lpdwSizeofBuffer = len;
-        return TRUE;
-    }
-    
-    /* Not a special case */
-    result = apr_table_get(r->subprocess_env, lpszVariableName);
-
-    if (result) {
-        len = strlen(result);
-        if (*lpdwSizeofBuffer < len + 1) {
-            *lpdwSizeofBuffer = len + 1;
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            return FALSE;
-        }
-        strcpy(lpvBuffer, result);
-        *lpdwSizeofBuffer = len;
-        return TRUE;
-    }
-
-    /* Not Found */
-    SetLastError(ERROR_INVALID_INDEX);
-    return FALSE;
-}
-
-BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
-                         DWORD dwReserved)
-{
-    request_rec *r = ((isapi_cid *)ConnID)->r;
-    apr_bucket_brigade *bb;
-    apr_bucket *b;
-
-    if (dwReserved == HSE_IO_SYNC)
-        ; /* XXX: Fake it */
-
-    bb = apr_brigade_create(r->pool);
-    b = apr_bucket_transient_create(Buffer, (apr_size_t)lpwdwBytes);
-    APR_BRIGADE_INSERT_TAIL(bb, b);
-    b = apr_bucket_eos_create();
-    APR_BRIGADE_INSERT_TAIL(bb, b);
-    ap_pass_brigade(r->output_filters, bb);
-
-    return TRUE;
-}
-
-BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize)
-{
-    request_rec *r = ((isapi_cid *)ConnID)->r;
-    DWORD read = 0;
-    int res;
-
-    if (r->remaining < (long) *lpdwSize)
-        *lpdwSize = r->remaining;
-
-    while (read < *lpdwSize &&
-           ((res = ap_get_client_block(r, (char*)lpvBuffer + read,
-                                       *lpdwSize - read)) > 0)) {
-        if (res < 0) {
-            *lpdwSize = 0;
-            if (!apr_get_os_error())
-                SetLastError(TODO_ERROR); /* XXX: Find the right error code */
-            return FALSE;
-        }
-
-        read += res;
-    }
-
-    *lpdwSize = read;
-    return TRUE;
-}
-
-static apr_off_t SendResponseHeaderEx(isapi_cid *cid, const char *stat,
-                                      const char *head, apr_size_t statlen,
-                                      apr_size_t headlen)
-{
-    int termarg;
-    char *termch;
-
-    if (!stat || statlen == 0 || !*stat) {
-        stat = "Status: 200 OK";
-    }
-    else {
-        char *newstat;
-        newstat = apr_palloc(cid->r->pool, statlen + 9);
-        strcpy(newstat, "Status: ");
-        apr_cpystrn(newstat + 8, stat, statlen + 1);
-        stat = newstat;
-    }
-
-    if (!head || headlen == 0 || !*head) {
-        head = "\r\n";
-    }
-    else
-    {
-        if (head[headlen]) {
-            /* Whoops... not NULL terminated */
-            head = apr_pstrndup(cid->r->pool, head, headlen);
-        }
-    }
-    /* Parse them out, or die trying */
-    cid->r->status= ap_scan_script_header_err_strs(cid->r, NULL, &termch,
-                                                  &termarg, stat, head, NULL);
-    cid->ecb->dwHttpStatusCode = cid->r->status;
-    if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR)
-        return -1;
-    
-    /* Headers will actually go when they are good and ready */
-
-    /* Any data left is sent directly by the caller, all we
-     * give back is the size of the headers we consumed
-     */
-    if (termch && (termarg == 1) && headlen > (termch - head)) {
-        return termch - head;
-    }
-    return 0;
-}
-
-/* XXX: Is there is still an O(n^2) attack possible here?  Please detail. */
-BOOL WINAPI ServerSupportFunction(HCONN hConn, DWORD dwHSERequest,
-                                  LPVOID lpvBuffer, LPDWORD lpdwSize,
-                                  LPDWORD lpdwDataType)
-{
-    isapi_cid *cid = (isapi_cid *)hConn;
-    request_rec *r = cid->r;
-    request_rec *subreq;
-
-    switch (dwHSERequest) {
-    case 1: /* HSE_REQ_SEND_URL_REDIRECT_RESP */
-        /* Set the status to be returned when the HttpExtensionProc()
-         * is done.
-         * WARNING: Microsoft now advertises HSE_REQ_SEND_URL_REDIRECT_RESP
-         *          and HSE_REQ_SEND_URL as equivalant per the Jan 2000 SDK.
-         *          They most definately are not, even in their own samples.
-         */
-        apr_table_set (r->headers_out, "Location", lpvBuffer);
-        cid->r->status = cid->ecb->dwHttpStatusCode 
-                                               = HTTP_MOVED_TEMPORARILY;
-        return TRUE;
-
-    case 2: /* HSE_REQ_SEND_URL */
-        /* Soak up remaining input */
-        if (r->remaining > 0) {
-            char argsbuffer[HUGE_STRING_LEN];
-            while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN));
-        }
-
-        /* Reset the method to GET */
-        r->method = apr_pstrdup(r->pool, "GET");
-        r->method_number = M_GET;
-
-        /* Don't let anyone think there's still data */
-        apr_table_unset(r->headers_in, "Content-Length");
-
-        /* AV fault per PR3598 - redirected path is lost! */
-        (char*)lpvBuffer = apr_pstrdup(r->pool, (char*)lpvBuffer);
-        ap_internal_redirect((char*)lpvBuffer, r);
-        return TRUE;
-
-    case 3: /* HSE_REQ_SEND_RESPONSE_HEADER */
-    {
-        /* Parse them out, or die trying */
-        apr_size_t statlen = 0, headlen = 0;
-        int ate;
-        if (lpvBuffer)
-            statlen = strlen((char*) lpvBuffer);
-        if (lpdwDataType)
-            headlen = strlen((char*) lpdwDataType);
-        ate = SendResponseHeaderEx(cid, (char*) lpvBuffer,
-                                   (char*) lpdwDataType,
-                                   statlen, headlen);
-        if (ate < 0) {
-            SetLastError(TODO_ERROR);
-            return FALSE;
-        }
-        else if (ate < headlen) {
-            apr_bucket_brigade *bb;
-            apr_bucket *b;
-            bb = apr_brigade_create(cid->r->pool);
-           b = apr_bucket_transient_create((char*) lpdwDataType + ate, 
-                                           headlen - ate);
-           APR_BRIGADE_INSERT_TAIL(bb, b);
-            b = apr_bucket_eos_create();
-           APR_BRIGADE_INSERT_TAIL(bb, b);
-           ap_pass_brigade(cid->r->output_filters, bb);
-        }
-        return TRUE;
-    }
-
-    case 4: /* HSE_REQ_DONE_WITH_SESSION */
-        /* Signal to resume the thread completing this request
-         */
-        if (cid->complete)
-            SetEvent(cid->complete);            
-        return TRUE;
-
-    case 1001: /* HSE_REQ_MAP_URL_TO_PATH */
-    {
-        /* Map a URL to a filename */
-        char *file = (char *)lpvBuffer;
-        DWORD len;
-        subreq = ap_sub_req_lookup_uri(apr_pstrndup(r->pool, file, *lpdwSize),
-                                       r, NULL);
-
-        len = apr_cpystrn(file, subreq->filename, *lpdwSize) - file;
-
-
-        /* IIS puts a trailing slash on directories, Apache doesn't */
-        if (subreq->finfo.filetype == APR_DIR) {
-            if (len < *lpdwSize - 1) {
-                file[len++] = '\\';
-                file[len] = '\0';
-            }
-        }
-        *lpdwSize = len;
-        return TRUE;
-    }
-
-    case 1002: /* HSE_REQ_GET_SSPI_INFO */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                           "ISAPI ServerSupportFunction HSE_REQ_GET_SSPI_INFO "
-                           "is not supported: %s", r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-        
-    case 1003: /* HSE_APPEND_LOG_PARAMETER */
-        /* Log lpvBuffer, of lpdwSize bytes, in the URI Query (cs-uri-query) field
-         */
-        apr_table_set(r->notes, "isapi-parameter", (char*) lpvBuffer);
-        if (cid->sconf->AppendLogToQuery) {
-            if (r->args)
-                r->args = apr_pstrcat(r->pool, r->args, (char*) lpvBuffer, NULL);
-            else
-                r->args = apr_pstrdup(r->pool, (char*) lpvBuffer);
-        }
-        if (cid->sconf->AppendLogToErrors)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
-                          "ISAPI %s: %s", cid->r->filename,
-                          (char*) lpvBuffer);
-        return TRUE;
-        
-    case 1005: /* HSE_REQ_IO_COMPLETION */
-        /* Emulates a completion port...  Record callback address and 
-         * user defined arg, we will call this after any async request 
-         * (e.g. transmitfile) as if the request executed async.
-         * Per MS docs... HSE_REQ_IO_COMPLETION replaces any prior call
-         * to HSE_REQ_IO_COMPLETION, and lpvBuffer may be set to NULL.
-         */
-        if (!cid->isa->fakeasync) {
-            if (cid->sconf->LogNotSupported)
-                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction HSE_REQ_IO_COMPLETION "
-                          "is not supported: %s", r->filename);
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
-        }
-        cid->completion = (PFN_HSE_IO_COMPLETION) lpvBuffer;
-        cid->completion_arg = (PVOID) lpdwDataType;
-        return TRUE;
-
-    case 1006: /* HSE_REQ_TRANSMIT_FILE */
-    {
-        HSE_TF_INFO *tf = (HSE_TF_INFO*)lpvBuffer;
-        apr_status_t rv;
-        apr_bucket_brigade *bb;
-        apr_bucket *b;
-        apr_file_t *fd;
-
-        if (!cid->isa->fakeasync && (tf->dwFlags & HSE_IO_ASYNC)) {
-            if (cid->sconf->LogNotSupported)
-                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                         "ISAPI ServerSupportFunction HSE_REQ_TRANSMIT_FILE "
-                         "as HSE_IO_ASYNC is not supported: %s", r->filename);
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return FALSE;
-        }
-        
-        if ((rv = apr_os_file_put(&fd, tf->hFile, r->pool)) != APR_SUCCESS) {
-            return FALSE;
-        }
-        
-        /* apr_dupfile_oshandle (&fd, tf->hFile, r->pool); */
-        bb = apr_brigade_create(r->pool);
-
-        if (tf->dwFlags & HSE_IO_SEND_HEADERS) 
-        {
-            /* According to MS: if calling HSE_REQ_TRANSMIT_FILE with the
-             * HSE_IO_SEND_HEADERS flag, then you can't otherwise call any
-             * HSE_SEND_RESPONSE_HEADERS* fn, but if you don't use the flag,
-             * you must have done so.  They document that the pHead headers
-             * option is valid only for HSE_IO_SEND_HEADERS - we are a bit
-             * more flexible and assume with the flag, pHead are the
-             * response headers, and without, pHead simply contains text
-             * (handled after this case).
-             */
-            apr_off_t ate = SendResponseHeaderEx(cid, tf->pszStatusCode, 
-                                                 (char*)tf->pHead,
-                                                 strlen(tf->pszStatusCode), 
-                                                 (apr_size_t)tf->HeadLength);
-            if (ate < 0)
-            {
-                apr_brigade_destroy(bb);
-                SetLastError(TODO_ERROR);
-                return FALSE;
-            }
-            if (ate < (apr_size_t)tf->HeadLength)
-            {
-                b = apr_bucket_transient_create((char*)tf->pHead + ate, 
-                                            (apr_size_t)tf->HeadLength - ate);
-                APR_BRIGADE_INSERT_TAIL(bb, b);
-            }
-        }
-        else if (tf->pHead && tf->HeadLength) {
-            b = apr_bucket_transient_create((char*)tf->pHead, 
-                                           (apr_size_t)tf->HeadLength);
-            APR_BRIGADE_INSERT_TAIL(bb, b);
-        }
-
-        b = apr_bucket_file_create(fd, (apr_off_t)tf->Offset, 
-                                  (apr_size_t)tf->BytesToWrite);
-        APR_BRIGADE_INSERT_TAIL(bb, b);
-        
-        if (tf->pTail && (apr_size_t)tf->TailLength) {
-            b = apr_bucket_transient_create((char*)tf->pTail, 
-                                           (apr_size_t)tf->TailLength);
-            APR_BRIGADE_INSERT_TAIL(bb, b);
-        }
-        
-        b = apr_bucket_eos_create();
-        APR_BRIGADE_INSERT_TAIL(bb, b);
-        ap_pass_brigade(r->output_filters, bb);
-
-        /* we do nothing with (tf->dwFlags & HSE_DISCONNECT_AFTER_SEND)
-         */
-
-        if (tf->dwFlags & HSE_IO_ASYNC) {
-            /* XXX: Fake async response,
-             * use tf->pfnHseIO, or if NULL, then use cid->fnIOComplete
-             * pass pContect to the HseIO callback.
-             */
-        }
-        return TRUE;
-    }
-
-    case 1007: /* HSE_REQ_REFRESH_ISAPI_ACL */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction "
-                          "HSE_REQ_REFRESH_ISAPI_ACL "
-                          "is not supported: %s", r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-    case 1008: /* HSE_REQ_IS_KEEP_CONN */
-        *((LPBOOL) lpvBuffer) = (r->connection->keepalive == 1);
-        return TRUE;
-
-    case 1010: /* XXX: Fake it : HSE_REQ_ASYNC_READ_CLIENT */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI asynchronous I/O not supported: %s", 
-                          r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-    case 1011: /* HSE_REQ_GET_IMPERSONATION_TOKEN  Added in ISAPI 4.0 */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction "
-                          "HSE_REQ_GET_IMPERSONATION_TOKEN "
-                          "is not supported: %s", r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-#ifdef HSE_REQ_MAP_URL_TO_PATH_EX
-    case 1012: /* HSE_REQ_MAP_URL_TO_PATH_EX */
-    {
-        /* Map a URL to a filename */
-        LPHSE_URL_MAPEX_INFO info = (LPHSE_URL_MAPEX_INFO) lpdwDataType;
-        char* test_uri = apr_pstrndup(r->pool, (char *)lpvBuffer, *lpdwSize);
-
-        subreq = ap_sub_req_lookup_uri(test_uri, r, NULL);
-        info->cchMatchingURL = strlen(test_uri);        
-        info->cchMatchingPath = apr_cpystrn(info->lpszPath, subreq->filename, 
-                                            MAX_PATH) - info->lpszPath;
-
-        /* Mapping started with assuming both strings matched.
-         * Now roll on the path_info as a mismatch and handle
-         * terminating slashes for directory matches.
-         */
-        if (subreq->path_info && *subreq->path_info) {
-            apr_cpystrn(info->lpszPath + info->cchMatchingPath, 
-                        subreq->path_info, MAX_PATH - info->cchMatchingPath);
-            info->cchMatchingURL -= strlen(subreq->path_info);
-            if (subreq->finfo.filetype == APR_DIR
-                 && info->cchMatchingPath < MAX_PATH - 1) {
-                /* roll forward over path_info's first slash */
-                ++info->cchMatchingPath;
-                ++info->cchMatchingURL;
-            }
-        }
-        else if (subreq->finfo.filetype == APR_DIR
-                 && info->cchMatchingPath < MAX_PATH - 1) {
-            /* Add a trailing slash for directory */
-            info->lpszPath[info->cchMatchingPath++] = '/';
-            info->lpszPath[info->cchMatchingPath] = '\0';
-        }
-
-        /* If the matched isn't a file, roll match back to the prior slash */
-        if (subreq->finfo.filetype == APR_NOFILE) {
-            while (info->cchMatchingPath && info->cchMatchingURL) {
-                if (info->lpszPath[info->cchMatchingPath - 1] == '/') 
-                    break;
-                --info->cchMatchingPath;
-                --info->cchMatchingURL;
-            }
-        }
-        
-        /* Paths returned with back slashes */
-        for (test_uri = info->lpszPath; *test_uri; ++test_uri)
-            if (*test_uri == '/')
-                *test_uri = '\\';
-        
-        /* is a combination of:
-         * HSE_URL_FLAGS_READ         0x001 Allow read
-         * HSE_URL_FLAGS_WRITE        0x002 Allow write
-         * HSE_URL_FLAGS_EXECUTE      0x004 Allow execute
-         * HSE_URL_FLAGS_SSL          0x008 Require SSL
-         * HSE_URL_FLAGS_DONT_CACHE   0x010 Don't cache (VRoot only)
-         * HSE_URL_FLAGS_NEGO_CERT    0x020 Allow client SSL cert
-         * HSE_URL_FLAGS_REQUIRE_CERT 0x040 Require client SSL cert
-         * HSE_URL_FLAGS_MAP_CERT     0x080 Map client SSL cert to account
-         * HSE_URL_FLAGS_SSL128       0x100 Require 128-bit SSL cert
-         * HSE_URL_FLAGS_SCRIPT       0x200 Allow script execution
-         *
-         * XxX: As everywhere, EXEC flags could use some work...
-         *      and this could go further with more flags, as desired.
-         */ 
-        info->dwFlags = (subreq->finfo.protection & APR_UREAD    ? 0x001 : 0)
-                      | (subreq->finfo.protection & APR_UWRITE   ? 0x002 : 0)
-                      | (subreq->finfo.protection & APR_UEXECUTE ? 0x204 : 0);
-        return TRUE;
-    }
-#endif
-
-    case 1014: /* HSE_REQ_ABORTIVE_CLOSE */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE"
-                          " is not supported: %s", r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-    case 1015: /* HSE_REQ_GET_CERT_INFO_EX  Added in ISAPI 4.0 */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction "
-                          "HSE_REQ_GET_CERT_INFO_EX "
-                          "is not supported: %s", r->filename);        
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-#ifdef HSE_REQ_SEND_RESPONSE_HEADER_EX
-    case 1016: /* HSE_REQ_SEND_RESPONSE_HEADER_EX  Added in ISAPI 4.0 */
-    {
-        LPHSE_SEND_HEADER_EX_INFO shi
-                                  = (LPHSE_SEND_HEADER_EX_INFO) lpvBuffer;
-        /* XXX: ignore shi->fKeepConn?  We shouldn't need the advise */
-        /* r->connection->keepalive = shi->fKeepConn; */
-        apr_off_t ate = SendResponseHeaderEx(cid, shi->pszStatus, 
-                                             shi->pszHeader,
-                                             shi->cchStatus, 
-                                             shi->cchHeader);
-        if (ate < 0) {
-            SetLastError(TODO_ERROR);
-            return FALSE;
-        }
-        else if (ate < (apr_off_t)shi->cchHeader) {
-            apr_bucket_brigade *bb;
-            apr_bucket *b;
-            bb = apr_brigade_create(cid->r->pool);
-           b = apr_bucket_transient_create(shi->pszHeader + ate, 
-                                           (apr_size_t)shi->cchHeader - ate);
-           APR_BRIGADE_INSERT_TAIL(bb, b);
-            b = apr_bucket_eos_create();
-           APR_BRIGADE_INSERT_TAIL(bb, b);
-           ap_pass_brigade(cid->r->output_filters, bb);
-        }
-        return TRUE;
-
-    }
-#endif
-
-    case 1017: /* HSE_REQ_CLOSE_CONNECTION  Added after ISAPI 4.0 */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction "
-                          "HSE_REQ_CLOSE_CONNECTION "
-                          "is not supported: %s", r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-    case 1018: /* HSE_REQ_IS_CONNECTED  Added after ISAPI 4.0 */
-        /* Returns True if client is connected c.f. MSKB Q188346
-         * assuming the identical return mechanism as HSE_REQ_IS_KEEP_CONN
-         */
-        *((LPBOOL) lpvBuffer) = (r->connection->aborted == 0);
-        return TRUE;
-
-    case 1020: /* HSE_REQ_EXTENSION_TRIGGER  Added after ISAPI 4.0 */
-        /*  Undocumented - defined by the Microsoft Jan '00 Platform SDK
-         */
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction "
-                          "HSE_REQ_EXTENSION_TRIGGER "
-                          "is not supported: %s", r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-
-    default:
-        if (cid->sconf->LogNotSupported)
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
-                          "ISAPI ServerSupportFunction (%d) not supported: "
-                          "%s", dwHSERequest, r->filename);
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-}
-
-/*
- * Command handler for the ISAPIReadAheadBuffer directive, which is TAKE1
- */
-static const char *isapi_cmd_readaheadbuffer(cmd_parms *cmd, void *config, 
-                                             char *arg)
-{
-    isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
-                                                   &isapi_module);
-    char *scan;
-    long val;
-
-    if (((val = strtol(arg, (char **) &scan, 10)) <= 0) || *scan)
-        return "ISAPIReadAheadBuffer must be a legitimate value.";
-    
-    sconf->ReadAheadBuffer = val;
-    return NULL;
-}
-
-/*
- * Command handler for the ISAPIReadAheadBuffer directive, which is TAKE1
- */
-static const char *isapi_cmd_lognotsupported(cmd_parms *cmd, void *config, 
-                                             char *arg)
-{
-    isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
-                                               &isapi_module);
-
-    if (strcasecmp(arg, "on") == 0) {
-        sconf->LogNotSupported = -1;
-    }
-    else if (strcasecmp(arg, "off") == 0) {
-        sconf->LogNotSupported = 0;
-    }
-    else {
-        return "ISAPILogNotSupported must be on or off";
-    }
-    return NULL;
-}
-
-static const char *isapi_cmd_appendlogtoerrors(cmd_parms *cmd, void *config, 
-                                               char *arg)
-{
-    isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
-                                                   &isapi_module);
-
-    if (strcasecmp(arg, "on") == 0) {
-        sconf->AppendLogToErrors = -1;
-    }
-    else if (strcasecmp(arg, "off") == 0) {
-        sconf->AppendLogToErrors = 0;
-    }
-    else {
-        return "ISAPIAppendLogToErrors must be on or off";
-    }
-    return NULL;
-}
-
-static const char *isapi_cmd_appendlogtoquery(cmd_parms *cmd, void *config, 
-                                               char *arg)
-{
-    isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config,
-                                                   &isapi_module);
-
-    if (strcasecmp(arg, "on") == 0) {
-        sconf->AppendLogToQuery = -1;
-    }
-    else if (strcasecmp(arg, "off") == 0) {
-        sconf->AppendLogToQuery = 0;
-    }
-    else {
-        return "ISAPIAppendLogToQuery must be on or off";
-    }
-    return NULL;
-}
-
-static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy, 
-                                       const char *filename)
-
-{
-    isapi_server_conf *sconf = ap_get_module_config(cmd->server->module_config, 
-                                                    &isapi_module);
-    isapi_loaded *isa, **newisa;
-    apr_finfo_t tmp;
-    apr_status_t rv;
-    char *fspec;
-    
-    fspec = ap_os_case_canonical_filename(cmd->pool, filename);
-    if (apr_stat(&tmp, fspec, 
-                 APR_FINFO_TYPE, cmd->temp_pool) != APR_SUCCESS) { 
-       ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
-           "ISAPI: unable to stat(%s), skipping", filename);
-       return NULL;
-    }
-    if (tmp.filetype != APR_REG) {
-       ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
-           "ISAPI: %s isn't a regular file, skipping", filename);
-       return NULL;
-    }
-
-    /* Load the extention as cached (passing sconf) */
-    rv = isapi_load(cmd->pool, sconf, NULL, fspec, &isa); 
-    if (rv != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server,
-                     "ISAPI: unable to cache %s, skipping", filename);
-       return NULL;
-    }
-
-    /* Add to cached list of loaded modules */
-    newisa = apr_array_push(sconf->loaded);
-    *newisa = isa;
-    
-    return NULL;
-}
-
-static void isapi_hooks(apr_pool_t *cont)
-{
-    ap_hook_post_config(isapi_post_config, NULL, NULL, APR_HOOK_MIDDLE);
-    ap_hook_handler(isapi_handler, NULL, NULL, APR_HOOK_MIDDLE);
-}
-
-static const command_rec isapi_cmds[] = {
-AP_INIT_TAKE1("ISAPIReadAheadBuffer", isapi_cmd_readaheadbuffer, NULL, RSRC_CONF,
-  "Maximum bytes to initially pass to the ISAPI handler"),
-AP_INIT_TAKE1("ISAPILogNotSupported", isapi_cmd_lognotsupported, NULL, RSRC_CONF,
-  "Log requests not supported by the ISAPI server"),
-AP_INIT_TAKE1("ISAPIAppendLogToErrors", isapi_cmd_appendlogtoerrors, NULL, RSRC_CONF,
-  "Send all Append Log requests to the error log"),
-AP_INIT_TAKE1("ISAPIAppendLogToQuery", isapi_cmd_appendlogtoquery, NULL, RSRC_CONF,
-  "Append Log requests are concatinated to the query args"),
-AP_INIT_ITERATE("ISAPICacheFile", isapi_cmd_cachefile, NULL, RSRC_CONF,
-  "Cache the specified ISAPI extension in-process"),
-{ NULL }
-};
-
-module isapi_module = {
-   STANDARD20_MODULE_STUFF,
-   NULL,                        /* create per-dir config */
-   NULL,                        /* merge per-dir config */
-   create_isapi_server_config,  /* server config */
-   NULL,                        /* merge server config */
-   isapi_cmds,                  /* command apr_table_t */
-   isapi_hooks                  /* register hooks */
-};