标签:
HttpProxyServer.h
#ifndef HTTPPROXYSERVER #define HTTPPROXYSERVER #pragma once #include <windows.h> #include <stdio.h> #include <wininet.h> #include <errno.h> #include <tchar.h> #include <assert.h> #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\n<body><h1>403 Forbidden</h1></body>"; //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(totalread2<MAXSIZE) { read2=recv(ServerSocket,read_in2,MAXSIZE-totalread2, 0); if(read2==0)break; if((read2<0) && (errno!=EINTR)) break; memcpy(send_out2+totalread2,read_in2,read2); totalread2+=read2; memset(read_in2,0,MAXSIZE); } } //4.转发数据到客户端 if(FD_ISSET(ClientSocket, &writefd)) //检查s是不是set的成员,如果是返回TRTUE { int err2=0; sendcount2=0; while(totalread2>0) //接受长度 { 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(totalread1<MAXSIZE) { read1=recv(ClientSocket, read_in1, MAXSIZE-totalread1, 0); if((read1==SOCKET_ERROR) || (read1==0)) break; memcpy(send_out1+totalread1,read_in1,read1); totalread1+=read1; memset(read_in1,0,MAXSIZE); } //发送请求 if(SendRequest(CSsocket,SenderBuf,send_out1,totalread1)) totalread1=0; } //2.收到客户端请求转发到服务器 if(FD_ISSET(ServerSocket, &writefd)) { int err=0; sendcount1=0; while(totalread1>0) { 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 ; }
标签:
原文地址:http://blog.csdn.net/qq125096885/article/details/51437077