JD2022-TU1/main/extern/ITNetwork/gear/private/tools/GearRemoteFileSystem/GearRemoteFileSystem.cpp

549 lines
16 KiB
C++

// GearRemoteFileSystem.cpp : Defines the entry point for the console application.
//
// PORT 8088
#include "stdafx.h"
#include "logfile.h"
#include "Windows.h"
#include "Winsvc.h"
#include <conio.h>
#include "time.h"
#include "../Utils/cpp/singleinstancechecker.h"
#define CONFIG_FILENAME "config.xml"
#define SERVER_LOG_LEVEL GEAR_LOG_USER_DEFINED
#define SYSTEM_LOG_LEVEL (GEAR_LOG_INFO | GEAR_LOG_ERROR | GEAR_LOG_CRITICAL | SERVER_LOG_LEVEL)
#define CMD_LINE_MSG "\nGearRemoteFileSystem -i -d -start -stop -n\n" \
"-i To install service\n" \
"-d To UnInstall service\n" \
"-start To start the service\n" \
"-stop To stop the service\n" \
"-n To run GearRemoteFileSystem as a normal command line application\n"\
"-v Verbose Mode (will display full debug info)\n"
LogFile* errorLogfile=0;
Gear::RFSServer* gRFSServer = 0;
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning = true;
Gear::U32 ServerLogLevel = SYSTEM_LOG_LEVEL;
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
BOOL InstallService();
BOOL DeleteService();
BOOL StartService();
BOOL StopService();
int RealMain(BOOL bStartFromService);
////////////////////////////////////////////////////////////////////////////////////////////////////
static void MyConsoleOut(Gear::U32 iLogLevel,const char* msg)
{
GEAR_UNUSED(iLogLevel);
if (strstr(msg, "Debug :") == 0)
{
printf("%s", msg);
if (errorLogfile)
errorLogfile->Write(msg);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
static int AssertFunct(const char *condition, const char *msg, const char *file, int line, int extra)
{
GEAR_UNUSED(extra);
char tmp[256];
Gear::StrFormat::snprintf(tmp, 256, "ASSERT: %s %s at %s(%d)\n", condition, msg, file, line);
Gear::NativeDebugOutput(tmp);
printf("%s", tmp);
if (errorLogfile)
errorLogfile->Write(tmp);
return 0;
}
////////////////////////////////////////////////////////////////////
//
// -i install the service
// -d delete the service
// -start start the service
// -stop stop the srevice
// -n start the server as a command line application and not a service
// -v Verbose
//
int main(int argc, char* argv[])
{
bool RunMain = false;
if(argc > 1)
{
for(int i = 1; i < argc; i++)
{
if(strcmp(argv[i],"-i")==0)
{
if(InstallService())
printf("\n\nService Installed Sucessfully\n");
else
printf("\n\nError Installing Service\n");
}
else if(strcmp(argv[i],"-d")==0)
{
if(DeleteService())
printf("\n\nService UnInstalled Sucessfully\n");
else
printf("\n\nError UnInstalling Service\n");
}
else if(strcmp(argv[i],"-start")==0)
{
StartService();
}
else if(strcmp(argv[i],"-stop")==0)
{
StopService();
}
else if(strcmp(argv[i],"-n")==0)
{
//NOTE: if you're debugging the server, use -n to run it as a normal command line application
RunMain = true;
}
else if(strcmp(argv[i],"-v")==0)
{
ServerLogLevel = 0xFFFFFFFF;
}
else
{
printf("\n\nUnknown Switch"CMD_LINE_MSG);
}
} // end for
if(RunMain)
{
RealMain(false);
}
}
else
{
SERVICE_TABLE_ENTRY DispatchTable[]= {{"GearRemoteFileSystem",ServiceMain},{NULL,NULL}};
if (StartServiceCtrlDispatcher(DispatchTable) == 0)
{
//NOTE: if you're debugging the server, use -n to run it as a normal command line application
MyConsoleOut(GEAR_LOG_INFO,"\n\nYou cannot start the service from the command line.\n"
"Please use the -start command line option if it is not allready started\n"
"If you dont want to run this server as a service, use the -n option\n"
"Here are the command line options : "CMD_LINE_MSG);
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void WINAPI ServiceMain(DWORD , LPTSTR *)
{
m_ServiceStatus.dwServiceType = SERVICE_WIN32;
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwServiceSpecificExitCode = 0;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
m_ServiceStatusHandle = RegisterServiceCtrlHandler("GearRemoteFileSystem", ServiceCtrlHandler);
if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error registering the service\n");
return;
}
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus))
{
}
Sleep(3000);
GEAR_LOG(GEAR_LOG_MSG, "Service is running...\n");
RealMain(true);
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
bRunning=false;
GEAR_LOG(GEAR_LOG_MSG, "Stopping service\n");
if( gRFSServer )
gRFSServer->Shutdown();
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL GetServiceBinaryPath(Gear::GearString & directoryPath)
{
SC_HANDLE schService, schSCManager;
LPQUERY_SERVICE_CONFIG lpqscBuf;
DWORD dwBytesNeeded;
BOOL bSuccess = false;
// Open a handle to the SC Manager database...
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Opening Service Manager\n");
}
else
{
schService=OpenService(schSCManager,"GearRemoteFileSystem",SERVICE_ALL_ACCESS);
if (schService == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Opening Service GearRemoteFileSystem\n");
}
else
{
// Allocate a buffer for the configuration information.
lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
if (lpqscBuf == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error , Could not allocate memory to retrieve service config.\n");
}
else
{
// Get the configuration information.
if (! QueryServiceConfig(schService, lpqscBuf,4096, &dwBytesNeeded))
{
GEAR_LOG(GEAR_LOG_ERROR, "Error , Could not retrieve service configuration\n");
}
else
{
directoryPath = lpqscBuf->lpBinaryPathName;
Gear::S32 iIndex = directoryPath.FindReverse('\\');
if (iIndex != -1)
{
directoryPath.Resize(iIndex);
bSuccess = true;
}
}
LocalFree(lpqscBuf);
}
}
}
return bSuccess;
}
BOOL InstallService()
{
char strDir[1024];
SC_HANDLE schSCManager,schService;
GetCurrentDirectory(1024,strDir);
strcat(strDir,"\\GearRemoteFileSystem.exe");
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error openning SCManager\n");
return false;
}
LPCTSTR lpszBinaryPathName=strDir;
schService = CreateService(schSCManager,"GearRemoteFileSystem", "Gear Remote file system server", // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
lpszBinaryPathName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error creating service \n");
return false;
}
CloseServiceHandle(schService);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL DeleteService()
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error deleting service \n");
return false;
}
hService=OpenService(schSCManager,"GearRemoteFileSystem",SERVICE_ALL_ACCESS);
if (hService == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error deleting service \n");
return false;
}
if(DeleteService(hService)==0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error deleting service \n");
return false;
}
if(CloseServiceHandle(hService)==0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error deleting service \n");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL StartService()
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Starting service\n");
return false;
}
hService=OpenService(schSCManager,"GearRemoteFileSystem",SERVICE_ALL_ACCESS);
if (hService == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Starting service \n");
return false;
}
if(StartService(hService, 0, 0)==0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Starting service \n");
return false;
}
if(CloseServiceHandle(hService)==0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Starting service \n");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL StopService()
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Stoping service \n");
return false;
}
hService=OpenService(schSCManager,"GearRemoteFileSystem",SERVICE_ALL_ACCESS);
if (hService == NULL)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Stoping service \n");
return false;
}
SERVICE_STATUS status;
if(ControlService(hService, SERVICE_CONTROL_STOP, &status)==0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Stoping service \n");
return false;
}
if(CloseServiceHandle(hService)==0)
{
GEAR_LOG(GEAR_LOG_ERROR, "Error Stoping service \n");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Be sure to have Locked the server config before calling SaveServerConfig()
Gear::Bool SaveServerConfig(Gear::RFS::Config& Config, Gear::Char* pFilename)
{
Gear::GearString filename = Config.GetApplicationPath();
filename += pFilename;
Gear::XMLWriterSerializer SerializerObj;
Gear::Bool result = SerializerObj.SetDevice(filename.CStr());
if( result )
{
SerializerObj << Config;
}
return result;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void LoadServerConfig(Gear::RFSServer& server, Gear::Char* pFilename)
{
// Take atomic access to the Server config
Gear::RFS::Config& Config = server.GetConfig();
Gear::GearString filename = Config.GetApplicationPath();
filename += pFilename;
Gear::XMLReaderSerializer SerializerObj;
Gear::Bool result = SerializerObj.SetDevice(filename.CStr());
if( result )
{
SerializerObj << Config;
GEAR_LOG1(SERVER_LOG_LEVEL, "> Configuration loaded successfully from '%s'\n", pFilename);
}
else
{
GEAR_LOG1(SERVER_LOG_LEVEL, "> Configuration file not found, creating new one '%s'\n", pFilename);
// Set Default configuration since we cannot find the configuration file
Config.ResetDefaultConfig();
// For the server application, let's assume we are at Ubisoft & Add the Ubisoft domain
Config.AddAuthorizedIP("10.*.*.*");
SaveServerConfig(Config, pFilename);
}
// Release atomic access to the Server config
server.ReleaseConfig();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void ConfigModificationCallback(Gear::RFS::Config& Config)
{
SaveServerConfig(Config, CONFIG_FILENAME);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
int RealMain(BOOL bStartFromService)
{
SingleInstanceChecker singleInstanceChecker("GearRemoteFileSystem");
if(singleInstanceChecker.IsAlreadyStarted())
{
GEAR_LOG(GEAR_LOG_ERROR, "Gear Remote File System Server is already running, exising...");
return FALSE;
}
errorLogfile = new LogFile("error.log");
//if we start from a service we need to change directory path
if (bStartFromService)
{
//get the path
Gear::GearString strServiceBinaryPath;
if (GetServiceBinaryPath(strServiceBinaryPath))
{
if (!SetCurrentDirectory(strServiceBinaryPath.CStr()))
{
GEAR_LOG(GEAR_LOG_ERROR, "Could not change current directory to service application root : ");
GEAR_LOG(GEAR_LOG_ERROR, strServiceBinaryPath.CStr());
return FALSE;
}
}
else
{
GEAR_LOG(GEAR_LOG_ERROR, "Could not retrieve service information, make sure the service is registered.");
return FALSE;
}
}
// Start Gear
Gear::StartEngine();
// Set Logging Level
Gear::GearLogManager::SetLoggingFilter(ServerLogLevel);
// Connect our Assert Function
Gear::Assert::ReplaceAssertFunction(AssertFunct);
// Create Console functor
Gear::ConsoleOut::ConsoleHook functor = Gear::MakeFunctor(&functor, MyConsoleOut);
Gear::ConsoleOut::AddHook(functor);
{
Gear::RFSServer rfsServer(SERVER_LOG_LEVEL, 0, Gear::True);
gRFSServer = &rfsServer;
// Load server config...
LoadServerConfig(rfsServer, CONFIG_FILENAME);
Gear::RFSServer::ConfigFunctor ConfigModifFunctor;
ConfigModifFunctor = MakeFunctor(&ConfigModifFunctor, &ConfigModificationCallback);
// Register config change notifier, to save on changes
rfsServer.SetConfigFunctor(ConfigModifFunctor);
// Start server...
rfsServer.Start();
// If a key is pressed we quit
Gear::ConsoleOut::Print("Press any key to exit...\n" );
while (!_kbhit())
Gear::System::Sleep(100);
rfsServer.Shutdown();
// Reset global server pointer
gRFSServer = 0;
}
Gear::ShutDownEngine();
delete errorLogfile;
return 0;
}