📄 mod_win32.c
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#ifdef WIN32#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"#include "mod_cgi.h"#include "apr_lib.h"#include "ap_regkey.h"extern OSVERSIONINFO osver; /* hiding in mpm_winnt.c */static int win_nt;/* * CGI Script stuff for Win32... */typedef enum { eFileTypeUNKNOWN, eFileTypeBIN, eFileTypeEXE16, eFileTypeEXE32, eFileTypeSCRIPT } file_type_e;typedef enum { INTERPRETER_SOURCE_UNSET, INTERPRETER_SOURCE_REGISTRY_STRICT, INTERPRETER_SOURCE_REGISTRY, INTERPRETER_SOURCE_SHEBANG } interpreter_source_e;AP_DECLARE(file_type_e) ap_get_win32_interpreter(const request_rec *, char **interpreter, char **arguments);module AP_MODULE_DECLARE_DATA win32_module;typedef struct { /* Where to find interpreter to run scripts */ interpreter_source_e script_interpreter_source;} win32_dir_conf;static void *create_win32_dir_config(apr_pool_t *p, char *dir){ win32_dir_conf *conf; conf = (win32_dir_conf*)apr_palloc(p, sizeof(win32_dir_conf)); conf->script_interpreter_source = INTERPRETER_SOURCE_UNSET; return conf;}static void *merge_win32_dir_configs(apr_pool_t *p, void *basev, void *addv){ win32_dir_conf *new; win32_dir_conf *base = (win32_dir_conf *) basev; win32_dir_conf *add = (win32_dir_conf *) addv; new = (win32_dir_conf *) apr_pcalloc(p, sizeof(win32_dir_conf)); new->script_interpreter_source = (add->script_interpreter_source != INTERPRETER_SOURCE_UNSET) ? add->script_interpreter_source : base->script_interpreter_source; return new;}static const char *set_interpreter_source(cmd_parms *cmd, void *dv, char *arg){ win32_dir_conf *d = (win32_dir_conf *)dv; if (!strcasecmp(arg, "registry")) { d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY; } else if (!strcasecmp(arg, "registry-strict")) { d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY_STRICT; } else if (!strcasecmp(arg, "script")) { d->script_interpreter_source = INTERPRETER_SOURCE_SHEBANG; } else { return apr_pstrcat(cmd->temp_pool, "ScriptInterpreterSource \"", arg, "\" must be \"registry\", \"registry-strict\" or " "\"script\"", NULL); } return NULL;}/* XXX: prep_string should translate the string into unicode, * such that it is compatible with whatever codepage the client * will read characters 80-ff. For the moment, use the unicode * values 0080-00ff. This isn't trivial, since the code page * varies between msdos and Windows applications. * For subsystem 2 [GUI] the default is the system Ansi CP. * For subsystem 3 [CLI] the default is the system OEM CP. */ static void prep_string(const char ** str, apr_pool_t *p){ const char *ch = *str; char *ch2; int widen = 0; if (!ch) { return; } while (*ch) { if (*(ch++) & 0x80) { ++widen; } } if (!widen) { return; } widen += (ch - *str) + 1; ch = *str; *str = ch2 = apr_palloc(p, widen); while (*ch) { if (*ch & 0x80) { /* sign extension won't hurt us here */ *(ch2++) = 0xC0 | ((*ch >> 6) & 0x03); *(ch2++) = 0x80 | (*(ch++) & 0x3f); } else { *(ch2++) = *(ch++); } } *(ch2++) = '\0';}/* Somewhat more exciting ... figure out where the registry has stashed the * ExecCGI or Open command - it may be nested one level deep (or more???) */static char* get_interpreter_from_win32_registry(apr_pool_t *p, const char* ext, int strict){ apr_status_t rv; ap_regkey_t *name_key = NULL; ap_regkey_t *type_key; ap_regkey_t *key; char execcgi_path[] = "SHELL\\EXECCGI\\COMMAND"; char execopen_path[] = "SHELL\\OPEN\\COMMAND"; char *type_name; char *buffer; if (!ext) { return NULL; } /* * Future optimization: * When the registry is successfully searched, store the strings for * interpreter and arguments in an ext hash to speed up subsequent look-ups */ /* Open the key associated with the script filetype extension */ rv = ap_regkey_open(&type_key, AP_REGKEY_CLASSES_ROOT, ext, APR_READ, p); if (rv != APR_SUCCESS) { return NULL; } /* Retrieve the name of the script filetype extension */ rv = ap_regkey_value_get(&type_name, type_key, "", p); if (rv == APR_SUCCESS && type_name[0]) { /* Open the key associated with the script filetype extension */ rv = ap_regkey_open(&name_key, AP_REGKEY_CLASSES_ROOT, type_name, APR_READ, p); } /* Open the key for the script command path by: * * 1) the 'named' filetype key for ExecCGI/Command * 2) the extension's type key for ExecCGI/Command * * and if the strict arg is false, then continue trying: * * 3) the 'named' filetype key for Open/Command * 4) the extension's type key for Open/Command */ if (name_key) { if ((rv = ap_regkey_open(&key, name_key, execcgi_path, APR_READ, p)) == APR_SUCCESS) { rv = ap_regkey_value_get(&buffer, key, "", p); ap_regkey_close(name_key); } } if (!name_key || (rv != APR_SUCCESS)) { if ((rv = ap_regkey_open(&key, type_key, execcgi_path, APR_READ, p)) == APR_SUCCESS) { rv = ap_regkey_value_get(&buffer, key, "", p); ap_regkey_close(type_key); } } if (!strict && name_key && (rv != APR_SUCCESS)) { if ((rv = ap_regkey_open(&key, name_key, execopen_path, APR_READ, p)) == APR_SUCCESS) { rv = ap_regkey_value_get(&buffer, key, "", p); ap_regkey_close(name_key); } } if (!strict && (rv != APR_SUCCESS)) { if ((rv = ap_regkey_open(&key, type_key, execopen_path, APR_READ, p)) == APR_SUCCESS) { rv = ap_regkey_value_get(&buffer, key, "", p); ap_regkey_close(type_key); } } if (name_key) { ap_regkey_close(name_key); } ap_regkey_close(type_key); if (rv != APR_SUCCESS || !buffer[0]) { return NULL; } return buffer;}static apr_array_header_t *split_argv(apr_pool_t *p, const char *interp, const char *cgiprg, const char *cgiargs){ apr_array_header_t *args = apr_array_make(p, 8, sizeof(char*)); char *d = apr_palloc(p, strlen(interp)+1); const char *ch = interp; const char **arg; int prgtaken = 0; int argtaken = 0; int inquo; int sl; while (*ch) { /* Skip on through Deep Space */ if (apr_isspace(*ch)) { ++ch; continue; } /* One Arg */ if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '*')) { const char *cgiarg = cgiargs; argtaken = 1; for (;;) { char *w = ap_getword_nulls(p, &cgiarg, '+'); if (!*w) { break; } ap_unescape_url(w); if (win_nt) { prep_string(&w, p); } arg = (const char**)apr_array_push(args); *arg = ap_escape_shell_cmd(p, w); } ch += 2; continue; } if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '1')) { /* Todo: Make short name!!! */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -