HttpProxyServer.h
#ifndef HTTPPROXYSERVER
#define HTTPPROXYSERVER
#pragma once
#include
#include
#include
#include
#include
#include
#pragma comment(lib,"Ws2_32.lib")
#define defineServiceName TEXT("HTTPProxyService 0.0.1") //服务名
#define defineServiceDisplayName TEXT("HTTP Proxy Service") //服务显示名
#define defineServicePath TEXT("\\HTTPProxyService.exe") //当前文件名称
#define defineServiceDescription TEXT("HTTP Proxy Service 0.0.1(HTTP Proxy V1.0 By FX)") //服务描述
#define MAX_HOSTNAME 1024 //最大主机名称
#define DEFAULTPORT 80 //默认主机端口
#define LISTENPORT 8000 //代理服务器监听端口
#define DEFLISNUM 500 //linsten最大队列
#define HEADLEN 7 //http://头长度
#define TIMEOUT 10000 //recv延时时间
#define MAXSIZE 20480 //缓冲大小
#define GET_STYLE 1 //get请求类型
#define HEAD_STYLE 2 //head请求类型
#define POST_STYLE 3 //post请求类型
#define CONNECT_STYLE 4 //connect请求类型
char ErrorMsg[]="HTTP/1.1 403 Forbidden\r\n\r\n403 Forbidden
"; //SOCK错误消息
char ConnectionEstablished[]="HTTP/1.0 200 OK\r\n\r\n"; //HTTP成功
HANDLE g_hSerHandMutex; //服务分发起等待句柄
SERVICE_STATUS ServiceStatus; //服务的状态。注意 ServiceStatus 一个全局变量,所以你可以跨多个函数使用它。
SERVICE_STATUS_HANDLE hStatus; //服务状态
//服务函数
void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
//处理 SCM 控制请求。服务控制
VOID WINAPI ServiceHandler(DWORD fdwControl);
//启动自己的工作线程 HTTPProxyFun 0.0.1
DWORD WINAPI HTTPProxyFun(LPVOID lpParam);
//现在,准备工作已经就绪,你可以开始编码了。服务程序控制台程序的一个子集。因此,开始你可以定义一个 main 函数,它是程序的入口点。对于服务程序来说,main 的代码令人惊讶地简短,因为它只创建分派表并启动控制分派机。
int ModifyRequest(char *SenderBuf,char *ReceiveBuf,int DataLen,int MethodLength);
//检测查询请求类型长度
int CheckRequest(char *ReceiveBuf,int *MethodLength);
//获取主机名和端口
void GetHostNameAndPort(char *ReceiveBuf,int datalen,char *HostName,UINT *RemotePort);
//获取域名后面的部分
char *GetURLRootPoint(char * ReceiveBuf,int DataLen,int *HostNaneLen);
//主机名解析IP地址
char *DNS(char *HostName);
//连接远程主机
BOOL ConnectToRemoteHost(SOCKET *ServerSocket,char *HostName,const UINT RemotePort);
//发送请求
BOOL SendRequest(SOCKET* CSsocket, char *SenderBuf, char *ReceiveBuf, int DataLen);
//HTTP代理线程
DWORD WINAPI ZXHTTPProxyThread(SOCKET* CSsocket);
//信息传递线程
void TransferData(SOCKET* CSsocket);
//安装服务
void InstallCmdService(void);
//移除服务
void RemoveCmdService(void);
//使用信息
void usage(char *par);
#endif
httpProxyService.cpp
#include "HttpProxyServer.h"
int main(int argc,char *argv[])
{
HANDLE hThread=CreateThread(NULL,0,HTTPProxyFun,NULL,0,NULL);
assert(hThread);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
return 0;
SERVICE_TABLE_ENTRY ServiceTable[2]; //分派表
ServiceTable[0].lpServiceName = defineServiceName; //线程名字 lpServiceName: 指向表示服务名称字符串的指针;当定义了多个服务时,那么这个域必须指定
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;//线程入口地址lpServiceProc: 指向服务主函数的指针(服务入口点);
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL; //最后一个必须为NULL分派表的最后一项必须是服务名和服务主函数域的 NULL 指针,
//文本例子程序中只宿主一个服务,所以服务名的定义是可选的。
//printf("HTTP Proxy V1.0 By LZX.\r\nUsage: %s ProxyPort\r\n",argv[0]);
if(argc==2)
{
if(!_stricmp(argv[1],"-i"))
{
usage(argv[0]);
InstallCmdService();
}
else if(!stricmp(argv[1],"-u"))
{
usage(argv[0]);
RemoveCmdService();
}
else usage(argv[0]);
return 0;
}
else usage(argv[0]);
StartServiceCtrlDispatcher(ServiceTable);// 启动服务的控制分派机线程
/****************************************************************************
服务控制管理器(SCM:Services Control Manager)是一个管理系统所有服
务的进程。当 SCM 启动某个服务时,它等待某个进程的主线程来调用
StartServiceCtrlDispatcher 函数。将分派表传递给StartServiceCtrlDispatcher。
这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线
程运行分派表中每个服务的 ServiceMain 函数(本文例子中只有一个服务)分
派器还监视程序中所有服务的执行情况。然后分派器将控制请求从 SCM 传给服
务。
注意:如果 StartServiceCtrlDispatcher 函数30秒没有被调用,便会报错,
为了避免这种情况,我们必须在 ServiceMain 函数中(参见本文例子)或在非
主函数的单独线程中初始化服务分派表。分派表中所有的服务执行完之后(例如,
用户通过“服务”控制面板程序停止它们),或者发生错误时。
StartServiceCtrlDispatcher 调用返回。然后主进程终止。
****************************************************************************/
return 0;
}
/*******************************************************************************
该函数是服务的入口点。它运行在一个单独的线程当中,这个线程是由控制分派器创建的。
ServiceMain 应该尽可能早早为服务注册控制处理器。这要通过调用 RegisterServiceCtrlHadler
函数来实现。你要将两个参数传递给此函数:服务名和指向 ControlHandlerfunction 的指针。
它指示控制分派器调用 ControlHandler 函数处理 SCM 控制请求。注册完控制处理器之后,
获得状态句柄(hStatus)。通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务
的状态。
ServiceMain 函数中,你给结构的几个域赋值,它们在服务运行的整个过程中都保持不变,比如:
dwServiceType。
*******************************************************************************/
//服务函数
void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
//定义变量
DWORD status = 0;
DWORD specificError = 0xfffffff;
HANDLE hThread;
ServiceStatus.dwServiceType = SERVICE_WIN32; //dwServiceType:指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING; //dwCurrentState:指定服务的当前状态。因为服务的初始化在这里没有完成,所以这里的状态为 SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; //这个域通知 SCM 服务接受哪个域。本文例子是允许 STOP 和 SHUTDOWN 请求。SCM 控制请求。
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
//dwWin32ExitCode 和 dwServiceSpecificExitCode:这两个域在你终止服务并报告退出细节时很有用。初始化服务时并不退出,因此,它们的值为 0;
//dwCheckPoint 和 dwWaitHint:这两个域表示初始化某个服务进程时要30秒以上。本文例子服务的初始化过程很短,所以这两个域的值都为 0。
//调用RegisterServiceCtrlHandler()注册一个ServiceHandler函数用来处理程序对Service的控制要求
hStatus = RegisterServiceCtrlHandler(TEXT("ServiceName"),(LPHANDLER_FUNCTION)ServiceHandler);
if (hStatus==0) return;
// Handle error condition
status = GetLastError();
if (status!=NO_ERROR)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = status;
ServiceStatus.dwServiceSpecificExitCode = specificError;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// Initialization complete - report running status
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(hStatus, &ServiceStatus);//通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。
//启动自己的工作线程
WaitForSingleObject(g_hSerHandMutex,INFINITE);
//设置服务状态
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if(SetServiceStatus(hStatus,&ServiceStatus)==0)
{
OutputDebugString(TEXT("SetServiceStatus in CmdControl in Switch Error !\n"));
}
ReleaseMutex(g_hSerHandMutex);
CloseHandle(g_hSerHandMutex);
hThread=CreateThread(NULL,0,HTTPProxyFun,NULL,0,NULL);
assert(hThread);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
return;
}
//它指示控制分派器调用 ControlHandler 函数处理 SCM 控制请求。服务控制
void WINAPI ServiceHandler(DWORD fdwControl)
{
switch(fdwControl)
{
case SERVICE_CONTROL_PAUSE: //控制暂停
{
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
}
break;
case SERVICE_CONTROL_CONTINUE://控制继续
{
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
}
break;
case SERVICE_CONTROL_STOP: //控制停止
{
WaitForSingleObject(g_hSerHandMutex,INFINITE);
//设置服务状态
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if(SetServiceStatus(hStatus,&ServiceStatus)==0)
{
OutputDebugString(TEXT("SetServiceStatus in CmdControl in Switch Error !\n"));
}
ReleaseMutex(g_hSerHandMutex);
CloseHandle(g_hSerHandMutex);
}
//break; 此处没有break是否是作者故意为之?fx 2016年5月17日11:18:45
case SERVICE_CONTROL_SHUTDOWN: //控制关闭
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(hStatus,&ServiceStatus);
}
return ;
default:
break;
}
//设置状态
SetServiceStatus(hStatus,&ServiceStatus);
return ;
}
//启动自己的工作线程(HTTP Proxy V1.0 By LZX)
DWORD WINAPI HTTPProxyFun(LPVOID lpParam)
{
//设置变量
int LisPort=LISTENPORT;
//初始化网络库
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData)) return 1;
//创建socket
SOCKET ProxyServer= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ProxyServer == SOCKET_ERROR)return 1;
//绑定端口
struct sockaddr_in Server={0};
Server.sin_family = AF_INET;
Server.sin_port = htons(LisPort);
Server.sin_addr.S_un.S_addr = INADDR_ANY;
if(bind(ProxyServer, (LPSOCKADDR)&Server, sizeof(Server)) == SOCKET_ERROR) return 1;
//监听连接
if(listen(ProxyServer, DEFLISNUM) == SOCKET_ERROR)return 1;
//定义变量
SOCKET AcceptSocket = INVALID_SOCKET;
SOCKET *CSsocket;
while(true)
{
//接受客户端连接
AcceptSocket = accept(ProxyServer, NULL, NULL);
CSsocket = (SOCKET*)malloc(sizeof(SOCKET)*2);
if (CSsocket == NULL)continue;
//创建线程处理客户端连接请求
CSsocket[0] = AcceptSocket;
HANDLE hThread = CreateThread (NULL,0, (LPTHREAD_START_ROUTINE)ZXHTTPProxyThread,CSsocket,0,NULL);
if (hThread == NULL) Sleep(1000);
else CloseHandle(hThread);
}
return true;
}
//主机名解析IP地址
char *DNS(char *HostName)
{
//参数效验
assert(HostName);
if (HostName==NULL)return NULL;
//获取主机地址
HOSTENT *hostent = NULL;
IN_ADDR iaddr;
hostent = gethostbyname(HostName);
if (hostent == NULL)
{
return NULL;
}
iaddr = *((LPIN_ADDR)*hostent->h_addr_list);
return inet_ntoa(iaddr);
}
//连接远程主机
BOOL ConnectToRemoteHost(SOCKET *ServerSocket,char *HostName,const UINT RemotePort)
{
//参数效验
assert(*ServerSocket!=SOCKET_ERROR);
assert(HostName!=NULL);
assert(RemotePort>0);
if (*ServerSocket==SOCKET_ERROR)return false;
if (*HostName==NULL)return false;
if (RemotePort<0)return false;
//地址信息
sockaddr_in Server={0};
Server.sin_family = AF_INET;
Server.sin_port = htons(RemotePort);
if (inet_addr(HostName) != INADDR_NONE)
{
Server.sin_addr.s_addr = inet_addr(HostName);
}
else
{
//解析主机地址
if (DNS(HostName) != NULL)
{
Server.sin_addr.s_addr = inet_addr(DNS(HostName));
}
else
{
assert(FALSE);
return FALSE;
}
}
//创建socket
*ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (*ServerSocket == INVALID_SOCKET) return FALSE;
//设置socket接收的超时时间为10秒
UINT TimeOut = TIMEOUT;
setsockopt(*ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut));
// 连接远程主机
if (connect(*ServerSocket, (const SOCKADDR *)&Server,sizeof(Server)) == SOCKET_ERROR)
{
closesocket(*ServerSocket);
return FALSE;
}
return TRUE;
}
//获取主机名和端口
void GetHostNameAndPort(char *ReceiveBuf,int datalen,char *HostName,UINT *RemotePort)
{
//参数效验
assert(datalen>0);
assert(RemotePort!=NULL);
assert(HostName!=NULL);
if (datalen<0)return;
if (RemotePort==NULL)return;
if (HostName==NULL)return;
//解析主机端口
char *fp = ReceiveBuf;
for(int i = 0;i < datalen && *fp != ':' && *fp != '\0' && *fp != '\r' && *fp != '/';i++)
{
//解析主机
HostName[i]=*fp++;
//解析端口
if(*fp == ':') *RemotePort=atoi(fp+1);
else *RemotePort=DEFAULTPORT;
}
}
//获取域名后面的部分
char * GetURLRootPoint(char * ReceiveBuf,int DataLen,int *HostNaneLen)
{
//参数效验
assert(DataLen>0);
assert(ReceiveBuf!=NULL);
assert(HostNaneLen!=NULL);
if (DataLen<0)return NULL;
if (ReceiveBuf==NULL)return NULL;
if (HostNaneLen==NULL)return NULL;
//解析操作
for(int i = 0;i < DataLen; i++)
{
if(ReceiveBuf[i] == '/')
{
*HostNaneLen = i;
return &ReceiveBuf[i];
}
}
return NULL;
}
//检测查询请求类型长度
int CheckRequest(char *ReceiveBuf,int *MethodLength)
{
//参数效验
assert(ReceiveBuf!=NULL);
assert(MethodLength!=NULL);
if (ReceiveBuf==NULL)return NULL;
if (MethodLength==NULL)return NULL;
if(!strnicmp(ReceiveBuf,"GET ",4))
{
*MethodLength = 4;
return GET_STYLE;
}
else if(!strnicmp(ReceiveBuf,"HEAD ",5)) //Looks like the same with GET
{
*MethodLength = 5;
return HEAD_STYLE;
}
else if(!strnicmp(ReceiveBuf,"POST ",5))
{
*MethodLength = 5;
return POST_STYLE;
}
else if(!strnicmp(ReceiveBuf,"CONNECT ",8))
{
*MethodLength = 8;
return CONNECT_STYLE;
}
else
{
return 0;
}
}
//修改请求信息
int ModifyRequest(char *SenderBuf,char *ReceiveBuf,int DataLen,int MethodLength)
{
//参数效验
assert(SenderBuf!=NULL);
assert(ReceiveBuf!=NULL);
assert(DataLen>0);
assert(MethodLength>0);
if (SenderBuf==NULL)return NULL;
if (ReceiveBuf==NULL)return NULL;
if (DataLen<0)return NULL;
if (MethodLength<0)return NULL;
//设置变量
strncpy(SenderBuf,ReceiveBuf,MethodLength);
int HedLen = 0;
//http头判断
if(strncmp(ReceiveBuf+MethodLength,"http://",HEADLEN)) return 0;
//获取域名后面的部分
char * Getrootfp = GetURLRootPoint(ReceiveBuf+MethodLength+HEADLEN,DataLen
-MethodLength-HEADLEN,&HedLen);
if(Getrootfp == NULL)
return 0;
memcpy(SenderBuf+MethodLength,Getrootfp,DataLen-MethodLength-HEADLEN-HedLen);
//返回长度
return DataLen-HEADLEN-HedLen;
}
//信息传递线程
void TransferData(SOCKET* CSsocket)
{
//参数效验
assert(CSsocket!=NULL);
if (CSsocket==NULL)return;
//定义变量
SOCKET ClientSocket = CSsocket[0];
SOCKET ServerSocket = CSsocket[1];
timeval timeset={0}; //超时时间
fd_set readfd,writefd;
int result,i=0;
char read_in1[MAXSIZE]={0};
char send_out1[MAXSIZE]={0};
char read_in2[MAXSIZE]={0};
char send_out2[MAXSIZE]={0}; //ServerSocket套接字接受数据
char SenderBuf[MAXSIZE]={0};
int read1=0;
int totalread1=0; //ClientSocket套接字接受长度
int send1=0;
int read2=0;
int totalread2=0; //ServerSocket套接字接受长度
int send2=0;
int sendcount1=0;
int sendcount2=0;
int maxfd=0; //最大套接字范围
maxfd=max(ClientSocket,ServerSocket)+1;
memset(read_in1,0,MAXSIZE);
memset(read_in2,0,MAXSIZE);
memset(send_out1,0,MAXSIZE);
memset(send_out2,0,MAXSIZE);
timeset.tv_sec=TIMEOUT;
timeset.tv_usec=0;
while(true)
{
//初始化为空集合
FD_ZERO(&readfd);
FD_ZERO(&writefd);
//添加套接字到集合
FD_SET((UINT)ClientSocket, &readfd);
FD_SET((UINT)ClientSocket, &writefd);
FD_SET((UINT)ServerSocket, &writefd);
FD_SET((UINT)ServerSocket, &readfd);
//查询事件
result=select(maxfd,&readfd,&writefd,NULL,×et);
if((result<0) && (errno!=EINTR)) break;
else if(result==0) break;
//3.接受远程服务端数据
if(FD_ISSET(ServerSocket, &readfd)) //检查s是不是set的成员,如果是返回TRTUE
{
//fx 2016年5月17日16:18:03
//由于已近连接了远程服务器,所有会先收到服务器的数据
//最大长度判断
if(totalread20) //接受长度
{
send2=send(ClientSocket, send_out2+sendcount2, totalread2, 0);
if(send2==0)break;
if((send2<0) && (errno!=EINTR))
{
err2=1;
break;
}
if((send2<0) && (errno==ENOSPC)) break;
sendcount2+=send2;
totalread2-=send2;
}
if(err2==1) break;
if((totalread2>0) && (sendcount2 > 0))
{
/* move not sended data to start addr */
memcpy(send_out2, send_out2+sendcount2, totalread2);
memset(send_out2+totalread2, 0, MAXSIZE-totalread2);
}
else memset(send_out2,0,MAXSIZE);
}
//1.接受客户端请求
if(FD_ISSET(ClientSocket, &readfd)) //检查s是不是set的成员,如果是返回TRTUE
{
if(totalread10)
{
send1=send(ServerSocket, send_out1+sendcount1, totalread1, 0);
if(send1==0)break;
if((send1<0) && (errno!=EINTR))
{
err=1;
break;
}
if((send1<0) && (errno==ENOSPC)) break;
sendcount1+=send1;
totalread1-=send1;
}
if(err==1) break;
if((totalread1>0) && (sendcount1>0))
{
memcpy(send_out1,send_out1+sendcount1,totalread1);
memset(send_out1+totalread1,0,MAXSIZE-totalread1);
}
else
memset(send_out1,0,MAXSIZE);
}
Sleep(5);
}
closesocket(ClientSocket);
closesocket(ServerSocket);
return;
}
//发送请求
BOOL SendRequest(SOCKET* CSsocket, char *SenderBuf, char *ReceiveBuf, int DataLen)
{
//参数效验
assert(CSsocket!=NULL);
assert(SenderBuf!=NULL);
assert(ReceiveBuf!=NULL);
assert(DataLen>0);
if (CSsocket==NULL)return false;
if (SenderBuf==NULL)return false;
if (ReceiveBuf==NULL)return false;
if (DataLen<0)return false;
//CSsocket[0] ClientSocket
//CSsocket[1] ServerSocket
DWORD dwThreadID;
char HostName[MAX_HOSTNAME] = {0};
UINT RemotePort = 0;
int Flag=0, MethodLength=0, SendLength=0;
//检测查询请求类型是否合法
Flag = CheckRequest(ReceiveBuf,&MethodLength);
if(Flag==0) return 0;
if(Flag==GET_STYLE || Flag==HEAD_STYLE || Flag==POST_STYLE)
{
SendLength=ModifyRequest(SenderBuf,ReceiveBuf,DataLen,MethodLength);
if(SendLength==NULL)return 0;
//获取主机名和端口
GetHostNameAndPort(ReceiveBuf+MethodLength+HEADLEN,DataLen-MethodLength-HEADLEN,HostName,&RemotePort);
//连接远程主机
if(ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort)==FALSE)return 0;
//发送数据
if(send(CSsocket[1],SenderBuf,SendLength,0) == SOCKET_ERROR) return 0;
}
else if(Flag==CONNECT_STYLE)
{
//获取主机名和端口
GetHostNameAndPort(ReceiveBuf+MethodLength,DataLen-MethodLength,HostName,&RemotePort);
//连接远程主机
if(ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort)==FALSE) return 0;
//发送数据
send(CSsocket[0], ConnectionEstablished, strlen(ConnectionEstablished),0);
}
if(CSsocket[0] && CSsocket[1])
{
//开启线程
HANDLE ThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferData,(LPVOID)CSsocket,0,&dwThreadID);
if (ThreadHandle != NULL)WaitForSingleObject(ThreadHandle, INFINITE);
CloseHandle(ThreadHandle);
}
else return FALSE;
return TRUE;
}
//HTTP代理线程
DWORD WINAPI ZXHTTPProxyThread(SOCKET* CSsocket)
{
//参数效验
assert(CSsocket!=NULL);
if(CSsocket==NULL) return NULL;
//分配内存
char *ReceiveBuf = (char*)malloc(sizeof(char)*MAXSIZE);
char *SenderBuf = (char*)malloc(sizeof(char)*MAXSIZE);
memset(ReceiveBuf,0,MAXSIZE);
memset( SenderBuf,0,MAXSIZE);
//接受数据
int DataLen = 0;
DataLen = recv(CSsocket[0],ReceiveBuf,MAXSIZE,0);
if(DataLen == SOCKET_ERROR || DataLen == 0)
{
closesocket(CSsocket[0]);
closesocket(CSsocket[1]);
free(CSsocket);
free(ReceiveBuf);
free(SenderBuf);
return 0;
}
//发送请求
if(SendRequest(CSsocket, SenderBuf, ReceiveBuf, DataLen)==FALSE)
send(CSsocket[0],ErrorMsg,strlen(ErrorMsg),0);
closesocket(CSsocket[0]);
closesocket(CSsocket[1]);
free(CSsocket);
free(ReceiveBuf);
free(SenderBuf);
return 0;
}
//安装服务
void InstallCmdService(void)
{
//变量定义
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR lpCurrentPath[MAX_PATH];
TCHAR lpImagePath[MAX_PATH];
TCHAR *lpHostName;
WIN32_FIND_DATA FileData;
HANDLE hSearch;
DWORD dwErrorCode;
SERVICE_STATUS InstallServiceStatus;
//构造文件路径
GetSystemDirectory(lpImagePath,MAX_PATH);
_tcscat(lpImagePath,defineServicePath);
lpHostName=NULL;
//拷贝文件
hSearch=FindFirstFile(lpImagePath,&FileData);
if(hSearch==INVALID_HANDLE_VALUE)
{
//文件不存在就复制到系统目录
GetModuleFileName(NULL,lpCurrentPath,MAX_PATH);
if(CopyFile(lpCurrentPath,lpImagePath,FALSE)==0)
{
dwErrorCode=GetLastError();
if(dwErrorCode==5)
{
printf("Failure ... Access is Denied !\n");
}
else
{
printf("Failure !\n");
}
return ;
}
else
{
printf("复制文件到系统目录成功\n");
}
}
else
{
printf("系统目录文件以及存在!\n");
FindClose(hSearch);
}
//打开服务器管理器
schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS);
if(schSCManager==NULL)
{
printf("Open Service Control Manager Database Failure !\n");
return ;
}
//创建服务
schService=CreateService(schSCManager,defineServiceName,defineServiceDisplayName,SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
SERVICE_ERROR_IGNORE,lpImagePath,NULL,NULL,NULL,NULL,NULL);
if(schService==NULL)
{
dwErrorCode=GetLastError();
if(dwErrorCode!=ERROR_SERVICE_EXISTS)
{
//创建服务失败
printf("创建服务失败\n");
CloseServiceHandle(schSCManager);
return ;
}
else
{
//服务已近存在,直接打开
printf("already Exists !\n");
schService=OpenService(schSCManager,defineServiceDisplayName,SERVICE_START);
if(schService==NULL)
{
printf("服务打开失败\n");
CloseServiceHandle(schSCManager);
return ;
}
}
}
else
{
printf("创建服务成功\n");
}
//更改服务配置参数
BOOL bSuccess;
SERVICE_DESCRIPTION ServiceDescription;
ServiceDescription.lpDescription=defineServiceDescription;
bSuccess=ChangeServiceConfig2(schService,SERVICE_CONFIG_DESCRIPTION,&ServiceDescription);
//启动服务
if(StartService(schService,0,NULL)==0)
{
dwErrorCode=GetLastError();
if(dwErrorCode==ERROR_SERVICE_ALREADY_RUNNING)
{
printf("already Running !\n");
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return ;
}
}
else
{
//服务运行中
printf("服务运行中1\n");
}
//查询服务状态
while(QueryServiceStatus(schService,&InstallServiceStatus)!=0)
{
if(InstallServiceStatus.dwCurrentState==SERVICE_START_PENDING)
Sleep(100);
else
break;
}
if(InstallServiceStatus.dwCurrentState!=SERVICE_RUNNING)
{
printf("服务运行失败 !\n"); //服务失败
}
else
{
printf("服务运行中 2!\n"); //服务运行中
}
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return ;
}
//移除服务
void RemoveCmdService(void)
{
//变量定义
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR lpImagePath[MAX_PATH];
TCHAR *lpHostName;
WIN32_FIND_DATA FileData;
SERVICE_STATUS RemoveServiceStatus;
HANDLE hSearch;
DWORD dwErrorCode;
//打开服务器管理器
GetSystemDirectory(lpImagePath,MAX_PATH);
_tcscat(lpImagePath,defineServicePath);
lpHostName=NULL;
schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS);
if(schSCManager==NULL)
{
printf("Opening SCM ......... ");
dwErrorCode=GetLastError();
if(dwErrorCode!=5)
{
printf("Failure !\n");
}
else
{
printf("Failure ... Access is Denied !\n");
}
return ;
}
//打开服务
schService=OpenService(schSCManager,defineServiceName,SERVICE_ALL_ACCESS);
if(schService==NULL)
{
printf("Opening Service ..... ");
dwErrorCode=GetLastError();
if(dwErrorCode==1060)
{
printf("no Exists !\n");
}
else
{
printf("Failure !\n");
}
CloseServiceHandle(schSCManager);
}
else
{
//查询服务状态
if(QueryServiceStatus(schService,&RemoveServiceStatus)!=0)
{
if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED)
{
printf("already Stopped !\n"); //服务以及停止
}
else
{
//停止服务
if(ControlService(schService,SERVICE_CONTROL_STOP,&RemoveServiceStatus)!=0)
{
while(RemoveServiceStatus.dwCurrentState==SERVICE_STOP_PENDING)
{
Sleep(10);
QueryServiceStatus(schService,&RemoveServiceStatus);
}
if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED)
{
printf("Success !\n"); //服务停止成功
}
else
{
printf("Failure !\n"); //服务停止失败
}
}
else
{
printf("Failure !\n");
}
}
}
else
{
printf("Query Failure !\n");
}
printf("Removing Service .... ");
//删除服务
if(DeleteService(schService)==0)
{
printf("Failure !\n");
}
else
{
printf("Success !\n");
}
}
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
//删除文件
printf("Removing File ....... ");
Sleep(1500);
hSearch=FindFirstFile(lpImagePath,&FileData);
if(hSearch==INVALID_HANDLE_VALUE)
{
printf("no Exists !\n");
}
else
{
if(DeleteFile(lpImagePath)==0)
{
printf("Failure !\n");
}
else
{
printf("Success !\n");
}
FindClose(hSearch);
}
return ;
}
void usage(char *par)
{
printf("\t\tHTTP Proxy Service 0.0.1\n");
printf("\t\tUsage: %s -i (to install service)\n",par);
printf("\t\t %s -u (to remove service)\n",par);
printf("\n");
return ;
}