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