📄 ntpipe.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/** NT Pipes network wrapper
*
* @author Mladen Turk
* @version $Revision: 466609 $, $Date: 2006-10-22 01:30:39 +0200 (dim., 22 oct. 2006) $
*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#define STRICT
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <sddl.h>
#include "tcn.h"
#include "apr_thread_mutex.h"
#include "apr_poll.h"
#ifdef TCN_DO_STATISTICS
#include "apr_atomic.h"
static volatile apr_uint32_t ntp_created = 0;
static volatile apr_uint32_t ntp_closed = 0;
static volatile apr_uint32_t ntp_cleared = 0;
static volatile apr_uint32_t ntp_accepted = 0;
void ntp_network_dump_statistics()
{
fprintf(stderr, "NT Network Statistics ..\n");
fprintf(stderr, "Sockets created : %d\n", ntp_created);
fprintf(stderr, "Sockets accepted : %d\n", ntp_accepted);
fprintf(stderr, "Sockets closed : %d\n", ntp_closed);
fprintf(stderr, "Sockets cleared : %d\n", ntp_cleared);
}
#endif
#define DEFNAME "\\\\.\\PIPE\\TOMCATNATIVEPIPE"
#define DEFNAME_FMT "\\\\.\\PIPE\\TOMCATNATIVEPIPE%08X%08X"
#define DEFSIZE 8192
#define DEFTIMEOUT 60000
#define TCN_NTP_UNKNOWN 0
#define TCN_NTP_CLIENT 1
#define TCN_NTP_SERVER 2
typedef struct {
apr_pool_t *pool;
apr_socket_t *sock; /* Dummy socket */
OVERLAPPED rd_o;
OVERLAPPED wr_o;
HANDLE h_pipe;
HANDLE rd_event;
HANDLE wr_event;
DWORD timeout;
int mode; /* Client or server mode */
int nmax;
DWORD sndbuf;
DWORD rcvbuf;
char name[MAX_PATH+1];
SECURITY_ATTRIBUTES sa;
} tcn_ntp_conn_t;
static const char *NTSD_STRING = "D:" /* Discretionary ACL */
"(D;OICI;GA;;;BG)" /* Deny access to Built-in Guests */
"(D;OICI;GA;;;AN)" /* Deny access to Anonymous Logon */
"(A;OICI;GRGWGX;;;AU)" /* Allow read/write/execute to Authenticated Users */
"(A;OICI;GA;;;BA)" /* Allow full control to Administrators */
"(A;OICI;GA;;;LS)" /* Allow full control to Local service account */
"(A;OICI;GA;;;SY)"; /* Allow full control to Local system */
static apr_status_t APR_THREAD_FUNC
ntp_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
if (t < 0)
con->timeout = INFINITE;
else
con->timeout = (DWORD)(apr_time_as_msec(t));
return APR_SUCCESS;
}
static apr_status_t APR_THREAD_FUNC
ntp_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t*)sock;
if (con->timeout == INFINITE)
*t = -1;
else
*t = con->timeout * 1000;
return APR_SUCCESS;
}
static APR_INLINE apr_status_t APR_THREAD_FUNC
ntp_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
apr_status_t rv = APR_SUCCESS;
switch (opt) {
case APR_SO_SNDBUF:
con->sndbuf = (DWORD)on;
break;
case APR_SO_RCVBUF:
con->rcvbuf = (DWORD)on;
break;
default:
rv = APR_EINVAL;
break;
}
return rv;
}
static APR_INLINE apr_status_t APR_THREAD_FUNC
ntp_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
apr_status_t rv = APR_SUCCESS;
switch (opt) {
case APR_SO_SNDBUF:
*on = con->sndbuf;
break;
case APR_SO_RCVBUF:
*on = con->rcvbuf;
break;
default:
rv = APR_EINVAL;
break;
}
return rv;
}
static apr_status_t ntp_cleanup(void *data)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)data;
if (con) {
if (con->h_pipe) {
FlushFileBuffers(con->h_pipe);
CloseHandle(con->h_pipe);
con->h_pipe = NULL;
}
if (con->rd_event) {
CloseHandle(con->rd_event);
con->rd_event = NULL;
}
if (con->wr_event) {
CloseHandle(con->wr_event);
con->wr_event= NULL;
}
}
#ifdef TCN_DO_STATISTICS
apr_atomic_inc32(&ntp_cleared);
#endif
return APR_SUCCESS;
}
static apr_status_t APR_THREAD_FUNC
ntp_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
{
UNREFERENCED(how);
return ntp_cleanup(sock);;
}
static apr_status_t APR_THREAD_FUNC
ntp_socket_close(apr_socket_t *sock)
{
#ifdef TCN_DO_STATISTICS
apr_atomic_inc32(&ntp_closed);
#endif
return ntp_cleanup(sock);;
}
static apr_status_t APR_THREAD_FUNC
ntp_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
DWORD readed;
if (!ReadFile(con->h_pipe, buf, *len, &readed, &con->rd_o)) {
DWORD err = GetLastError();
if (err == ERROR_IO_PENDING) {
DWORD r = WaitForSingleObject(con->rd_event, con->timeout);
if (r == WAIT_TIMEOUT)
return APR_TIMEUP;
else if (r != WAIT_OBJECT_0)
return APR_EOF;
}
else if (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA) {
/* Server closed the pipe */
return APR_EOF;
}
GetOverlappedResult(con->h_pipe, &con->rd_o, &readed, FALSE);
}
*len = readed;
return APR_SUCCESS;
}
static apr_status_t APR_THREAD_FUNC
ntp_socket_send(apr_socket_t *sock, const char *buf,
apr_size_t *len)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
DWORD written;
if (!WriteFile(con->h_pipe, buf, *len, &written, &con->wr_o)) {
DWORD err = GetLastError();
if (err == ERROR_IO_PENDING) {
DWORD r = WaitForSingleObject(con->wr_event, con->timeout);
if (r == WAIT_TIMEOUT)
return APR_TIMEUP;
else if (r != WAIT_OBJECT_0)
return APR_EOF;
}
else if (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA) {
/* Server closed the pipe */
return APR_EOF;
}
GetOverlappedResult(con->h_pipe, &con->wr_o, &written, FALSE);
}
*len = written;
return APR_SUCCESS;
}
static apr_status_t APR_THREAD_FUNC
ntp_socket_sendv(apr_socket_t *sock,
const struct iovec *vec,
apr_int32_t nvec, apr_size_t *len)
{
tcn_ntp_conn_t *con = (tcn_ntp_conn_t *)sock;
apr_status_t rv;
apr_size_t written = 0;
apr_int32_t i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -