// Service manager status reporting BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint) { static DWORD checkpoint = 1; BOOL result = TRUE; // If we're in the start state then we don't want the control manager // sending us control messages because they'll confuse us. if (state == SERVICE_START_PENDING) g_srvstatus.dwControlsAccepted = 0; else g_srvstatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN; // Save the new status we've been given g_srvstatus.dwCurrentState = state; g_srvstatus.dwWin32ExitCode = exitcode; g_srvstatus.dwWaitHint = waithint; // Update the checkpoint variable to let the SCM know that we // haven't died if requests take a long time if ((state == SERVICE_RUNNING) || (state == SERVICE_STOPPED)) g_srvstatus.dwCheckPoint = 0; else g_srvstatus.dwCheckPoint = checkpoint++; // Tell the SCM our new status if (!(result = SetServiceStatus(g_hstatus, &g_srvstatus))) LogErrorMsg("SetServiceStatus failed"); return result; }
bool CLoveTcp::ListenSocket() { if( listen( m_nSocket, 1024*1024 ) == -1 ) { LogErrorMsg("listen socket error"); return false; } return true; }
int CLoveTcp::setnonblocking( int fd ) { if( fcntl( fd, F_SETFL, fcntl( fd, F_GETFD, 0 )|O_NONBLOCK ) == -1 ) { LogErrorMsg("setnonblocking error"); return -1; } return 0; }
int CLoveTcp::Accept(sockaddr_in& addr) { int nConnect = -1; socklen_t nLen = sizeof(struct sockaddr); if ((nConnect = accept(m_nSocket,(struct sockaddr*)&addr, &nLen)) == -1) { LogErrorMsg("accept error"); } return nConnect; }
bool CLoveTcp::Connect(std::string& strIp,int nPort) { if (strIp.empty()) { LogErrorMsg("the IP is socket error"); return false; } struct sockaddr_in server_addr; memset(&server_addr,0,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=inet_addr(strIp.c_str()); server_addr.sin_port=htons(nPort); socklen_t nLen = 0; if (int nConnect = connect(m_nSocket,(struct sockaddr *)(&server_addr),nLen) == -1) { LogErrorMsg("connect server error serverIp=%s,port=%d",strIp.c_str(),nPort); return false; } return true; }
bool CLoveTcp::EpollMod(int nFd) { struct epoll_event ev; ev.data.fd = nFd; ev.events = EPOLLIN | EPOLLET; if( epoll_ctl( m_nEpoll, EPOLL_CTL_MOD, nFd, &ev ) < 0 ) { LogErrorMsg("epoll_del error"); return false; } return true; }
bool CLoveTcp::BindSocket(int nPort) { struct sockaddr_in server_addr; memset(&server_addr,0,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(nPort); if(bind(m_nSocket,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) { LogErrorMsg("bin socket error"); return false; } return true; }
bool CLoveTcp::CreateSocket() { if((m_nSocket = socket(AF_INET,SOCK_STREAM,0))==-1) { LogErrorMsg("create socket error"); return false; } if (setnonblocking(m_nSocket) == -1) { LogErrorMsg("setnonblocking error"); } int nSock = 0; if (setsockopt(m_nSocket,SOL_SOCKET,SO_REUSEADDR,&nSock,sizeof(nSock)) < 0) { /* code */ LogErrorMsg("setsockopt failed"); } m_nEpoll = epoll_create1(EPOLL_CLOEXEC); if (EpollAdd(m_nSocket) == false) { return false; }; return true; }
// SERVICE MAIN ROUTINE int vncService::WinVNCServiceMain() { typedef DWORD (WINAPI * RegisterServiceProc)(DWORD, DWORD); const ULONG RSP_SIMPLE_SERVICE = 0x00000001; const ULONG RSP_UNREGISTER_SERVICE = 0x00000000; g_servicemode = TRUE; // How to run as a service depends upon the OS being used switch (g_platform_id) { // Windows 95/98 case VER_PLATFORM_WIN32_WINDOWS: { // Obtain a handle to the kernel library HINSTANCE kerneldll = LoadLibrary("KERNEL32.DLL"); if (kerneldll == NULL) break; // And find the RegisterServiceProcess function RegisterServiceProc RegisterService; RegisterService = (RegisterServiceProc) GetProcAddress(kerneldll, "RegisterServiceProcess"); if (RegisterService == NULL) break; // Register this process with the OS as a service! RegisterService(NULL, RSP_SIMPLE_SERVICE); // Run the service itself WinVNCAppMain(); // Then remove the service from the system service table RegisterService(NULL, RSP_UNREGISTER_SERVICE); // Free the kernel library FreeLibrary(kerneldll); // *** If we don't kill the process directly here, then // for some reason, WinVNC crashes... // *** Is this now fixed (with the stdcall patch above)? //ExitProcess(0); } break; // Windows NT case VER_PLATFORM_WIN32_NT: { // Create a service entry table SERVICE_TABLE_ENTRY dispatchTable[] = { {VNCSERVICENAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL, NULL} }; // Call the service control dispatcher with our entry table if (!StartServiceCtrlDispatcher(dispatchTable)) LogErrorMsg("StartServiceCtrlDispatcher failed."); } break; }; return 0; }