feat: Рабочая версия сервиса
parent
53cc2a08ce
commit
72bf8d917a
@ -0,0 +1,135 @@
|
||||
#include "client.h"
|
||||
#include "server.h"
|
||||
|
||||
#define DEFAULT_BUFLEN 512
|
||||
|
||||
SOCKET ConnectSocket = INVALID_SOCKET;
|
||||
|
||||
DWORD WINAPI ClientWriteToPipe(LPDWORD dummy);
|
||||
DWORD WINAPI ClientReadFromPipe(LPDWORD dummy);
|
||||
|
||||
VOID StartShellClient(TCHAR *ServerIP) {
|
||||
WSADATA wsaData;
|
||||
int iResult;
|
||||
struct addrinfo* result = NULL, *ptr = NULL, hints;
|
||||
|
||||
// Initialize Winsock
|
||||
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (iResult != 0) {
|
||||
printf("WSAStartup failed: %d\n", iResult);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create socket for client
|
||||
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
// Resolve the server address and port
|
||||
iResult = getaddrinfo(ServerIP, DEFAULT_PORT, &hints, &result);
|
||||
if (iResult != 0) {
|
||||
printf("getaddrinfo failed: %d\n", iResult);
|
||||
WSACleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Attempt to connect to the first address returned by the call to getaddrinfo
|
||||
ptr = result;
|
||||
|
||||
// Create a SOCKET for connecting to server
|
||||
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
|
||||
ptr->ai_protocol);
|
||||
|
||||
if (ConnectSocket == INVALID_SOCKET) {
|
||||
printf("Error at socket(): %ld\n", WSAGetLastError());
|
||||
freeaddrinfo(result);
|
||||
WSACleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Connect to a socket
|
||||
//
|
||||
// Connect to server.
|
||||
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
|
||||
if (iResult == SOCKET_ERROR) {
|
||||
closesocket(ConnectSocket);
|
||||
ConnectSocket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
if (ConnectSocket == INVALID_SOCKET) {
|
||||
printf("Unable to connect to server!\n");
|
||||
WSACleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
HANDLE threads[2];
|
||||
threads[0] = CreateThread(NULL, 0, ClientWriteToPipe, NULL, 0, NULL);
|
||||
threads[1] = CreateThread(NULL, 0, ClientReadFromPipe, NULL, 0, NULL);
|
||||
|
||||
WaitForMultipleObjects(2, threads, TRUE, INFINITE);
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
CloseHandle(threads[i]);
|
||||
|
||||
// Finalize
|
||||
// shutdown the send half of the connection since no more data will be sent
|
||||
iResult = shutdown(ConnectSocket, SD_SEND);
|
||||
if (iResult == SOCKET_ERROR) {
|
||||
printf("shutdown failed: %d\n", WSAGetLastError());
|
||||
closesocket(ConnectSocket);
|
||||
WSACleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// cleanup
|
||||
closesocket(ConnectSocket);
|
||||
WSACleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI ClientWriteToPipe(LPDWORD dummy) {
|
||||
UNREFERENCED_PARAMETER(dummy);
|
||||
DWORD iResult, dwRead, bSuccess;
|
||||
|
||||
for (;;) {
|
||||
CHAR chBuf[DEFAULT_BUFLEN] = "";
|
||||
|
||||
bSuccess =
|
||||
ReadFile(GetStdHandle(STD_INPUT_HANDLE), chBuf, DEFAULT_BUFLEN, &dwRead, NULL);
|
||||
if (!bSuccess) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
iResult = send(ConnectSocket, chBuf, dwRead, 0);
|
||||
if (iResult == SOCKET_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI ClientReadFromPipe(LPDWORD dummy) {
|
||||
UNREFERENCED_PARAMETER(dummy);
|
||||
DWORD iResult, dwRead, bSuccess;
|
||||
|
||||
for (;;) {
|
||||
CHAR chBuf[DEFAULT_BUFLEN + 1] = "";
|
||||
|
||||
iResult = recv(ConnectSocket, chBuf, DEFAULT_BUFLEN, 0);
|
||||
if (iResult > 0) {
|
||||
chBuf[strlen(chBuf)] = 0;
|
||||
bSuccess = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf,
|
||||
strlen(chBuf), &dwRead, NULL);
|
||||
if (!bSuccess) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
// Defined functions
|
||||
VOID StartShellClient(TCHAR *ServerIP);
|
@ -0,0 +1,149 @@
|
||||
#include "service.h"
|
||||
|
||||
extern SERVICE_STATUS gSvcStatus;
|
||||
extern SERVICE_STATUS_HANDLE gSvcStatusHandle;
|
||||
extern HANDLE ghSvcStopEvent;
|
||||
|
||||
VOID SvcInstall() {
|
||||
SC_HANDLE schSCManager;
|
||||
SC_HANDLE schService;
|
||||
TCHAR szUnquotedPath[MAX_PATH];
|
||||
|
||||
if (!GetModuleFileName(NULL, szUnquotedPath, MAX_PATH)) {
|
||||
printf("Cannot install service (%d)\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
TCHAR szPath[MAX_PATH];
|
||||
StringCbPrintf(szPath, MAX_PATH, TEXT("\"%s\" -sc"), szUnquotedPath);
|
||||
|
||||
// Get a handle to the SCM database.
|
||||
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (NULL == schSCManager) {
|
||||
printf("OpenSCManager failed (%d)\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Installing %s as service...\n", szPath);
|
||||
|
||||
schService = CreateService(schSCManager, // SCM database
|
||||
SVCNAME, // name of service
|
||||
SVCNAME, // service name to display
|
||||
SERVICE_ALL_ACCESS, // desired access
|
||||
SERVICE_WIN32_OWN_PROCESS, // service type
|
||||
SERVICE_DEMAND_START, // start type
|
||||
SERVICE_ERROR_NORMAL, // error control type
|
||||
szPath, // path to service's binary
|
||||
NULL, // no load ordering group
|
||||
NULL, // no tag identifier
|
||||
NULL, // no dependencies
|
||||
NULL, // LocalSystem account
|
||||
NULL); // no password
|
||||
|
||||
if (schService == NULL) {
|
||||
printf("CreateService failed (%d)\n", GetLastError());
|
||||
CloseServiceHandle(schSCManager);
|
||||
return;
|
||||
}
|
||||
else
|
||||
printf("Service installed successfully\n");
|
||||
|
||||
CloseServiceHandle(schService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
}
|
||||
|
||||
VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
|
||||
DWORD dwWaitHint) {
|
||||
static DWORD dwCheckPoint = 1;
|
||||
|
||||
// Fill in the SERVICE_STATUS structure.
|
||||
gSvcStatus.dwCurrentState = dwCurrentState;
|
||||
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
|
||||
gSvcStatus.dwWaitHint = dwWaitHint;
|
||||
|
||||
if (dwCurrentState == SERVICE_START_PENDING)
|
||||
gSvcStatus.dwControlsAccepted = 0;
|
||||
else
|
||||
gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||
|
||||
if ((dwCurrentState == SERVICE_RUNNING) ||
|
||||
(dwCurrentState == SERVICE_STOPPED))
|
||||
gSvcStatus.dwCheckPoint = 0;
|
||||
else
|
||||
gSvcStatus.dwCheckPoint = dwCheckPoint++;
|
||||
|
||||
// Report the status of the service to the SCM.
|
||||
SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
|
||||
}
|
||||
|
||||
VOID WINAPI SvcCtrlHandler(DWORD dwCtrl) {
|
||||
// Handle the requested control code.
|
||||
switch (dwCtrl) {
|
||||
case SERVICE_CONTROL_STOP:
|
||||
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
|
||||
|
||||
// Signal the service to stop.
|
||||
SetEvent(ghSvcStopEvent);
|
||||
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
|
||||
|
||||
return;
|
||||
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID SvcReportEvent(LPTSTR szFunction) {
|
||||
HANDLE hEventSource;
|
||||
LPCTSTR lpszStrings[2];
|
||||
TCHAR Buffer[80];
|
||||
|
||||
hEventSource = RegisterEventSource(NULL, SVCNAME);
|
||||
|
||||
if (NULL != hEventSource) {
|
||||
StringCchPrintf(Buffer, 80, TEXT("%s failed with %d"), szFunction,
|
||||
GetLastError());
|
||||
|
||||
lpszStrings[0] = SVCNAME;
|
||||
lpszStrings[1] = Buffer;
|
||||
|
||||
ReportEvent(hEventSource, // event log handle
|
||||
EVENTLOG_ERROR_TYPE, // event type
|
||||
0, // event category
|
||||
SVC_ERROR, // event identifier
|
||||
NULL, // no security identifier
|
||||
2, // size of lpszStrings array
|
||||
0, // no binary data
|
||||
lpszStrings, // array of strings
|
||||
NULL); // no binary data
|
||||
|
||||
DeregisterEventSource(hEventSource);
|
||||
}
|
||||
}
|
||||
|
||||
VOID SvcRemove(void) {
|
||||
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
if (!hSCManager) {
|
||||
printf("Error: Can't open Service Control Manager\n");
|
||||
// addLogMessage("Error: Can't open Service Control Manager");
|
||||
return;
|
||||
}
|
||||
|
||||
SC_HANDLE hService = OpenService(hSCManager, SVCNAME, SERVICE_STOP | DELETE);
|
||||
if (!hService) {
|
||||
printf("Error: Can't remove service\n");
|
||||
// addLogMessage("Error: Can't remove service");
|
||||
CloseServiceHandle(hSCManager);
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteService(hService);
|
||||
CloseServiceHandle(hService);
|
||||
CloseServiceHandle(hSCManager);
|
||||
// addLogMessage("Success remove service!");
|
||||
printf("Service deleted successfully\n");
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#pragma comment(lib, "advapi32.lib")
|
||||
|
||||
#define SVCNAME TEXT("ShellServer")
|
||||
#define SVC_ERROR ((DWORD)0xC0020001L)
|
||||
|
||||
VOID SvcInstall(void);
|
||||
VOID WINAPI SvcCtrlHandler(DWORD);
|
||||
VOID WINAPI SvcMain(DWORD, LPTSTR*);
|
||||
|
||||
VOID ReportSvcStatus(DWORD, DWORD, DWORD);
|
||||
VOID SvcInit(DWORD, LPTSTR*);
|
||||
VOID SvcReportEvent(LPTSTR);
|
Loading…
Reference in New Issue