📄 proc.c
字号:
/* Copyright 2000-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. */#include "win32/apr_arch_threadproc.h"#include "win32/apr_arch_file_io.h"#include "apr_thread_proc.h"#include "apr_file_io.h"#include "apr_general.h"#include "apr_strings.h"#include "apr_portable.h"#include "apr_lib.h"#include <stdlib.h>#if APR_HAVE_SIGNAL_H#include <signal.h>#endif#include <string.h>#if APR_HAVE_PROCESS_H#include <process.h>#endif#ifdef _WIN32_WCE#ifndef DETACHED_PROCESS#define DETACHED_PROCESS 0#endif#ifndef CREATE_UNICODE_ENVIRONMENT#define CREATE_UNICODE_ENVIRONMENT 0#endif#ifndef STARTF_USESHOWWINDOW#define STARTF_USESHOWWINDOW 0#endif#ifndef SW_HIDE#define SW_HIDE 0#endif#endif/* * some of the ideas expressed herein are based off of Microsoft * Knowledge Base article: Q190351 * */APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new, apr_pool_t *pool){ (*new) = (apr_procattr_t *)apr_pcalloc(pool, sizeof(apr_procattr_t)); (*new)->pool = pool; (*new)->cmdtype = APR_PROGRAM; return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t in, apr_int32_t out, apr_int32_t err){ apr_status_t stat = APR_SUCCESS; if (in) { /* APR_CHILD_BLOCK maps to APR_WRITE_BLOCK, while * APR_PARENT_BLOCK maps to APR_READ_BLOCK, so we * must transpose the CHILD/PARENT blocking flags * only for the stdin pipe. stdout/stderr naturally * map to the correct mode. */ if (in == APR_CHILD_BLOCK) in = APR_READ_BLOCK; else if (in == APR_PARENT_BLOCK) in = APR_WRITE_BLOCK; stat = apr_create_nt_pipe(&attr->child_in, &attr->parent_in, in, attr->pool); if (stat == APR_SUCCESS) stat = apr_file_inherit_unset(attr->parent_in); } if (out && stat == APR_SUCCESS) { stat = apr_create_nt_pipe(&attr->parent_out, &attr->child_out, out, attr->pool); if (stat == APR_SUCCESS) stat = apr_file_inherit_unset(attr->parent_out); } if (err && stat == APR_SUCCESS) { stat = apr_create_nt_pipe(&attr->parent_err, &attr->child_err, err, attr->pool); if (stat == APR_SUCCESS) stat = apr_file_inherit_unset(attr->parent_err); } return stat;}APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in, apr_file_t *parent_in){ apr_status_t rv = APR_SUCCESS; if (child_in) { if (attr->child_in == NULL) rv = apr_file_dup(&attr->child_in, child_in, attr->pool); else rv = apr_file_dup2(attr->child_in, child_in, attr->pool); if (rv == APR_SUCCESS) rv = apr_file_inherit_set(attr->child_in); } if (parent_in && rv == APR_SUCCESS) { if (attr->parent_in == NULL) rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool); else rv = apr_file_dup2(attr->parent_in, parent_in, attr->pool); } return rv;}APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out, apr_file_t *parent_out){ apr_status_t rv = APR_SUCCESS; if (child_out) { if (attr->child_out == NULL) rv = apr_file_dup(&attr->child_out, child_out, attr->pool); else rv = apr_file_dup2(attr->child_out, child_out, attr->pool); if (rv == APR_SUCCESS) rv = apr_file_inherit_set(attr->child_out); } if (parent_out && rv == APR_SUCCESS) { if (attr->parent_out == NULL) rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool); else rv = apr_file_dup2(attr->parent_out, parent_out, attr->pool); } return rv;}APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err, apr_file_t *parent_err){ apr_status_t rv = APR_SUCCESS; if (child_err) { if (attr->child_err == NULL) rv = apr_file_dup(&attr->child_err, child_err, attr->pool); else rv = apr_file_dup2(attr->child_err, child_err, attr->pool); if (rv == APR_SUCCESS) rv = apr_file_inherit_set(attr->child_err); } if (parent_err && rv == APR_SUCCESS) { if (attr->parent_err == NULL) rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool); else rv = apr_file_dup2(attr->parent_err, parent_err, attr->pool); } return rv;}APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr, const char *dir) { /* curr dir must be in native format, there are all sorts of bugs in * the NT library loading code that flunk the '/' parsing test. */ return apr_filepath_merge(&attr->currdir, NULL, dir, APR_FILEPATH_NATIVE, attr->pool);}APR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr, apr_cmdtype_e cmd) { attr->cmdtype = cmd; return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr, apr_int32_t det) { attr->detached = det; return APR_SUCCESS;}static apr_status_t attr_cleanup(void *theattr){ apr_procattr_t *attr = (apr_procattr_t *)theattr; if (attr->user_token) CloseHandle(attr->user_token); attr->user_token = NULL; return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr, const char *username, const char *password){#ifdef _WIN32_WCE return APR_ENOTIMPL;#else HANDLE user; apr_wchar_t *wusername = NULL; apr_wchar_t *wpassword = NULL; apr_status_t rv; apr_size_t len, wlen; if (apr_os_level >= APR_WIN_NT_4) { if (attr->user_token) { /* Cannot set that twice */ if (attr->errfn) { attr->errfn(attr->pool, 0, apr_pstrcat(attr->pool, "function called twice" " on username: ", username, NULL)); } return APR_EINVAL; } len = strlen(username) + 1; wlen = len; wusername = apr_palloc(attr->pool, wlen * sizeof(apr_wchar_t)); if ((rv = apr_conv_utf8_to_ucs2(username, &len, wusername, &wlen)) != APR_SUCCESS) { if (attr->errfn) { attr->errfn(attr->pool, rv, apr_pstrcat(attr->pool, "utf8 to ucs2 conversion failed" " on username: ", username, NULL)); } return rv; } if (password) { len = strlen(password) + 1; wlen = len; wpassword = apr_palloc(attr->pool, wlen * sizeof(apr_wchar_t)); if ((rv = apr_conv_utf8_to_ucs2(password, &len, wpassword, &wlen)) != APR_SUCCESS) { if (attr->errfn) { attr->errfn(attr->pool, rv, apr_pstrcat(attr->pool, "utf8 to ucs2 conversion failed" " on password: ", password, NULL)); } return rv; } } if (!LogonUserW(wusername, NULL, wpassword ? wpassword : L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &user)) { /* Logon Failed */ return apr_get_os_error(); } if (wpassword) memset(wpassword, 0, wlen * sizeof(apr_wchar_t)); /* Get the primary token for user */ if (!DuplicateTokenEx(user, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, NULL, SecurityImpersonation, TokenPrimary, &(attr->user_token))) { /* Failed to duplicate the user token */ rv = apr_get_os_error(); CloseHandle(user); return rv; } CloseHandle(user); attr->sd = apr_pcalloc(attr->pool, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(attr->sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(attr->sd, -1, 0, 0); attr->sa = apr_palloc(attr->pool, sizeof(SECURITY_ATTRIBUTES)); attr->sa->nLength = sizeof (SECURITY_ATTRIBUTES); attr->sa->lpSecurityDescriptor = attr->sd; attr->sa->bInheritHandle = TRUE; /* register the cleanup */ apr_pool_cleanup_register(attr->pool, (void *)attr,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -