// 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 #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; }