Пример #1
0
int
main(int argc, char *argv[])
{
   char path[PATH_MAX];
   FILE *log;

   strcpy(path, "/tmp/efreetd_XXXXXX");
   if (mkstemp(path) < 0)
     {
        perror("mkstemp");
        return 1;
     }
   if (chmod(path, 0700) < 0)
     {
        perror("chmod");
        return 1;
     }

   log = fopen(path, "wb");
   if (!log) return 1;

   if (!eina_init()) return 1;
   eina_log_print_cb_set(eina_log_print_cb_file, log);

   efreetd_log_dom = eina_log_domain_register("efreetd", EFREETD_DEFAULT_LOG_COLOR);
   if (efreetd_log_dom < 0)
     {
        EINA_LOG_ERR("Efreet: Could not create a log domain for efreetd.");
        goto ecore_error;
     }
   if (!ecore_init()) goto ecore_error;
   ecore_app_args_set(argc, (const char **)argv);
   if (!ecore_file_init()) goto ecore_file_error;

   if (!dbus_init()) goto dbus_error;
   if (!cache_init()) goto cache_error;

#ifdef HAVE_SYS_RESOURCE_H
   setpriority(PRIO_PROCESS, 0, 19);
#elif _WIN32
    SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
#endif

   ecore_main_loop_begin();

   cache_shutdown();
   dbus_shutdown();
   ecore_file_shutdown();
   ecore_shutdown();
   eina_log_domain_unregister(efreetd_log_dom);
   efreetd_log_dom = -1;
   eina_shutdown();
   return 0;

cache_error:
   dbus_shutdown();
dbus_error:
   ecore_file_shutdown();
ecore_file_error:
   ecore_shutdown();
ecore_error:
   if (efreetd_log_dom >= 0)
     eina_log_domain_unregister(efreetd_log_dom);
   efreetd_log_dom = -1;
   eina_shutdown();
   return 1;
}
Пример #2
0
/// Do 'execute' instruction.
///
/// \param sCommand_line    fully command line, after modify
///
/// Return AGENT_RET_SUCCESS if succeed, or AGENT_RET_FAIL if fail
static MBA_AGENT_RETURN execute_cmd(char *sCmdline) {
    // Child  : hOutputWrite, hInputRead, hErrorWrite
    // Parent : hOutputRead, hInputWrite
    HANDLE hOutputRead, hOutputWrite;
    HANDLE hInputRead, hInputWrite;
    HANDLE hErrorWrite;
    
    // Thread handler
    HANDLE hThread;
    DWORD dTid;
    
    DWORD dEndSize = 0;

    WSAPROTOCOL_INFO protoInfo;
    
    SECURITY_ATTRIBUTES pipeAttr;

    // Set up the security attributes struct.
    pipeAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    pipeAttr.lpSecurityDescriptor = NULL;
    pipeAttr.bInheritHandle = TRUE;

    // Create the child output pipe.
    if (!CreatePipe(&hOutputRead, &hOutputWrite, &pipeAttr, 0)) {
        display_error("execute_cmd - CreatePipe", TRUE);
        return AGENT_RET_FAIL;
    }

    // Create a duplicate of the output write handle for the std error write handle.
    // This is necessary in case the child application closes one of its std output handles.
    if ( !DuplicateHandle(
            GetCurrentProcess(), hOutputWrite,
            GetCurrentProcess(), &hErrorWrite,
            0, TRUE, DUPLICATE_SAME_ACCESS) ) {
                display_error("execute_cmd - DuplicateHandle : hErrorWrite -> hOutputWrite", TRUE);
                return AGENT_RET_FAIL;
            }
        

    // Create the child input pipe.
    if ( !CreatePipe( &hInputRead, &hInputWrite, &pipeAttr,0) ){
        display_error("execute_cmd - CreatePipe", TRUE);
        return AGENT_RET_FAIL;
    }

    // Ensure the handle for reading from child stdout pipe is not inherited
    if ( !SetHandleInformation( hOutputRead, HANDLE_FLAG_INHERIT, 0) ) {
        display_error("execute_cmd - SetHandleInformation : Child read", TRUE);
        return AGENT_RET_FAIL;
    }

    // Ensure the handle for writing to child stdin pipe is not inherited
    if ( !SetHandleInformation( hInputWrite, HANDLE_FLAG_INHERIT, 0) ) {
        display_error("execute_cmd - SetHandleInformation : Child write", TRUE);
        return AGENT_RET_FAIL;
    }
        
    // Sets up STARTUPINFO structure, and launches redirected child.
    prep_and_launch_redirected_child(sCmdline, hOutputWrite, hInputRead, hErrorWrite);

    // Close pipe handles (do not continue to modify in the parent).
    if (!CloseHandle(hOutputWrite)) {
        display_error("execute_cmd - CloseHandle : Child Write", TRUE);
        return AGENT_RET_FAIL;
    }
    if (!CloseHandle(hInputRead)) {
        display_error("execute_cmd - CloseHandle : Child Read", TRUE);
        return AGENT_RET_FAIL;
    }
    if (!CloseHandle(hErrorWrite)) {
        display_error("execute_cmd - CloseHandle : Child Error", TRUE);
        return AGENT_RET_FAIL;
    }

    // Duplicate ClientSocket for thread
    WSADuplicateSocket( g_sClientSocket, GetCurrentProcessId(), &protoInfo );
    g_sClientDupSocket = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, &protoInfo, 0, 0 );
    if( g_sClientDupSocket == INVALID_SOCKET ) {
        display_error("execute_cmd - WSASocket : Dup ClientSocket", TRUE );
        return AGENT_RET_FAIL;
    }

    // Launch the thread that gets the input and sends it to the child.
    hThread = CreateThread(
        NULL,                       // a pointer to a SECURITY_ATTRIBUTES structure
        0,                          // the initial size of the stack, in bytes
        get_and_send_input_thread,  // a pointer to the application-defined function to be executed by the thread
        (LPVOID)hInputWrite,        // a pointer to a variable to be passed to the thread.
        0,                          // the flags that control the creation of the thread
        &dTid);                      // a pointer to a variable that receives the thread identifier.
                                    //      If this parameter is NULL, the thread identifier is not returned.
    if (hThread == NULL) {
        display_error("execute_cmd - CreateThread : Write", TRUE);
        return AGENT_RET_FAIL;
    }

    // Read the child's output
    read_and_handle_output( hOutputRead );
    // Redirection is complete 

    // Tell the thread to exit and wait for thread to die.
    closesocket( g_sClientDupSocket );
    
    // send out the zero-sized message to terminate agent 'exec' action
    send(g_sClientSocket, (const char*)&dEndSize, sizeof(dEndSize), 0);

    // Wait Thread which keep receiving & forwarding commands
    if (WaitForSingleObject(hThread, INFINITE) == WAIT_FAILED) {
        display_error("WaitForSingleObject", TRUE);
        return AGENT_RET_FAIL;
    }

    // Close input and output handle
    if (!CloseHandle(hOutputRead)) {
        display_error("execute_cmd - CloseHandle : hOutputRead", TRUE);
        return AGENT_RET_FAIL;
    }
    if (!CloseHandle(hInputWrite)) {
        display_error("execute_cmd - CloseHandle : hInputWrite", TRUE);
        return AGENT_RET_FAIL;
    }
    return AGENT_RET_SUCCESS;
}
Пример #3
0
/*
 * Setup and run the server. This is called from Init via the loader.
 */
DWORD server_setup( SOCKET fd )
{
	Remote * remote        = NULL;
	char cStationName[256] = {0};
	char cDesktopName[256] = {0};
	DWORD res              = 0;

	dprintf("[SERVER] Initializing...");

#ifdef _UNIX
	int local_error = 0;
#endif

	// if hAppInstance is still == NULL it means that we havent been
	// reflectivly loaded so we must patch in the hAppInstance value
	// for use with loading server extensions later.
	InitAppInstance();

	srand( (unsigned int)time(NULL) );
	
	__try 
	{
		do
		{
			dprintf( "[SERVER] module loaded at 0x%08X", hAppInstance );
			
			// Open a THREAD item for the servers main thread, we use this to manage migration later.
			serverThread = thread_open();

			dprintf( "[SERVER] main server thread: handle=0x%08X id=0x%08X sigterm=0x%08X", serverThread->handle, serverThread->id, serverThread->sigterm );

			if( !(remote = remote_allocate(fd)) )
			{
				SetLastError( ERROR_NOT_ENOUGH_MEMORY );
				break;
			}

			// Do not allow the file descriptor to be inherited by child processes
			SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);

			dprintf("[SERVER] Initializing tokens...");

			// Store our thread handle
			remote->hServerThread = serverThread->handle;

#ifdef _WIN32
			// Store our process token
			if (!OpenThreadToken(remote->hServerThread, TOKEN_ALL_ACCESS, TRUE, &remote->hServerToken))
				OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &remote->hServerToken);

			// Copy it to the thread token
			remote->hThreadToken = remote->hServerToken;

			// Save the initial session/station/desktop names...
			remote->dwOrigSessionId      = server_sessionid();
			remote->dwCurrentSessionId   = remote->dwOrigSessionId;
			GetUserObjectInformation( GetProcessWindowStation(), UOI_NAME, &cStationName, 256, NULL );
			remote->cpOrigStationName    = _strdup( cStationName );
			remote->cpCurrentStationName = _strdup( cStationName );
			GetUserObjectInformation( GetThreadDesktop( GetCurrentThreadId() ), UOI_NAME, &cDesktopName, 256, NULL );
			remote->cpOrigDesktopName    = _strdup( cDesktopName );
			remote->cpCurrentDesktopName = _strdup( cDesktopName );
#endif

			dprintf("[SERVER] Flushing the socket handle...");
			server_socket_flush( remote );
		
			dprintf("[SERVER] Initializing SSL...");
			if( !server_initialize_ssl( remote ) )
				break;

			dprintf("[SERVER] Negotiating SSL...");
			if( !server_negotiate_ssl( remote ) )
				break;

			dprintf("[SERVER] Registering dispatch routines...");
			register_dispatch_routines();

			dprintf("[SERVER] Entering the main server dispatch loop...");
			server_dispatch( remote );
		
			dprintf("[SERVER] Deregistering dispatch routines...");
			deregister_dispatch_routines();

		} while (0);

		dprintf("[SERVER] Closing down SSL...");

		server_destroy_ssl( remote );

		if( remote )
			remote_deallocate( remote );

	} 
	__except( exceptionfilter(GetExceptionCode(), GetExceptionInformation()) )
	{
		dprintf("[SERVER] *** exception triggered!");

		thread_kill( serverThread );
	}

	dprintf("[SERVER] Finished.");
	return res;
}
Пример #4
0
static void dumpBacktrace( unsigned int depth )
{
  if ( depth == 0 )
    depth = 20;

#if ((defined(linux) || defined(__linux__)) && !defined(ANDROID)) || defined(__FreeBSD__)
  // Below there is a bunch of operations that are not safe in multi-threaded
  // environment (dup()+close() combo, wait(), juggling with file descriptors).
  // Maybe some problems could be resolved with dup2() and waitpid(), but it seems
  // that if the operations on descriptors are not serialized, things will get nasty.
  // That's why there's this lovely mutex here...
  static QMutex mutex;
  QMutexLocker locker( &mutex );

  int stderr_fd = -1;
  if ( access( "/usr/bin/c++filt", X_OK ) < 0 )
  {
    myPrint( "Stacktrace (c++filt NOT FOUND):\n" );
  }
  else
  {
    int fd[2];

    if ( pipe( fd ) == 0 && fork() == 0 )
    {
      close( STDIN_FILENO ); // close stdin

      // stdin from pipe
      if ( dup( fd[0] ) != STDIN_FILENO )
      {
        QgsDebugMsg( "dup to stdin failed" );
      }

      close( fd[1] );        // close writing end
      execl( "/usr/bin/c++filt", "c++filt", static_cast< char * >( nullptr ) );
      perror( "could not start c++filt" );
      exit( 1 );
    }

    myPrint( "Stacktrace (piped through c++filt):\n" );
    stderr_fd = dup( STDERR_FILENO );
    close( fd[0] );          // close reading end
    close( STDERR_FILENO );  // close stderr

    // stderr to pipe
    int stderr_new = dup( fd[1] );
    if ( stderr_new != STDERR_FILENO )
    {
      if ( stderr_new >= 0 )
        close( stderr_new );
      QgsDebugMsg( "dup to stderr failed" );
    }

    close( fd[1] );  // close duped pipe
  }

  void **buffer = new void *[ depth ];
  int nptrs = backtrace( buffer, depth );
  backtrace_symbols_fd( buffer, nptrs, STDERR_FILENO );
  delete [] buffer;
  if ( stderr_fd >= 0 )
  {
    int status;
    close( STDERR_FILENO );
    int dup_stderr = dup( stderr_fd );
    if ( dup_stderr != STDERR_FILENO )
    {
      close( dup_stderr );
      QgsDebugMsg( "dup to stderr failed" );
    }
    close( stderr_fd );
    wait( &status );
  }
#elif defined(Q_OS_WIN)
  void **buffer = new void *[ depth ];

  SymSetOptions( SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_UNDNAME );
  SymInitialize( GetCurrentProcess(), "http://msdl.microsoft.com/download/symbols;http://download.osgeo.org/osgeo4w/symstore", TRUE );

  unsigned short nFrames = CaptureStackBackTrace( 1, depth, buffer, nullptr );
  SYMBOL_INFO *symbol = ( SYMBOL_INFO * ) qgsMalloc( sizeof( SYMBOL_INFO ) + 256 );
  symbol->MaxNameLen = 255;
  symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
  IMAGEHLP_LINE *line = ( IMAGEHLP_LINE * ) qgsMalloc( sizeof( IMAGEHLP_LINE ) );
  line->SizeOfStruct = sizeof( IMAGEHLP_LINE );

  for ( int i = 0; i < nFrames; i++ )
  {
    DWORD dwDisplacement;
    SymFromAddr( GetCurrentProcess(), ( DWORD64 )( buffer[ i ] ), 0, symbol );
    symbol->Name[ 255 ] = 0;
    if ( SymGetLineFromAddr( GetCurrentProcess(), ( DWORD64 )( buffer[i] ), &dwDisplacement, line ) )
    {
      myPrint( "%s(%d) : (%s) frame %d, address %x\n", line->FileName, line->LineNumber, symbol->Name, i, symbol->Address );
    }
    else
    {
      myPrint( "%s(%d) : (%s) unknown source location, frame %d, address %x [GetLastError()=%d]\n", __FILE__, __LINE__, symbol->Name, i, symbol->Address, GetLastError() );
    }
  }

  qgsFree( symbol );
  qgsFree( line );
#else
  Q_UNUSED( depth );
#endif
}
Пример #5
0
int main(int argc, char* argv[])
{
  char exePath[MAXPATHLEN];

  nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
  if (NS_FAILED(rv)) {
    Output("Couldn't calculate the application directory.\n");
    return 255;
  }

  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
  if (!lastSlash || (lastSlash - exePath > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
    return 255;

  strcpy(++lastSlash, XPCOM_DLL);

  int gotCounters;
#if defined(XP_UNIX)
  struct rusage initialRUsage;
  gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
#elif defined(XP_WIN)
  // GetProcessIoCounters().ReadOperationCount seems to have little to
  // do with actual read operations. It reports 0 or 1 at this stage
  // in the program. Luckily 1 coincides with when prefetch is
  // enabled. If Windows prefetch didn't happen we can do our own
  // faster dll preloading.
  IO_COUNTERS ioCounters;
  gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
  if (gotCounters && !ioCounters.ReadOperationCount)
#endif
  {
      XPCOMGlueEnablePreload();
  }


  rv = XPCOMGlueStartup(exePath);
  if (NS_FAILED(rv)) {
    Output("Couldn't load XPCOM.\n");
    return 255;
  }

  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
  if (NS_FAILED(rv)) {
    Output("Couldn't load XRE functions.\n");
    return 255;
  }

#ifdef XRE_HAS_DLL_BLOCKLIST
  XRE_SetupDllBlocklist();
#endif

  if (gotCounters) {
#if defined(XP_WIN)
    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
                            int(ioCounters.ReadOperationCount));
    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER,
                            int(ioCounters.ReadTransferCount / 1024));
    IO_COUNTERS newIoCounters;
    if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) {
      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS,
                              int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount));
      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER,
                              int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024));
    }
#elif defined(XP_UNIX)
    XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS,
                            int(initialRUsage.ru_majflt));
    struct rusage newRUsage;
    if (!getrusage(RUSAGE_SELF, &newRUsage)) {
      XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS,
                              int(newRUsage.ru_majflt - initialRUsage.ru_majflt));
    }
#endif
  }

  int result;
  {
    ScopedLogging log;
    result = do_main(exePath, argc, argv);
  }

  XPCOMGlueShutdown();
  return result;
}
Пример #6
0
int main(int argc, char *argv[]) {
  DWORD  error;
  HANDLE process;
  ULONG64 module_base;
  int i;
  char* search;
  char buf[256];   /* Enough to hold one hex address, I trust! */
  int rv = 0;
  /* We may add SYMOPT_UNDNAME if --demangle is specified: */
  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES;
  char* filename = "a.out";         /* The default if -e isn't specified */
  int print_function_name = 0;      /* Set to 1 if -f is specified */

  for (i = 1; i < argc; i++) {
    if (strcmp(argv[i], "--functions") == 0 || strcmp(argv[i], "-f") == 0) {
      print_function_name = 1;
    } else if (strcmp(argv[i], "--demangle") == 0 ||
               strcmp(argv[i], "-C") == 0) {
      symopts |= SYMOPT_UNDNAME;
    } else if (strcmp(argv[i], "--exe") == 0 ||
               strcmp(argv[i], "-e") == 0) {
      if (i + 1 >= argc) {
        fprintf(stderr, "FATAL ERROR: -e must be followed by a filename\n");
        return 1;
      }
      filename = argv[i+1];
      i++;     /* to skip over filename too */
    } else if (strcmp(argv[i], "--help") == 0) {
      usage();
      exit(0);
    } else {
      usage();
      exit(1);
    }
  }

  process = GetCurrentProcess();

  if (!SymInitialize(process, NULL, FALSE)) {
    error = GetLastError();
    fprintf(stderr, "SymInitialize returned error : %lu\n", error);
    return 1;
  }

  search = malloc(SEARCH_CAP);
  if (SymGetSearchPath(process, search, SEARCH_CAP)) {
    if (strlen(search) + sizeof(";" WEBSYM) > SEARCH_CAP) {
      fprintf(stderr, "Search path too long\n");
      SymCleanup(process);
      return 1;
    }
    strcat(search, ";" WEBSYM);
  } else {
    error = GetLastError();
    fprintf(stderr, "SymGetSearchPath returned error : %lu\n", error);
    rv = 1;                   /* An error, but not a fatal one */
    strcpy(search, WEBSYM);   /* Use a default value */
  }
  if (!SymSetSearchPath(process, search)) {
    error = GetLastError();
    fprintf(stderr, "SymSetSearchPath returned error : %lu\n", error);
    rv = 1;                   /* An error, but not a fatal one */
  }

  SymSetOptions(symopts);
  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);
  if (!module_base) {
    /* SymLoadModuleEx failed */
    error = GetLastError();
    fprintf(stderr, "SymLoadModuleEx returned error : %lu for %s\n",
            error, filename);
    SymCleanup(process);
    return 1;
  }

  buf[sizeof(buf)-1] = '\0';  /* Just to be safe */
  while (fgets(buf, sizeof(buf)-1, stdin)) {
    /* GNU addr2line seems to just do a strtol and ignore any
     * weird characters it gets, so we will too.
     */
    unsigned __int64 reladdr = _strtoui64(buf, NULL, 16);
    ULONG64 buffer[(sizeof(SYMBOL_INFO) +
                    MAX_SYM_NAME*sizeof(TCHAR) +
                    sizeof(ULONG64) - 1)
                   / sizeof(ULONG64)];
    memset(buffer, 0, sizeof(buffer));
    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
    IMAGEHLP_LINE64 line;
    DWORD dummy;

    // Just ignore overflow. In an overflow scenario, the resulting address
    // will be lower than module_base which hasn't been mapped by any prior
    // SymLoadModuleEx() command. This will cause SymFromAddr() and
    // SymGetLineFromAddr64() both to return failures and print the correct
    // ?? and ??:0 message variant.
    ULONG64 absaddr = reladdr + module_base;

    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    // The length of the name is not including the null-terminating character.
    pSymbol->MaxNameLen = MAX_SYM_NAME - 1;
    if (print_function_name) {
      if (SymFromAddr(process, (DWORD64)absaddr, NULL, pSymbol)) {
        printf("%s\n", pSymbol->Name);
      } else {
        printf("??\n");
      }
    }
    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
    if (SymGetLineFromAddr64(process, (DWORD64)absaddr, &dummy, &line)) {
      printf("%s:%d\n", line.FileName, (int)line.LineNumber);
    } else {
      printf("??:0\n");
    }
  }
  SymUnloadModule64(process, module_base);
  SymCleanup(process);
  return rv;
}
Пример #7
0
/// Launch the realm server
extern int main(int argc, char **argv)
{
    sLog.SetLogDB(false);
    ///- Command line parsing to get the configuration file name
    char const* cfg_file = _RIBON_REALM_CONFIG;
    int c=1;
    while( c < argc )
    {
        if( strcmp(argv[c],"-c") == 0)
        {
            if( ++c >= argc )
            {
                sLog.outError("Runtime-Error: -c option requires an input argument");
                usage(argv[0]);
                return 1;
            }
            else
                cfg_file = argv[c];
        }

        #ifdef WIN32
        ////////////
        //Services//
        ////////////
        if( strcmp(argv[c],"-s") == 0)
        {
            if( ++c >= argc )
            {
                sLog.outError("Runtime-Error: -s option requires an input argument");
                usage(argv[0]);
                return 1;
            }
            if( strcmp(argv[c],"install") == 0)
            {
                if (WinServiceInstall())
                    sLog.outString("Installing service");
                return 1;
            }
            else if( strcmp(argv[c],"uninstall") == 0)
            {
                if(WinServiceUninstall())
                    sLog.outString("Uninstalling service");
                return 1;
            }
            else
            {
                sLog.outError("Runtime-Error: unsupported option %s",argv[c]);
                usage(argv[0]);
                return 1;
            }
        }
        if( strcmp(argv[c],"--service") == 0)
        {
            WinServiceRun();
        }
        ////
        #endif
        ++c;
    }

    if (!sConfig.SetSource(cfg_file))
    {
        sLog.outError("Could not find configuration file %s.", cfg_file);
        return 1;
    }
    sLog.Initialize();

    sLog.outString( "(logon-daemon) Revision: %s ", _FULLVERSION );
    sLog.outString( "Build Date: %s", __DATE__ );
    sLog.outString( "Build Time: %s", __TIME__ );
    sLog.outString( "<Ctrl-C> to stop.\n" );

    sLog.outString( "'########::'####:'########:::'#######::'##::: ##:");
    sLog.outString( " ##.... ##:. ##:: ##.... ##:'##.... ##: ###:: ##:");
    sLog.outString( " ##:::: ##:: ##:: ##:::: ##: ##:::: ##: ####: ##:");
    sLog.outString( " ########::: ##:: ########:: ##:::: ##: ## ## ##:");
    sLog.outString( " ##.. ##:::: ##:: ##.... ##: ##:::: ##: ##. ####:");
    sLog.outString( " ##::. ##::: ##:: ##:::: ##: ##:::: ##: ##:. ###:");
    sLog.outString( " ##:::. ##:'####: ########::. #######:: ##::. ##:");
    sLog.outString( "..:::::..::....::........::::.......:::..::::..::");
    sLog.outString( "                                        L O G O N");
    sLog.outString( "http://www.dark-resurrection.de/wowsp/         \n");

    sLog.outString("Using configuration file %s.", cfg_file);

    ///- Check the version of the configuration file
    uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
    if (confVersion < _REALMDCONFVERSION)
    {
        sLog.outError("*****************************************************************************");
        sLog.outError(" WARNING: Your RibonLogon.conf version indicates your conf file is out of date!");
        sLog.outError("          Please check for updates, as your current default values may cause");
        sLog.outError("          strange behavior.");
        sLog.outError("*****************************************************************************");
        clock_t pause = 3000 + clock();

        while (pause > clock()) {}
    }

    sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
    if (SSLeay() < 0x009080bfL )
    {
        sLog.outError("Outdated version of OpenSSL lib. Logins to server impossible!");
        sLog.outError("Minimal required version [OpenSSL 0.9.8k]");
        clock_t pause = 5000 + clock();
        while (pause > clock()) {}
        return 1;
    }

    /// realmd PID file creation
    std::string pidfile = sConfig.GetStringDefault("PidFile", "");
    if(!pidfile.empty())
    {
        uint32 pid = CreatePIDFile(pidfile);
        if( !pid )
        {
            sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() );
            return 1;
        }

        sLog.outString( "Daemon PID: %u\n", pid );
    }

    ///- Initialize the database connection
    if(!StartDB())
        return 1;

    ///- Initialize the log database
    if(sConfig.GetBoolDefault("EnableLogDB", false))
    {
        // everything successful - set var to enable DB logging once startup finished.
        sLog.SetLogDBLater(true);
        sLog.SetLogDB(false);
        // ensure we've set realm to 0 (realmd realmid)
        sLog.SetRealmID(0);
    }
    else
    {
        sLog.SetLogDBLater(false);
        sLog.SetLogDB(false);
        sLog.SetRealmID(0);
    }

    ///- Get the list of realms for the server
    m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20));
    if (m_realmList.size() == 0)
    {
        sLog.outError("No valid realms specified.");
        return 1;
    }

    ///- Launch the listening network socket
    port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
    std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0");

    SocketHandler h;
    ListenSocket<AuthSocket> authListenSocket(h);
    if ( authListenSocket.Bind(bind_ip.c_str(),rmport))
    {
        sLog.outError( "RibonLogon can not bind to %s:%d",bind_ip.c_str(), rmport );
        return 1;
    }

    h.Add(&authListenSocket);

    ///- Catch termination signals
    HookSignals();

    ///- Handle affinity for multiple processors and process priority on Windows
    #ifdef WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
        if(Aff > 0)
        {
            ULONG_PTR appAff;
            ULONG_PTR sysAff;

            if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
            {
                ULONG_PTR curAff = Aff & appAff;            // remove non accessible processors

                if(!curAff )
                {
                    sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff);
                }
                else
                {
                    if(SetProcessAffinityMask(hProcess,curAff))
                        sLog.outString("Using processors (bitmask, hex): %x", curAff);
                    else
                        sLog.outError("Can't set used processors (hex): %x", curAff);
                }
            }
            sLog.outString();
        }

        bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);

        if(Prio)
        {
            if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
                sLog.outString("RibonLogon process priority class set to HIGH");
            else
                sLog.outError("ERROR: Can't set realmd process priority class.");
            sLog.outString();
        }
    }
    #endif

    // maximum counter for next ping
    uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
    uint32 loopCounter = 0;

    // possibly enable db logging; avoid massive startup spam by doing it here.
    if (sLog.GetLogDBLater())
    {
        sLog.outString("Enabling database logging...");
        sLog.SetLogDBLater(false);
        // login db needs thread for logging
        sLog.SetLogDB(true);
    }
    else
    {
        sLog.SetLogDB(false);
        sLog.SetLogDBLater(false);
    }

    ///- Wait for termination signal
    while (!stopEvent)
    {

        h.Select(0, 100000);

        if( (++loopCounter) == numLoops )
        {
            loopCounter = 0;
            sLog.outDetail("Ping MySQL to keep connection alive");
            delete loginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1");
        }
#ifdef WIN32
        if (m_ServiceStatus == 0) stopEvent = true;
        while (m_ServiceStatus == 2) Sleep(1000);
#endif
    }

    ///- Wait for the delay thread to exit
    loginDatabase.ThreadEnd();
    loginDatabase.HaltDelayThread();

    ///- Remove signal handling before leaving
    UnhookSignals();

    sLog.outString( "Halting process..." );
    return 0;
}
Пример #8
0
//main function
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{

    HWND hwnd,hCheckWnd;        /* This is the handle for our window */
    MSG messages;        /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    hCheckWnd = GetRunningWindow();

    if (hCheckWnd)   // hCheckWnd != NULL -> Previous instance exists
    {
        MessageBox(hCheckWnd, "The program is already running", "Info", MB_OK);
        return FALSE;       // Exit program
    }
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;       /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;        /* No menu */
    wincl.cbClsExtra = 0;        /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;        /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    //wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    wincl.hbrBackground = GetSysColorBrush(COLOR_3DFACE);

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

   // int desktopwidth=GetSystemMetrics(SM_CXSCREEN);
    //int desktopheight=GetSystemMetrics(SM_CYSCREEN);


    /* The class is registered, let's create the program*/
    hwnd = CreateWindow (
               szClassName,        /* Classname */
               szTitleText,        /* Title Text */
               WS_DISABLED  , /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               MAX_X,        /* The programs width */
               MAX_Y,        /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,         /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL         /* No Window Creation data */
           );

    RegisterSession(hwnd);

    RegisterHotKey(NULL,1,MOD_CONTROL,0x71);

    SetProcessWorkingSetSize(GetCurrentProcess(), (SIZE_T) -1, (SIZE_T) -1);

    bool gRet;

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while ((gRet = GetMessage (&messages, NULL, 0, 0)) != 0 )
    {
        if (gRet == -1)
        {
            UnregisterSession(hwnd);
            OnDestroyTray();
            PostQuitMessage (0);
        }
        else
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
            if (messages.message == WM_HOTKEY)
            {
                SaveEnergyShort();
            }
        }
    }
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
Пример #9
0
 int ProcessInfo::getResidentSize() {
     PROCESS_MEMORY_COUNTERS pmc;
     verify( 16051, GetProcessMemoryInfo( GetCurrentProcess() , &pmc, sizeof(pmc) ) );
     return _wconvertmtos( pmc.WorkingSetSize );
 }
Пример #10
0
/** Print out a stacktrace. */
static void Stacktrace(LPEXCEPTION_POINTERS e, HANDLE hThread = INVALID_HANDLE_VALUE) {
	PIMAGEHLP_SYMBOL pSym;
	STACKFRAME sf;
	HANDLE process, thread;
	DWORD dwModBase, Disp;
	BOOL more = FALSE;
	int count = 0;
	char modname[MAX_PATH];

	pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);

	BOOL suspended = FALSE;
	CONTEXT c;
	if (e) {
		c = *e->ContextRecord;
		thread = GetCurrentThread();
	} else {
		SuspendThread(hThread);
		suspended = TRUE;
		memset(&c, 0, sizeof(CONTEXT));
		c.ContextFlags = CONTEXT_FULL;
		// FIXME: This does not work if you want to dump the current thread's stack
		if (!GetThreadContext(hThread, &c)) {
			ResumeThread(hThread);
			return;
		}
		thread = hThread;
	}

	ZeroMemory(&sf, sizeof(sf));
	sf.AddrPC.Offset = c.Eip;
	sf.AddrStack.Offset = c.Esp;
	sf.AddrFrame.Offset = c.Ebp;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrStack.Mode = AddrModeFlat;
	sf.AddrFrame.Mode = AddrModeFlat;

	process = GetCurrentProcess();

	// use globalalloc to reduce risk for allocator related deadlock
	char* printstrings = (char*)GlobalAlloc(GMEM_FIXED, 0);

	bool containsOglDll = false;
	while (true) {
		more = StackWalk(
			IMAGE_FILE_MACHINE_I386, // TODO: fix this for 64 bit windows?
			process,
			thread,
			&sf,
			&c,
			NULL,
			SymFunctionTableAccess,
			SymGetModuleBase,
			NULL
		);
		if (!more || sf.AddrFrame.Offset == 0) {
			break;
		}

		dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset);

		if (dwModBase) {
			GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH);
		} else {
			strcpy(modname, "Unknown");
		}

		pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
		pSym->MaxNameLength = MAX_PATH;

		char *printstringsnew = (char *)GlobalAlloc(GMEM_FIXED, (count + 1) * BUFFER_SIZE);
		memcpy(printstringsnew, printstrings, count * BUFFER_SIZE);
		GlobalFree(printstrings);
		printstrings = printstringsnew;

		if (SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym)) {
			// This is the code path taken on VC if debugging syms are found.
			SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s(%s+%#0lx) [0x%08lX]", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
		} else {
			// This is the code path taken on MinGW, and VC if no debugging syms are found.
			SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s [0x%08lX]", count, modname, sf.AddrPC.Offset);
		}

		// OpenGL lib names (ATI): "atioglxx.dll" "atioglx2.dll"
		containsOglDll = containsOglDll || strstr(modname, "atiogl");
		// OpenGL lib names (Nvidia): "nvoglnt.dll" "nvoglv32.dll" "nvoglv64.dll" (last one is a guess)
		containsOglDll = containsOglDll || strstr(modname, "nvogl");

		++count;
	}

	if (containsOglDll) {
		PRINT("This stack trace indicates a problem with your graphic card driver. "
		      "Please try upgrading or downgrading it. "
		      "Specifically recommended is the latest driver, and one that is as old as your graphic card. "
		      "Make sure to use a driver removal utility, before installing other drivers.");
	}

	if (suspended) {
		ResumeThread(hThread);
	}

	for (int i = 0; i < count; ++i) {
		PRINT("%s", printstrings + i * BUFFER_SIZE);
	}

	GlobalFree(printstrings);

	GlobalFree(pSym);
}
Пример #11
0
/// Main function
int Master::Run()
{
    BigNumber seed1;
    seed1.SetRand(16 * 8);

    sLog->outString("%s (worldserver-daemon)", _FULLVERSION);
    sLog->outString("<Ctrl-C> to stop.\n");

    sLog->outString(" ______                       __");
    sLog->outString("/\\__  _\\       __          __/\\ \\__");
    sLog->outString("\\/_/\\ \\/ _ __ /\\_\\    ___ /\\_\\ \\, _\\  __  __");
    sLog->outString("   \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
    sLog->outString("    \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
    sLog->outString("     \\ \\_\\ \\_\\  \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
    sLog->outString("      \\/_/\\/_/   \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
    sLog->outString("                                 C O R E  /\\___/");
    sLog->outString("http://TrinityCore.org                    \\/__/\n");
    sLog->outString(" ");
    sLog->outString("       ###                               ###");
    sLog->outString("      #OFFM##     Eye of Beholder     ##FFO8#");
    sLog->outString("    #F###K####     http://e0b.eu     #######MM#");
    sLog->outString("   #FFM#FFMM#                         #MFF##FF##");
    sLog->outString("  #F###K###         #########          ###M###F#");
    sLog->outString("  #M#MX#XXM#     #FMMMMM#F#MKMK#      ##EX##M#MM#");
    sLog->outString(" #MM#XX#VIM#    ##KMM##MMFK##M#8##    #FVO8XO#MM#");
    sLog->outString(" #FM##MF#OO8### #MKAAOF##OL1 `o8## ###FOOKMF###F#");
    sLog->outString(" #FM##K###XX#FOFMF3O#######D1` <AMFOFMXO###M##KM#");
    sLog->outString(" ##M######KX####gw#######Dyuu1  `1####AX######MM#");
    sLog->outString(" #MO##VAVVA#XX#u<8###########L< `<1KFX#8VIXVX#FF#");
    sLog->outString(" #FF#8IVVIV8#MK<<A###########w` `<<3M##VVIAIV#MFM");
    sLog->outString(" #KM#8hIAIIAK#J`<o8#########4<``<<1wM8AVhVVhV#MK#");
    sLog->outString(" ####8hIAVIVK#g`<<bF#######O1``<<11wMMAIVAIhV####");
    sLog->outString(" ####8hVIVAI#M81<<<<<1ooo1<```<11ub3M#AVAIVIV####");
    sLog->outString("#####AhAIhVMM##J111<<``````<<11ubgLK#MKAII8II#####");
    sLog->outString("#####8hAVhIK#VF8bo11<<<<<<<<11ubgJD#V##IhI8IV#####");
    sLog->outString("##MM#VhVVIA#M#FAKJbbuuu11oubbgJL488F#M#MIIAhh##M##");
    sLog->outString("#M#M#VhVII###VVM#KLggbbbbbg7JL349##VV8##AIAhh##K##");
    sLog->outString("#M#M##A8###KM8AIhHM#K8D4DD990KKK8hIA8KK####A8#####");
    sLog->outString("###M#####VK8AAIMVD##MMMM#KM#M#M#8IKVV8A#98####M###");
    sLog->outString("###A##8##I8VAKVh8# ##### ###### #KIh9AVKhV#88#A###");
    sLog->outString("###8A#AK#AV#VII0I#              #HI0IIM8V8#AAMA###");
    sLog->outString("###AV8hA#Vh8#ho0#                #KhhKKhI##hAAA8##");
    sLog->outString("##AV88hV#8hI#9h#                  #JI#AhI##hAAAV##");
    sLog->outString("##hhA8oI##ho9M#                    #MKho9#AoAMIh8#");
    sLog->outString("##ohM8oV##A9#                        #KA###oV#IoA#");
    sLog->outString("##hhM#######                          ########VoA#");
    sLog->outString("##h9K8A8IA8#                           #AVA#VMKhA#");
    sLog->outString("##h8K#8FVV9#                           #IAAMAMKVA#");
    sLog->outString("###A#M8#A88#                           #AVK8A#A8##");
    sLog->outString("###V#MA#AAM#                           #KIK8A#V8##");
    sLog->outString("#M8V#FAA8AF#                           #FV#AA#V88#");
    sLog->outString("#88A8K88AA##                           #9V88A#A88#");
    sLog->outString("##8V8AAAAV##                           #UVV8I#V88#");
    sLog->outString("#8VhVVVAIV##                           #AhV8h8hVA#");
    sLog->outString("#AVIVVVAhV##                           #UhV8h8hAV#");
    sLog->outString("#8VhVIVVIV#                            #9IIAh8hVA#");
    sLog->outString("#8IhVIVI8M#                            #M8IVh8hIA#");
    sLog->outString("#AIhVVVIK#                              #FIVh8hhA#");
    sLog->outString("##hoVUII#                                #UVhMhhA#");
    sLog->outString("#8hhV9I9#                                #KVV#hhA#");
    sLog->outString("##hhIKF#                                  #K88hhA#");
    sLog->outString("##hh8##                                     #Mhh8#");
    sLog->outString("#KhJ##                                       #8hA#");
    sLog->outString("####                                          ####");

    /// worldserver PID file creation
    std::string pidfile = ConfigMgr::GetStringDefault("PidFile", "");
    if (!pidfile.empty())
    {
        uint32 pid = CreatePIDFile(pidfile);
        if (!pid)
        {
            sLog->outError("Cannot create PID file %s.\n", pidfile.c_str());
            return 1;
        }

        sLog->outString("Daemon PID: %u\n", pid);
    }

    ///- Start the databases
    if (!_StartDB())
        return 1;

    // set server offline (not connectable)
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID);

    ///- Initialize the World
    sWorld->SetInitialWorldSettings();

    // Initialise the signal handlers
    WorldServerSignalHandler SignalINT, SignalTERM;
    #ifdef _WIN32
    WorldServerSignalHandler SignalBREAK;
    #endif /* _WIN32 */

    // Register worldserver's signal handlers
    ACE_Sig_Handler Handler;
    Handler.register_handler(SIGINT, &SignalINT);
    Handler.register_handler(SIGTERM, &SignalTERM);
    #ifdef _WIN32
    Handler.register_handler(SIGBREAK, &SignalBREAK);
    #endif /* _WIN32 */

    ///- Launch WorldRunnable thread
    ACE_Based::Thread world_thread(new WorldRunnable);
    world_thread.setPriority(ACE_Based::Highest);

    ACE_Based::Thread* cliThread = NULL;

#ifdef _WIN32
    if (ConfigMgr::GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
#else
    if (ConfigMgr::GetBoolDefault("Console.Enable", true))
#endif
    {
        ///- Launch CliRunnable thread
        cliThread = new ACE_Based::Thread(new CliRunnable);
    }

    ACE_Based::Thread rar_thread(new RARunnable);

    ///- Handle affinity for multiple processors and process priority on Windows
    #ifdef _WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0);
        if (Aff > 0)
        {
            ULONG_PTR appAff;
            ULONG_PTR sysAff;

            if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
            {
                ULONG_PTR curAff = Aff & appAff;            // remove non accessible processors

                if (!curAff)
                {
                    sLog->outError("Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", Aff, appAff);
                }
                else
                {
                    if (SetProcessAffinityMask(hProcess, curAff))
                        sLog->outString("Using processors (bitmask, hex): %x", curAff);
                    else
                        sLog->outError("Can't set used processors (hex): %x", curAff);
                }
            }
            sLog->outString("");
        }

        bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false);

        //if (Prio && (m_ServiceStatus == -1)  /* need set to default process priority class in service mode*/)
        if (Prio)
        {
            if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
                sLog->outString("worldserver process priority class set to HIGH");
            else
                sLog->outError("Can't set worldserver process priority class.");
            sLog->outString("");
        }
    }
    #endif
    //Start soap serving thread
    ACE_Based::Thread* soap_thread = NULL;

    if (ConfigMgr::GetBoolDefault("SOAP.Enabled", false))
    {
        TCSoapRunnable* runnable = new TCSoapRunnable();
        runnable->setListenArguments(ConfigMgr::GetStringDefault("SOAP.IP", "127.0.0.1"), ConfigMgr::GetIntDefault("SOAP.Port", 7878));
        soap_thread = new ACE_Based::Thread(runnable);
    }

    ///- Start up freeze catcher thread
    if (uint32 freeze_delay = ConfigMgr::GetIntDefault("MaxCoreStuckTime", 0))
    {
        FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable();
        fdr->SetDelayTime(freeze_delay*1000);
        ACE_Based::Thread freeze_thread(fdr);
        freeze_thread.setPriority(ACE_Based::Highest);
    }

    ///- Launch the world listener socket
    uint16 wsport = sWorld->getIntConfig(CONFIG_PORT_WORLD);
    std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0");

    if (sWorldSocketMgr->StartNetwork(wsport, bind_ip.c_str ()) == -1)
    {
        sLog->outError("Failed to start network");
        World::StopNow(ERROR_EXIT_CODE);
        // go down and shutdown the server
    }

    // set server online (allow connecting now)
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);

    sLog->outString("%s (worldserver-daemon) ready...", _FULLVERSION);

    // when the main thread closes the singletons get unloaded
    // since worldrunnable uses them, it will crash if unloaded after master
    world_thread.wait();
    rar_thread.wait();

    if (soap_thread)
    {
        soap_thread->wait();
        soap_thread->destroy();
        delete soap_thread;
    }

    // set server offline
    LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);

    ///- Clean database before leaving
    ClearOnlineAccounts();

    _StopDB();

    sLog->outString("Halting process...");

    if (cliThread)
    {
        #ifdef _WIN32

        // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API)
        //_exit(1);
        // send keyboard input to safely unblock the CLI thread
        INPUT_RECORD b[5];
        HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
        b[0].EventType = KEY_EVENT;
        b[0].Event.KeyEvent.bKeyDown = TRUE;
        b[0].Event.KeyEvent.uChar.AsciiChar = 'X';
        b[0].Event.KeyEvent.wVirtualKeyCode = 'X';
        b[0].Event.KeyEvent.wRepeatCount = 1;

        b[1].EventType = KEY_EVENT;
        b[1].Event.KeyEvent.bKeyDown = FALSE;
        b[1].Event.KeyEvent.uChar.AsciiChar = 'X';
        b[1].Event.KeyEvent.wVirtualKeyCode = 'X';
        b[1].Event.KeyEvent.wRepeatCount = 1;

        b[2].EventType = KEY_EVENT;
        b[2].Event.KeyEvent.bKeyDown = TRUE;
        b[2].Event.KeyEvent.dwControlKeyState = 0;
        b[2].Event.KeyEvent.uChar.AsciiChar = '\r';
        b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
        b[2].Event.KeyEvent.wRepeatCount = 1;
        b[2].Event.KeyEvent.wVirtualScanCode = 0x1c;

        b[3].EventType = KEY_EVENT;
        b[3].Event.KeyEvent.bKeyDown = FALSE;
        b[3].Event.KeyEvent.dwControlKeyState = 0;
        b[3].Event.KeyEvent.uChar.AsciiChar = '\r';
        b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
        b[3].Event.KeyEvent.wVirtualScanCode = 0x1c;
        b[3].Event.KeyEvent.wRepeatCount = 1;
        DWORD numb;
        WriteConsoleInput(hStdIn, b, 4, &numb);

        cliThread->wait();

        #else

        cliThread->destroy();

        #endif

        delete cliThread;
    }

    // for some unknown reason, unloading scripts here and not in worldrunnable
    // fixes a memory leak related to detaching threads from the module
    //UnloadScriptingModule();

    // Exit the process with specified return value
    return World::GetExitCode();
}
Пример #12
0
HRESULT WINAPI ObjectFromLresult( LRESULT result, REFIID riid, WPARAM wParam, void **ppObject )
{
    WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3];
    HANDLE server_proc, server_mapping, mapping;
    DWORD proc_id, size;
    IStream *stream;
    HGLOBAL data;
    void *view;
    HRESULT hr;
    WCHAR *p;

    TRACE("%ld %s %ld %p\n", result, debugstr_guid(riid), wParam, ppObject );

    if(wParam)
        FIXME("unsupported wParam = %lx\n", wParam);

    if(!ppObject)
        return E_INVALIDARG;
    *ppObject = NULL;

    if(result != (ATOM)result)
        return E_FAIL;

    if(!GlobalGetAtomNameW(result, atom_str, sizeof(atom_str)/sizeof(WCHAR)))
        return E_FAIL;
    if(memcmp(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix)))
        return E_FAIL;
    p = atom_str + sizeof(lresult_atom_prefix)/sizeof(WCHAR);
    proc_id = strtoulW(p, &p, 16);
    if(*p != ':')
        return E_FAIL;
    server_mapping = ULongToHandle( strtoulW(p+1, &p, 16) );
    if(*p != ':')
        return E_FAIL;
    size = strtoulW(p+1, &p, 16);
    if(*p != 0)
        return E_FAIL;

    server_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, proc_id);
    if(!server_proc)
        return E_FAIL;

    if(!DuplicateHandle(server_proc, server_mapping, GetCurrentProcess(), &mapping,
                0, FALSE, DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS))
        return E_FAIL;
    CloseHandle(server_proc);
    GlobalDeleteAtom(result);

    view = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
    CloseHandle(mapping);
    if(!view)
        return E_FAIL;

    data = GlobalAlloc(GMEM_FIXED, size);
    memcpy(data, view, size);
    UnmapViewOfFile(view);
    if(!data)
        return E_OUTOFMEMORY;

    hr = CreateStreamOnHGlobal(data, TRUE, &stream);
    if(FAILED(hr)) {
        GlobalFree(data);
        return hr;
    }

    hr = CoUnmarshalInterface(stream, riid, ppObject);
    IStream_Release(stream);
    return hr;
}
Пример #13
0
/// Launch the realm server
extern int main(int argc, char **argv)
{
    ///- Command line parsing
    char const* cfg_file = _REALMD_CONFIG;

    char const *options = ":c:s:";

    ACE_Get_Opt cmd_opts(argc, argv, options);
    cmd_opts.long_option("version", 'v');

    char serviceDaemonMode = '\0';

    int option;
    while ((option = cmd_opts()) != EOF)
    {
        switch (option)
        {
            case 'c':
                cfg_file = cmd_opts.opt_arg();
                break;
            case 'v':
                printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
                return 0;

            case 's':
            {
                const char *mode = cmd_opts.opt_arg();

                if (!strcmp(mode, "run"))
                    serviceDaemonMode = 'r';
#ifdef WIN32
                else if (!strcmp(mode, "install"))
                    serviceDaemonMode = 'i';
                else if (!strcmp(mode, "uninstall"))
                    serviceDaemonMode = 'u';
#else
                else if (!strcmp(mode, "stop"))
                    serviceDaemonMode = 's';
#endif
                else
                {
                    sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode);
                    usage(argv[0]);
                    Log::WaitBeforeContinueIfNeed();
                    return 1;
                }
                break;
            }
            case ':':
                sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt());
                usage(argv[0]);
                Log::WaitBeforeContinueIfNeed();
                return 1;
            default:
                sLog.outError("Runtime-Error: bad format of commandline arguments");
                usage(argv[0]);
                Log::WaitBeforeContinueIfNeed();
                return 1;
        }
    }

#ifdef WIN32                                                // windows service command need execute before config read
    switch (serviceDaemonMode)
    {
        case 'i':
            if (WinServiceInstall())
                sLog.outString("Installing service");
            return 1;
        case 'u':
            if (WinServiceUninstall())
                sLog.outString("Uninstalling service");
            return 1;
        case 'r':
            WinServiceRun();
            break;
    }
#endif

    if (!sConfig.SetSource(cfg_file))
    {
        sLog.outError("Could not find configuration file %s.", cfg_file);
        Log::WaitBeforeContinueIfNeed();
        return 1;
    }

#ifndef WIN32                                               // posix daemon commands need apply after config read
    switch (serviceDaemonMode)
    {
        case 'r':
            startDaemon();
            break;
        case 's':
            stopDaemon();
            break;
    }
#endif

    sLog.Initialize();

    sLog.outString( "%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) );
    sLog.outString( "<Ctrl-C> to stop.\n" );
    sLog.outString("Using configuration file %s.", cfg_file);

    ///- Check the version of the configuration file
    uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
    if (confVersion < _REALMDCONFVERSION)
    {
        sLog.outError("*****************************************************************************");
        sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!");
        sLog.outError("          Please check for updates, as your current default values may cause");
        sLog.outError("          strange behavior.");
        sLog.outError("*****************************************************************************");
        Log::WaitBeforeContinueIfNeed();
    }

    DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
    if (SSLeay() < 0x009080bfL )
    {
        DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!");
        DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]");
    }

    DETAIL_LOG("Using ACE: %s", ACE_VERSION);

#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
    ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true);
#else
    ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true);
#endif

    sLog.outBasic("Max allowed open files is %d", ACE::max_handles());

    /// realmd PID file creation
    std::string pidfile = sConfig.GetStringDefault("PidFile", "");
    if(!pidfile.empty())
    {
        uint32 pid = CreatePIDFile(pidfile);
        if( !pid )
        {
            sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() );
            Log::WaitBeforeContinueIfNeed();
            return 1;
        }

        sLog.outString( "Daemon PID: %u\n", pid );
    }

    ///- Initialize the database connection
    if(!StartDB())
    {
        Log::WaitBeforeContinueIfNeed();
        return 1;
    }

    ///- Get the list of realms for the server
    sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20));
    if (sRealmList.size() == 0)
    {
        sLog.outError("No valid realms specified.");
        Log::WaitBeforeContinueIfNeed();
        return 1;
    }

    // cleanup query
    // set expired bans to inactive
    LoginDatabase.BeginTransaction();
    LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
    LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
    LoginDatabase.CommitTransaction();

    ///- Launch the listening network socket
    ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor;

    uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT);
    std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0");

    ACE_INET_Addr bind_addr(rmport, bind_ip.c_str());

    if(acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
    {
        sLog.outError("MaNGOS realmd can not bind to %s:%d", bind_ip.c_str(), rmport);
        Log::WaitBeforeContinueIfNeed();
        return 1;
    }

    ///- Catch termination signals
    HookSignals();

    ///- Handle affinity for multiple processors and process priority on Windows
    #ifdef WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
        if(Aff > 0)
        {
            ULONG_PTR appAff;
            ULONG_PTR sysAff;

            if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
            {
                ULONG_PTR curAff = Aff & appAff;            // remove non accessible processors

                if(!curAff )
                {
                    sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff);
                }
                else
                {
                    if(SetProcessAffinityMask(hProcess,curAff))
                        sLog.outString("Using processors (bitmask, hex): %x", curAff);
                    else
                        sLog.outError("Can't set used processors (hex): %x", curAff);
                }
            }
            sLog.outString();
        }

        bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);

        if(Prio)
        {
            if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
                sLog.outString("realmd process priority class set to HIGH");
            else
                sLog.outError("Can't set realmd process priority class.");
            sLog.outString();
        }
    }
    #endif

    //server has started up successfully => enable async DB requests
    LoginDatabase.AllowAsyncTransactions();

    // maximum counter for next ping
    uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
    uint32 loopCounter = 0;

    #ifndef WIN32
    detachDaemon();
    #endif
    ///- Wait for termination signal
    while (!stopEvent)
    {
        // dont move this outside the loop, the reactor will modify it
        ACE_Time_Value interval(0, 100000);

        if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1)
            break;

        if( (++loopCounter) == numLoops )
        {
            loopCounter = 0;
            DETAIL_LOG("Ping MySQL to keep connection alive");
            LoginDatabase.Ping();
        }
#ifdef WIN32
        if (m_ServiceStatus == 0) stopEvent = true;
        while (m_ServiceStatus == 2) Sleep(1000);
#endif
    }

    ///- Wait for the delay thread to exit
    LoginDatabase.HaltDelayThread();

    ///- Remove signal handling before leaving
    UnhookSignals();

    sLog.outString( "Halting process..." );
    return 0;
}
Пример #14
0
// Main function
int Master::Run()
{
    int defaultStderr = dup(2);

    if (sConfig.GetBoolDefault("Console.Enable", true))
        sConsole.Initialize();
    sConsole.SetLoading(true);
    sConsole.DrawLogo();

    // worldd PID file creation
    std::string pidfile = sConfig.GetStringDefault("PidFile", "");
    if (!pidfile.empty())
    {
        uint32 pid = CreatePIDFile(pidfile);
        if (!pid)
        {
            sLog.outError("Cannot create PID file %s.\n", pidfile.c_str());
            return 1;
        }

        sLog.outString("Daemon PID: %u\n", pid);
    }

    // Start the databases
    _StartDB();

    // Initialize the World
    sWorld.SetInitialWorldSettings();

    // set realmbuilds depend on OregonCore expected builds, and set server online
    std::string builds = AcceptableClientBuildsListStr();
    LoginDatabase.escape_string(builds);
    LoginDatabase.PExecute("UPDATE realmlist SET realmflags = realmflags & ~(%u), population = 0, realmbuilds = '%s'  WHERE id = '%d'", REALM_FLAG_OFFLINE, builds.c_str(), realmID);

    sConsole.SetLoading(false);

    // Catch termination signals
    _HookSignals();

    ACE_Based::Thread* cliThread = NULL;

    #ifdef _WIN32
    if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
    #else
    if (sConfig.GetBoolDefault("Console.Enable", true))
    #endif
    {
        // Launch CliRunnable thread
        cliThread = new ACE_Based::Thread(new Console::CliRunnable);
    }

    ACE_Based::Thread rar_thread(new RARunnable);

    // Handle affinity for multiple processors and process priority on Windows
    #ifdef _WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
        if (Aff > 0)
        {
            ULONG_PTR appAff;
            ULONG_PTR sysAff;

            if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
            {
                ULONG_PTR curAff = Aff & appAff;            // remove non accessible processors

                if (!curAff)
                    sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for OregonCore. Accessible processors bitmask (hex): %x", Aff, appAff);
                else
                {
                    if (SetProcessAffinityMask(hProcess, curAff))
                        sLog.outString("Using processors (bitmask, hex): %x", curAff);
                    else
                        sLog.outError("Can't set used processors (hex): %x", curAff);
                }
            }
            sLog.outString();
        }

        bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);

        if (Prio)
        {
            if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
                sLog.outString("OregonCore process priority class set to HIGH");
            else
                sLog.outError("ERROR: Can't set OregonCore process priority class.");
            sLog.outString();
        }
    }
    #endif

    // Start soap serving thread
    ACE_Based::Thread* soap_thread = NULL;

    if (sConfig.GetBoolDefault("SOAP.Enabled", false))
    {
        OCSoapRunnable* runnable = new OCSoapRunnable();

        runnable->setListenArguments(sConfig.GetStringDefault("SOAP.IP", "127.0.0.1"), sConfig.GetIntDefault("SOAP.Port", 7878));
        soap_thread = new ACE_Based::Thread(runnable);
    }

    //uint32 socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME);

    // Start up freeze catcher thread
    ACE_Based::Thread* freeze_thread = NULL;
    if (uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0))
    {
        FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable();
        fdr->SetDelayTime(freeze_delay * 1000);
        freeze_thread = new ACE_Based::Thread(fdr);
        freeze_thread->setPriority(ACE_Based::Highest);
    }

    // Launch the world listener socket
    uint16 wsport = sWorld.getConfig(CONFIG_PORT_WORLD);
    std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0");

    if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1)
    {
        sLog.outError("Failed to start network");
        World::StopNow(ERROR_EXIT_CODE);
        // go down and shutdown the server
        // give other threads a chance to start-up so we can shutdown them safely
        ACE_Based::Thread::Sleep(1500);
    }

    /* Run our World, we use main thread for this,
       because it we need the highest priority possible */
    WorldRunnable().run();

    // Stop freeze protection before shutdown tasks
    if (freeze_thread)
    {
        freeze_thread->kill(-1); // destroy
        freeze_thread->wait();
        delete freeze_thread;
    }
    
    sWorldSocketMgr->Wait();

    // Stop soap thread
    if (soap_thread)
    {
        soap_thread->wait();
        delete soap_thread;
    }

    // Set server offline in realmlist
    LoginDatabase.PExecute("UPDATE realmlist SET realmflags = realmflags | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);

    // when the main thread closes the singletons get unloaded
    // since worldrunnable uses them, it will crash if unloaded after master
    rar_thread.wait ();

    // Clean account database before leaving
    clearOnlineAccounts();

    // Wait for delay threads to end
    CharacterDatabase.HaltDelayThread();
    WorldDatabase.HaltDelayThread();
    LoginDatabase.HaltDelayThread();

    sLog.outString("Halting process...");

    if (cliThread)
    {
        cliThread->kill(SIGINT);
        cliThread->wait();
        delete cliThread;
    }

    // we've been messing up with stderr (if Console.Enable was set),
    // so we need to restore it back, to prevent SIGPIPEs after restart
    dup2(defaultStderr, 2);
    close(defaultStderr);

    // Remove signal handling before leaving
    _UnhookSignals();

    // for some unknown reason, unloading scripts here and not in worldrunnable
    // fixes a memory leak related to detaching threads from the module
    //UnloadScriptingModule();

    // Exit the process with specified return value
    return World::GetExitCode();
}
Пример #15
0
std::string CSysInfo::GetUserAgent()
{
  static std::string result;
  if (!result.empty())
    return result;

  result = GetAppName() + "/" + (std::string)g_infoManager.GetLabel(SYSTEM_BUILD_VERSION_SHORT) + " (";
#if defined(TARGET_WINDOWS)
  result += GetKernelName() + " " + GetKernelVersion();
  BOOL bIsWow = FALSE;
  if (IsWow64Process(GetCurrentProcess(), &bIsWow) && bIsWow)
      result.append("; WOW64");
  else
  {
    SYSTEM_INFO si = {};
    GetSystemInfo(&si);
    if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
      result.append("; Win64; x64");
    else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
      result.append("; Win64; IA64");
    else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM)
      result.append("; ARM");
  }
#elif defined(TARGET_DARWIN)
#if defined(TARGET_DARWIN_IOS)
  std::string iDevStr(GetModelName()); // device model name with number of model version
  size_t iDevStrDigit = iDevStr.find_first_of("0123456789");
  std::string iDev(iDevStr, 0, iDevStrDigit);  // device model name without number 
  if (iDevStrDigit == 0)
    iDev = "unknown";
  result += iDev + "; ";
  std::string iOSVerison(GetOsVersion());
  size_t lastDotPos = iOSVerison.rfind('.');
  if (lastDotPos != std::string::npos && iOSVerison.find('.') != lastDotPos
      && iOSVerison.find_first_not_of('0', lastDotPos + 1) == std::string::npos)
    iOSVerison.erase(lastDotPos);
  StringUtils::Replace(iOSVerison, '.', '_');
  if (iDev == "iPad" || iDev == "AppleTV")
    result += "CPU OS ";
  else
    result += "CPU iPhone OS ";
  result += iOSVerison + " like Mac OS X";
#else
  result += "Macintosh; ";
  std::string cpuFam(GetBuildTargetCpuFamily());
  if (cpuFam == "x86")
    result += "Intel ";
  else if (cpuFam == "PowerPC")
    result += "PPC ";
  result += "Mac OS X ";
  std::string OSXVersion(GetOsVersion());
  StringUtils::Replace(OSXVersion, '.', '_');
  result += OSXVersion;
#endif
#elif defined(TARGET_ANDROID)
  result += "Linux; Android ";
  std::string versionStr(GetOsVersion());
  const size_t verLen = versionStr.length();
  if (verLen >= 2 && versionStr.compare(verLen - 2, 2, ".0", 2) == 0)
    versionStr.erase(verLen - 2); // remove last ".0" if any
  result += versionStr;
  std::string deviceInfo(GetModelName());

  char buildId[PROP_VALUE_MAX];
  int propLen = __system_property_get("ro.build.id", buildId);
  if (propLen > 0 && propLen <= PROP_VALUE_MAX)
  {
    if (!deviceInfo.empty())
      deviceInfo += " ";
    deviceInfo += "Build/";
    deviceInfo.append(buildId, propLen);
  }

  if (!deviceInfo.empty())
    result += "; " + deviceInfo;
#elif defined(TARGET_POSIX)
  result += "X11; ";
  struct utsname un;
  if (uname(&un) == 0)
  {
    std::string cpuStr(un.machine);
    if (cpuStr == "x86_64" && GetXbmcBitness() == 32)
      cpuStr = "i686 (x86_64)";
    result += un.sysname;
    result += " ";
    result += cpuStr;
  }
  else
    result += "Unknown";
#else
  result += "Unknown";
#endif
  result += ")";

  if (GetAppName() != "Kodi")
    result += " Kodi_Fork_" + GetAppName() + "/1.0"; // default fork number is '1.0', replace it with actual number if necessary

#ifdef TARGET_LINUX
  // Add distribution name
  std::string linuxOSName(GetOsName(true));
  if (!linuxOSName.empty())
    result += " " + linuxOSName + "/" + GetOsVersion();
#endif

#ifdef TARGET_RASPBERRY_PI
  result += " HW_RaspberryPi/1.0";
#elif defined (TARGET_DARWIN_IOS)
  std::string iDevVer;
  if (iDevStrDigit == std::string::npos)
    iDevVer = "0.0";
  else
    iDevVer.assign(iDevStr, iDevStrDigit, std::string::npos);
  StringUtils::Replace(iDevVer, ',', '.');
  result += " HW_" + iDev + "/" + iDevVer;
#endif
  // add more device IDs here if needed. 
  // keep only one device ID in result! Form:
  // result += " HW_" + "deviceID" + "/" + "1.0"; // '1.0' if device has no version

#if defined(TARGET_ANDROID)
  // Android has no CPU string by default, so add it as additional parameter
  struct utsname un1;
  if (uname(&un1) == 0)
  {
    std::string cpuStr(un1.machine);
    StringUtils::Replace(cpuStr, ' ', '_');
    result += " Sys_CPU/" + cpuStr;
  }
#endif

  result += " App_Bitness/" + StringUtils::Format("%d", GetXbmcBitness());

  std::string fullVer(g_infoManager.GetLabel(SYSTEM_BUILD_VERSION));
  StringUtils::Replace(fullVer, ' ', '-');
  result += " Version/" + fullVer;

  return result;
}
Пример #16
0
VOID HookInlineChecks(BOOL Patch)
{
    int i;
    DWORD NewData;
#ifndef ISXEQ
    DWORD tmp;
    DWORD oldperm;
#endif

    int cmps[] = { __AC1 + 6 };

    int cmps2[] = { __AC2,
                    __AC3,
                    __AC4,
                    __AC5,
                    __AC6,
                    __AC7 };

    int len2[] = { 6, 6, 6, 6, 6, 6 }; 

    char NewData2[20];

    static char OldData2[sizeof(cmps2)/sizeof(cmps2[0])][20];

    if (Patch)
    {
        NewData = 0x7fffffff;

        for (i=0;i<sizeof(cmps)/sizeof(cmps[0]);i++) {
#ifdef ISXEQ
            EzModify(cmps[i],&NewData,4);
#else
            AddDetour(cmps[i], NULL, NULL, 4);
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps[i], 4, PAGE_EXECUTE_READWRITE, &oldperm);
            WriteProcessMemory(GetCurrentProcess(), (LPVOID)cmps[i], (LPVOID)&NewData, 4, NULL);
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps[i], 4, oldperm, &tmp);
#endif
        }

        memset(NewData2, 0x90, 20);

        for (i=0;i<sizeof(cmps2)/sizeof(cmps2[0]);i++) {
#ifdef ISXEQ
            EzModify(cmps2[i],NewData2,len2[i]);
#else
            AddDetour(cmps2[i], NULL, NULL, len2[i]);
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps2[i], len2[i], PAGE_EXECUTE_READWRITE, &oldperm);
            memcpy((void *)OldData2[i], (void *)cmps2[i], len2[i]);
            WriteProcessMemory(GetCurrentProcess(), (LPVOID)cmps2[i], (LPVOID)NewData2, len2[i], NULL);
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps2[i], len2[i], oldperm, &tmp);
#endif
        }
    }
    else
    {
        NewData = __AC1_Data;

        for (i=0;i<sizeof(cmps)/sizeof(cmps[0]);i++) {
#ifdef ISXEQ
            EzUnModify(cmps[i]);
#else
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps[i], 4, PAGE_EXECUTE_READWRITE, &oldperm);
            WriteProcessMemory(GetCurrentProcess(), (LPVOID)cmps[i], (LPVOID)&NewData, 4, NULL);
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps[i], 4, oldperm, &tmp);
            RemoveDetour(cmps[i]);
#endif
        }

        for (i=0;i<sizeof(cmps2)/sizeof(cmps2[0]);i++) {
#ifdef ISXEQ
            EzUnModify(cmps2[i]);
#else
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps2[i], len2[i], PAGE_EXECUTE_READWRITE, &oldperm);
            WriteProcessMemory(GetCurrentProcess(), (LPVOID)cmps2[i], (LPVOID)OldData2[i], len2[i], NULL);
            VirtualProtectEx(GetCurrentProcess(), (LPVOID)cmps2[i], len2[i], oldperm, &tmp);
            RemoveDetour(cmps2[i]);
#endif
        }
    }
}
Пример #17
0
//  Called from MyApp() immediately upon entry to MyApp::OnInit()
void OCPNPlatform::Initialize_1( void )
{
    
#ifdef OCPN_USE_CRASHRPT
#ifndef _DEBUG
    // Install Windows crash reporting
    
    CR_INSTALL_INFO info;
    memset(&info, 0, sizeof(CR_INSTALL_INFO));
    info.cb = sizeof(CR_INSTALL_INFO);
    info.pszAppName = _T("OpenCPN");
    
    wxString version_crash = str_version_major + _T(".") + str_version_minor + _T(".") + str_version_patch;
    info.pszAppVersion = version_crash.c_str();
    
    int type = MiniDumpWithDataSegs;  // Include the data sections from all loaded modules.
    // This results in the inclusion of global variables
    
    type |=  MiniDumpNormal;// | MiniDumpWithPrivateReadWriteMemory | MiniDumpWithIndirectlyReferencedMemory;
    info.uMiniDumpType = (MINIDUMP_TYPE)type;
    
    // Install all available exception handlers....
    info.dwFlags = CR_INST_ALL_POSSIBLE_HANDLERS;
    
    //  Except memory allocation failures
    info.dwFlags &= ~CR_INST_NEW_OPERATOR_ERROR_HANDLER;
    
    //  Allow user to attach files
    info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES;
    
    //  Allow user to add more info
    info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS;
    
    
    // URL for sending error reports over HTTP.
    if(g_bEmailCrashReport){
        info.pszEmailTo = _T("*****@*****.**");
        info.pszSmtpProxy = _T("mail.bigdumboat.com:587");
        info.pszUrl = _T("http://bigdumboat.com/crashrpt/ocpn_crashrpt.php");
        info.uPriorities[CR_HTTP] = 1;  // First try send report over HTTP
    }
    else{
        info.dwFlags |= CR_INST_DONT_SEND_REPORT;
        info.uPriorities[CR_HTTP] = CR_NEGATIVE_PRIORITY;       // don't send at all
    }
    
    info.uPriorities[CR_SMTP] = CR_NEGATIVE_PRIORITY;  // Second try send report over SMTP
    info.uPriorities[CR_SMAPI] = CR_NEGATIVE_PRIORITY; //1; // Third try send report over Simple MAPI
    
    wxStandardPaths& crash_std_path = g_Platform->GetStdPaths();
    
    wxString crash_rpt_save_locn = crash_std_path.GetConfigDir();
    if( g_bportable ) {
        wxFileName exec_path_crash( crash_std_path.GetExecutablePath() );
        crash_rpt_save_locn = exec_path_crash.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
    }
    
    wxString locn = crash_rpt_save_locn + _T("\\CrashReports");
    
    if(!wxDirExists( locn ) )
        wxMkdir( locn );
    
    if(wxDirExists( locn ) ){
        wxCharBuffer buf = locn.ToUTF8();
        wchar_t wlocn[256];
        if(buf && (locn.Length() < sizeof(wlocn)) ){
            MultiByteToWideChar( 0, 0, buf.data(), -1, wlocn, sizeof(wlocn)-1);
            info.pszErrorReportSaveDir = (LPCWSTR)wlocn;
        }
    }
    
    // Provide privacy policy URL
    wxFileName exec_path_crash( crash_std_path.GetExecutablePath() );
    wxString policy_file =  exec_path_crash.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
    policy_file += _T("PrivacyPolicy.txt");
    policy_file.Prepend(_T("file:"));
    
    info.pszPrivacyPolicyURL = policy_file.c_str();;
    
    int nResult = crInstall(&info);
    if(nResult!=0) {
        TCHAR buff[256];
        crGetLastErrorMsg(buff, 256);
        MessageBox(NULL, buff, _T("crInstall error, Crash Reporting disabled."), MB_OK);
    }
    
    // Establish the crash callback function
    crSetCrashCallback( CrashCallback, NULL );
    
    // Take screenshot of the app window at the moment of crash
    crAddScreenshot2(CR_AS_PROCESS_WINDOWS|CR_AS_USE_JPEG_FORMAT, 95);
    
    //  Mark some files to add to the crash report
    wxString home_data_crash = crash_std_path.GetConfigDir();
    if( g_bportable ) {
        wxFileName f( crash_std_path.GetExecutablePath() );
        home_data_crash = f.GetPath();
    }
    appendOSDirSlash( &home_data_crash );
    
    wxString config_crash = _T("opencpn.ini");
    config_crash.Prepend( home_data_crash );
    crAddFile2( config_crash.c_str(), NULL, NULL, CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE );
    
    wxString log_crash = _T("opencpn.log");
    log_crash.Prepend( home_data_crash );
    crAddFile2( log_crash.c_str(), NULL, NULL, CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE );
    
#endif
#endif

    
#ifdef LINUX_CRASHRPT
#if wxUSE_ON_FATAL_EXCEPTION
    // fatal exceptions handling
    wxHandleFatalExceptions (true);
#endif
#endif

#ifdef __WXMSW__
    //  Invoke my own handler for failures of malloc/new
    _set_new_handler( MyNewHandler );
    //  configure malloc to call the New failure handler on failure
    _set_new_mode(1);
#endif    
    
    //    On MSW, force the entire process to run on one CPU core only
    //    This resolves some difficulty with wxThread syncronization
#if 0
#ifdef __WXMSW__
    //Gets the current process handle
    HANDLE hProc = GetCurrentProcess();
    DWORD procMask;
    DWORD sysMask;
    HANDLE hDup;
    DuplicateHandle( hProc, hProc, hProc, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
    
    //Gets the current process affinity mask
    GetProcessAffinityMask( hDup, &procMask, &sysMask );
    
    // Take a simple approach, and assume up to 4 processors
    DWORD newMask;
    if( ( procMask & 1 ) == 1 ) newMask = 1;
    else
        if( ( procMask & 2 ) == 2 ) newMask = 2;
        else
            if( ( procMask & 4 ) == 4 ) newMask = 4;
            else
                if( ( procMask & 8 ) == 8 ) newMask = 8;
                
                //Set te affinity mask for the process
                BOOL res = SetProcessAffinityMask( hDup, (DWORD_PTR) newMask );
            
            if( res == 0 ) {
                //Error setting affinity mask!!
            }
#endif
#endif
            
#ifdef __WXMSW__
            
            //    Handle any Floating Point Exceptions which may leak thru from other
            //    processes.  The exception filter is in cutil.c
            //    Seems to only happen for W98
            
            wxPlatformInfo Platform;
            if( Platform.GetOperatingSystemId() == wxOS_WINDOWS_9X ) SetUnhandledExceptionFilter (&MyUnhandledExceptionFilter);
#endif
            
#ifdef __WXMSW__
            //     _CrtSetBreakAlloc(25503);
#endif
            

#ifndef __WXMSW__
            //      Setup Linux SIGNAL handling, for external program control
            
            //      Build the sigaction structure
            sa_all.sa_handler = catch_signals;// point to my handler
            sigemptyset(&sa_all.sa_mask);// make the blocking set
            // empty, so that all
            // other signals will be
            // unblocked during my handler
            sa_all.sa_flags = 0;
            
            sigaction(SIGUSR1, NULL, &sa_all_old);// save existing action for this signal
            
            //      Register my request for some signals
            sigaction(SIGUSR1, &sa_all, NULL);
            
            sigaction(SIGUSR1, NULL, &sa_all_old);// inspect existing action for this signal
            
            sigaction(SIGTERM, &sa_all, NULL);
            sigaction(SIGTERM, NULL, &sa_all_old);
#endif

#ifdef __OCPN__ANDROID__
    androidUtilInit( );
#endif            
            
}
Пример #18
0
bool Master::Run()
{
    sLog.outString( "MaNGOS daemon %s", _FULLVERSION );
    sLog.outString( "<Ctrl-C> to stop.\n\n" );

    sLog.outTitle( "MM   MM         MM   MM  MMMMM   MMMM   MMMMM");
    sLog.outTitle( "MM   MM         MM   MM MMM MMM MM  MM MMM MMM");
    sLog.outTitle( "MMM MMM         MMM  MM MMM MMM MM  MM MMM");
    sLog.outTitle( "MM M MM         MMMM MM MMM     MM  MM  MMM");
    sLog.outTitle( "MM M MM  MMMMM  MM MMMM MMM     MM  MM   MMM");
    sLog.outTitle( "MM M MM M   MMM MM  MMM MMMMMMM MM  MM    MMM");
    sLog.outTitle( "MM   MM     MMM MM   MM MM  MMM MM  MM     MMM");
    sLog.outTitle( "MM   MM MMMMMMM MM   MM MMM MMM MM  MM MMM MMM");
    sLog.outTitle( "MM   MM MM  MMM MM   MM  MMMMMM  MMMM   MMMMM");
    sLog.outTitle( "        MM  MMM http://www.mangosproject.org");
    sLog.outTitle( "        MMMMMM\n\n");

    _StartDB();

    //loglevel = (uint8)sConfig.GetIntDefault("LogLevel", DEFAULT_LOG_LEVEL);

    sWorld.SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT) );
    sWorld.SetMotd( sConfig.GetStringDefault("Motd", "Welcome to the Massive Network Game Object Server." ).c_str() );
    sWorld.SetInitialWorldSettings();

    port_t wsport, rmport;
    rmport = sWorld.getConfig(CONFIG_PORT_REALM);           //sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
    wsport = sWorld.getConfig(CONFIG_PORT_WORLD);           //sConfig.GetIntDefault( "WorldServerPort", DEFAULT_WORLDSERVER_PORT );

    uint32 socketSelecttime;
                                                            //sConfig.GetIntDefault( "SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME );
    socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME);

    //uint32 grid_clean_up_delay = sConfig.GetIntDefault("GridCleanUpDelay", 300);
    //sLog.outDebug("Setting Grid clean up delay to %d seconds.", grid_clean_up_delay);
    //grid_clean_up_delay *= 1000;
    //MapManager::Instance().SetGridCleanUpDelay(grid_clean_up_delay);

    //uint32 map_update_interval = sConfig.GetIntDefault("MapUpdateInterval", 100);
    //sLog.outDebug("Setting map update interval to %d milli-seconds.", map_update_interval);
    //MapManager::Instance().SetMapUpdateInterval(map_update_interval);

    //    sRealmList.setServerPort(wsport);
    //    sRealmList.GetAndAddRealms ();
    SocketHandler h;
    ListenSocket<WorldSocket> worldListenSocket(h);
    //    ListenSocket<AuthSocket> authListenSocket(h);

    if (worldListenSocket.Bind(wsport))
    {
        _StopDB();
        sLog.outString( "MaNGOS can not bind to that port" );
        exit(1);
    }

    h.Add(&worldListenSocket);
    //    h.Add(&authListenSocket);

    _HookSignals();

    ZThread::Thread t(new WorldRunnable);

    //#ifndef WIN32
    t.setPriority ((ZThread::Priority )2);
    //#endif

    #ifdef ENABLE_CLI
    ZThread::Thread td1(new CliRunnable);
    #endif

    #ifdef ENABLE_RA

    ListenSocket<RASocket> RAListenSocket(h);

    if (RAListenSocket.Bind(sConfig.GetIntDefault( "RA.Port", 3443 )))
    {

        sLog.outString( "MaNGOS can not bind to that port" );
        // exit(1); go on with no RA

    }

    h.Add(&RAListenSocket);
    #endif

    #ifdef WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
        if(Aff > 0)
        {
            uint32 appAff;
            uint32 sysAff;

            if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
            {
                uint32 curAff = Aff & appAff;               // remove non accassable processors

                if(!curAff )
                {
                    sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessable for mangosd. Accessable processors bitmask (hex): %x",Aff,appAff);
                }
                else
                {
                    if(SetProcessAffinityMask(hProcess,curAff))
                        sLog.outString("Using processors (bitmask, hex): %x", curAff);
                    else
                        sLog.outError("Can't set used processors (hex): %x",curAff);
                }
            }
            sLog.outString("");
        }

        uint32 Prio = sConfig.GetIntDefault("ProcessPriority", 0);

        if(Prio)
        {
            if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
                sLog.outString("mangosd process priority class set to HIGH");
            else
                sLog.outError("ERROR: Can't set mangosd process priority class.");
            sLog.outString("");
        }
    }
    #endif

    uint32 realCurrTime, realPrevTime;
    realCurrTime = realPrevTime = getMSTime();
    while (!World::m_stopEvent)
    {

        if (realPrevTime > realCurrTime)
            realPrevTime = 0;

        realCurrTime = getMSTime();
        sWorldSocketMgr.Update( realCurrTime - realPrevTime );
        realPrevTime = realCurrTime;

        //h.Select(0, 100000);
        h.Select(0, socketSelecttime);
    }

    sLog.outString( "WORLD: Saving Addons" );
    sAddOnHandler._SaveToDB();

    _UnhookSignals();

    t.wait();

    _StopDB();

    sLog.outString( "Halting process..." );

    return 0;
}
/*
 * Create a restricted token and execute the specified process with it.
 *
 * Returns restricted token on success and 0 on failure.
 *
 * On NT4, or any other system not containing the required functions, will
 * NOT execute anything.
 */
HANDLE
CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char *progname)
{
	BOOL		b;
	STARTUPINFO si;
	HANDLE		origToken;
	HANDLE		restrictedToken;
	SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
	SID_AND_ATTRIBUTES dropSids[2];
	__CreateRestrictedToken _CreateRestrictedToken = NULL;
	HANDLE		Advapi32Handle;

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);

	Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
	if (Advapi32Handle != NULL)
	{
		_CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
	}

	if (_CreateRestrictedToken == NULL)
	{
		fprintf(stderr, _("%s: WARNING: cannot create restricted tokens on this platform\n"), progname);
		if (Advapi32Handle != NULL)
			FreeLibrary(Advapi32Handle);
		return 0;
	}

	/* Open the current token to use as a base for the restricted one */
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
	{
		fprintf(stderr, _("%s: could not open process token: error code %lu\n"), progname, GetLastError());
		return 0;
	}

	/* Allocate list of SIDs to remove */
	ZeroMemory(&dropSids, sizeof(dropSids));
	if (!AllocateAndInitializeSid(&NtAuthority, 2,
		 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
								  0, &dropSids[0].Sid) ||
		!AllocateAndInitializeSid(&NtAuthority, 2,
	SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
								  0, &dropSids[1].Sid))
	{
		fprintf(stderr, _("%s: could not allocate SIDs: error code %lu\n"),
				progname, GetLastError());
		return 0;
	}

	b = _CreateRestrictedToken(origToken,
							   DISABLE_MAX_PRIVILEGE,
							   sizeof(dropSids) / sizeof(dropSids[0]),
							   dropSids,
							   0, NULL,
							   0, NULL,
							   &restrictedToken);

	FreeSid(dropSids[1].Sid);
	FreeSid(dropSids[0].Sid);
	CloseHandle(origToken);
	FreeLibrary(Advapi32Handle);

	if (!b)
	{
		fprintf(stderr, _("%s: could not create restricted token: error code %lu\n"),
				progname, GetLastError());
		return 0;
	}

#ifndef __CYGWIN__
	AddUserToTokenDacl(restrictedToken);
#endif

	if (!CreateProcessAsUser(restrictedToken,
							 NULL,
							 cmd,
							 NULL,
							 NULL,
							 TRUE,
							 CREATE_SUSPENDED,
							 NULL,
							 NULL,
							 &si,
							 processInfo))

	{
		fprintf(stderr, _("%s: could not start process for command \"%s\": error code %lu\n"), progname, cmd, GetLastError());
		return 0;
	}

	ResumeThread(processInfo->hThread);
	return restrictedToken;
}
Пример #20
0
void RefreshWindowList(HWND hwndCombobox, StringList &classList)
{
    SendMessage(hwndCombobox, CB_RESETCONTENT, 0, 0);
    classList.Clear();

    BOOL bCurrentProcessIsWow64 = FALSE;
    IsWow64Process(GetCurrentProcess(), &bCurrentProcessIsWow64);

    HWND hwndCurrent = GetWindow(GetDesktopWindow(), GW_CHILD);
    do
    {
        if(IsWindowVisible(hwndCurrent))
        {
            RECT clientRect;
            GetClientRect(hwndCurrent, &clientRect);

            HWND hwndParent = GetParent(hwndCurrent);

            DWORD exStyles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_EXSTYLE);
            DWORD styles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_STYLE);


            if( (exStyles & WS_EX_TOOLWINDOW) == 0 && (styles & WS_CHILD) == 0 && hwndParent == NULL)
            {
                String strWindowName;
                strWindowName.SetLength(GetWindowTextLength(hwndCurrent));
                GetWindowText(hwndCurrent, strWindowName, strWindowName.Length()+1);

                //-------

                DWORD processID;
                GetWindowThreadProcessId(hwndCurrent, &processID);
                if(processID == GetCurrentProcessId())
                    continue;

                TCHAR fileName[MAX_PATH+1];
                scpy(fileName, TEXT("unknown"));

                HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID);
                if(hProcess)
                {
                    BOOL bTargetProcessIsWow64 = FALSE;
                    IsWow64Process(hProcess, &bTargetProcessIsWow64);

                    DWORD dwSize = MAX_PATH;
                    QueryFullProcessImageName(hProcess, 0, fileName, &dwSize);
                    CloseHandle(hProcess);

                    if(bCurrentProcessIsWow64 != bTargetProcessIsWow64)
                        continue;
                }

                //-------

                String strFileName = fileName;
                strFileName.FindReplace(TEXT("\\"), TEXT("/"));

                String strText;
                strText << TEXT("[") << GetPathFileName(strFileName) << TEXT("]: ") << strWindowName;

                int id = (int)SendMessage(hwndCombobox, CB_ADDSTRING, 0, (LPARAM)strWindowName.Array());
                SendMessage(hwndCombobox, CB_SETITEMDATA, id, (LPARAM)hwndCurrent);

                String strClassName;
                strClassName.SetLength(256);
                GetClassName(hwndCurrent, strClassName.Array(), 255);
                strClassName.SetLength(slen(strClassName));

                classList << strClassName;
            }
        }
    } while (hwndCurrent = GetNextWindow(hwndCurrent, GW_HWNDNEXT));
}
Пример #21
0
int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
                            DWORD owner_rights, DWORD everyone_rights)
{
  /* Top-level SID authority */
  SID_IDENTIFIER_AUTHORITY world_auth= SECURITY_WORLD_SID_AUTHORITY;
  PSID everyone_sid= 0;
  HANDLE htoken= 0;
  SECURITY_ATTRIBUTES *sa= 0;
  PACL dacl= 0;
  DWORD owner_token_length, dacl_length;
  SECURITY_DESCRIPTOR *sd;
  PTOKEN_USER owner_token;
  PSID owner_sid;
  My_security_attr *attr;

  if (! is_nt())
  {
    *psa= 0;
    return 0;
  }

  /*
    Get SID of Everyone group. Easier to retrieve all SIDs each time
    this function is called than worry about thread safety.
  */
  if (! AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
                                 0, 0, 0, 0, 0, 0, 0, &everyone_sid))
  {
    *perror= "Failed to retrieve the SID of Everyone group";
    goto error;
  }

  /*
    Get SID of the owner. Using GetSecurityInfo this task can be done
    in just one call instead of five, but GetSecurityInfo declared in
    aclapi.h, so I hesitate to use it.
    SIC: OpenThreadToken works only if there is an active impersonation
    token, hence OpenProcessToken is used.
  */
  if (! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken))
  {
    *perror= "Failed to retrieve thread access token";
    goto error;
  }
  GetTokenInformation(htoken, TokenUser, 0, 0, &owner_token_length);

  if (! my_multi_malloc(MYF(MY_WME),
                        &sa, ALIGN_SIZE(sizeof(SECURITY_ATTRIBUTES)) +
                             sizeof(My_security_attr),
                        &sd, sizeof(SECURITY_DESCRIPTOR),
                        &owner_token, owner_token_length,
                        0))
  {
    *perror= "Failed to allocate memory for SECURITY_ATTRIBUTES";
    goto error;
  }
  bzero(owner_token, owner_token_length);
  if (! GetTokenInformation(htoken, TokenUser, owner_token,
                            owner_token_length, &owner_token_length))
  {
    *perror= "GetTokenInformation failed";
    goto error;
  }
  owner_sid= owner_token->User.Sid;

  if (! IsValidSid(owner_sid))
  {
    *perror= "IsValidSid failed";
    goto error;
  }

  /* Calculate the amount of memory that must be allocated for the DACL */
  dacl_length= sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)) * 2 +
               GetLengthSid(everyone_sid) + GetLengthSid(owner_sid);

  /* Create an ACL */
  if (! (dacl= (PACL) my_malloc(dacl_length, MYF(MY_ZEROFILL|MY_WME))))
  {
    *perror= "Failed to allocate memory for DACL";
    goto error;
  }
  if (! InitializeAcl(dacl, dacl_length, ACL_REVISION))
  {
    *perror= "Failed to initialize DACL";
    goto error;
  }
  if (! AddAccessAllowedAce(dacl, ACL_REVISION, everyone_rights, everyone_sid))
  {
    *perror= "Failed to set up DACL";
    goto error;
  }
  if (! AddAccessAllowedAce(dacl, ACL_REVISION, owner_rights, owner_sid))
  {
    *perror= "Failed to set up DACL";
    goto error;
  }
  if (! InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION))
  {
    *perror= "Could not initialize security descriptor";
    goto error;
  }
  if (! SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE))
  {
    *perror= "Failed to install DACL";
    goto error;
  }

  sa->nLength= sizeof(*sa);
  sa->bInheritHandle= TRUE;
  sa->lpSecurityDescriptor= sd;
  /* Save pointers to everyone_sid and dacl to be able to clean them up */
  attr= (My_security_attr*) (((char*) sa) + ALIGN_SIZE(sizeof(*sa)));
  attr->everyone_sid= everyone_sid;
  attr->dacl= dacl;
  *psa= sa;

  CloseHandle(htoken);
  return 0;
error:
  if (everyone_sid)
    FreeSid(everyone_sid);
  if (htoken)
    CloseHandle(htoken);
  my_free(sa);
  my_free(dacl);
  *psa= 0;
  return 1;
}
Пример #22
0
/*
 * Background thread to check for updates
 */
static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
{
	BOOL releases_only, found_new_version = FALSE;
	int status = 0;
	const char* server_url = RUFUS_URL "/";
	int i, j, k, verbose = 0, verpos[4];
	static const char* archname[] = {"win_x86", "win_x64"};
	static const char* channel[] = {"release", "beta"};		// release channel
	DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
	char* buf = NULL;
	char agent[64], hostname[64], urlpath[128], mime[32];
	OSVERSIONINFOA os_version = {sizeof(OSVERSIONINFOA), 0, 0, 0, 0, ""};
	HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL;
	URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0,
		hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1};
	SYSTEMTIME ServerTime, LocalTime;
	FILETIME FileTime;
	int64_t local_time = 0, reg_time, server_time, update_interval;
	BOOL is_x64 = FALSE, (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL;

	update_check_in_progress = TRUE;
	verbose = ReadRegistryKey32(REGKEY_HKCU, REGKEY_VERBOSE_UPDATES);
	// Unless the update was forced, wait a while before performing the update check
	if (!force_update_check) {
		// TODO: Also check on inactivity
		// It would of course be a lot nicer to use a timer and wake the thread, but my
		// development time is limited and this is FASTER to implement.
		do {
			for (i=0; (i<30) && (!force_update_check); i++)
				Sleep(500);
		} while ((!force_update_check) && ((iso_op_in_progress || format_op_in_progress || (dialog_showing>0))));
		if (!force_update_check) {
			if ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1)) {
				vuprintf("Check for updates disabled, as per registry settings.\n");
				goto out;
			}
			reg_time = ReadRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE);
			update_interval = (int64_t)ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL);
			if (update_interval == 0) {
				WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL);
				update_interval = DEFAULT_UPDATE_INTERVAL;
			}
			GetSystemTime(&LocalTime);
			if (!SystemTimeToFileTime(&LocalTime, &FileTime))
				goto out;
			local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000;
			vvuprintf("Local time: %" PRId64 "\n", local_time);
			if (local_time < reg_time + update_interval) {
				vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time);
				goto out;
			}
		}
	}

	PrintStatus(3000, TRUE, "Checking for " APPLICATION_NAME " updates...\n");
	status++;	// 1

	if (!GetVersionExA(&os_version)) {
		uprintf("Could not read Windows version - Check for updates cancelled.\n");
		goto out;
	}

	// Detect if the OS is 64 bit, without relying on external libs
	if (sizeof(uintptr_t) < 8) {
		// This application is not 64 bit, but it might be 32 bit running in WOW64
		pIsWow64Process = (BOOL (__stdcall *)(HANDLE, PBOOL))
			GetProcAddress(GetModuleHandleA("KERNEL32"), "IsWow64Process");
		if (pIsWow64Process != NULL) {
			(*pIsWow64Process)(GetCurrentProcess(), &is_x64);
		}
	} else {
		is_x64 = TRUE;
	}

	if ((!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) || (!InternetGetConnectedState(&dwFlags, 0)))
		goto out;
	hostname[sizeof(hostname)-1] = 0;

	safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
	hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (hSession == NULL)
		goto out;
	hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL);
	if (hConnection == NULL)
		goto out;

	status++;	// 2
	releases_only = !GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS);

	for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) {
		uprintf("Checking %s channel...\n", channel[k]);
		// At this stage we can query the server for various update version files.
		// We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver"
		// and then remove each each of the <os_> components until we find our match. For instance, we may first
		// look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later)
		// This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups.
		safe_sprintf(urlpath, sizeof(urlpath), "%s%s%s_%s_%d.%d.ver", APPLICATION_NAME, (k==0)?"":"_",
			(k==0)?"":channel[k], archname[is_x64?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion);
		vuprintf("Base update check: %s\n", urlpath);
		for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) {
			if ((urlpath[j] == '.') || (urlpath[j] == '_')) {
				verpos[i++] = j;
			}
		}
		if (i != ARRAYSIZE(verpos)) {
			uprintf("Broken code in CheckForUpdatesThread()!\n");
			goto out;
		}

		UrlParts.lpszUrlPath = urlpath;
		UrlParts.dwUrlPathLength = sizeof(urlpath);
		for (i=0; i<ARRAYSIZE(verpos); i++) {
			vvuprintf("Trying %s\n", UrlParts.lpszUrlPath);
			hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, (const char**)"*/*\0",
				INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES|
				INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL);
			if ((hRequest == NULL) || (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)))
				goto out;

			// Ensure that we get a text file
			dwSize = sizeof(dwStatus);
			dwStatus = 404;
			HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL);
			if (dwStatus == 200) 
				break;
			InternetCloseHandle(hRequest);
			hRequest = NULL;
			safe_strcpy(&urlpath[verpos[i]], 5, ".ver");
		}
		if (dwStatus != 200) {
			vuprintf("Could not find a %s version file on server %s", channel[k], server_url);
			if ((releases_only) || (k+1 >= ARRAYSIZE(channel)))
				goto out;
			continue;
		}
		vuprintf("Found match for %s on server %s.", urlpath, server_url);

		dwSize = sizeof(mime);
		HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL);
		if (strcmp(mime, "text/plain") != 0)
			goto out;

		// We also get a date from Apache, which we'll use to avoid out of sync check,
		// in case some set their clock way into the future and back.
		// On the other hand, if local clock is set way back in the past, we will never check.
		dwSize = sizeof(ServerTime);
		// If we can't get a date we can trust, don't bother...
		if ( (!HttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL))
			|| (!SystemTimeToFileTime(&ServerTime, &FileTime)) )
			goto out;
		server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000;
		vvuprintf("Server time: %" PRId64 "\n", server_time);
		// Always store the server response time - the only clock we trust!
		WriteRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE, server_time);
		// Might as well let the user know
		if (!force_update_check) {
			if (local_time > server_time + 600) {
				uprintf("Your local clock appears more than 10 minutes early - You ought to fix that...\n");
			}
			if (local_time < server_time - 600) {
				uprintf("Your local clock appears more than 10 minutes late - you ought to fix that...\n");
			}
		}

		dwSize = sizeof(dwTotalSize);
		if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL))
			goto out;

		safe_free(buf);
		// Make sure the file is NUL terminated
		buf = (char*)calloc(dwTotalSize+1, 1);
		if (buf == NULL) goto out;
		// This is a version file - we should be able to gulp it down in one go
		if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize))
			goto out;

		status++;
		vuprintf("Successfully downloaded version file (%d bytes)\n", dwTotalSize);

		parse_update(buf, dwTotalSize+1);

		vuprintf("UPDATE DATA:\n");
		vuprintf("  version: %d.%d.%d.%d (%s)\n", update.version[0], update.version[1], 
			update.version[2], update.version[3], channel[k]);
		vuprintf("  platform_min: %d.%d\n", update.platform_min[0], update.platform_min[1]);
		vuprintf("  url: %s\n", update.download_url);

		found_new_version = (to_uint64_t(update.version) > to_uint64_t(rufus_version))
			&& ( (os_version.dwMajorVersion > update.platform_min[0])
			  || ( (os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1])) );
		uprintf("N%sew %s version found%c\n", found_new_version?"":"o n", channel[k], found_new_version?'!':'.');
	}

out:
	safe_free(buf);
	if (hRequest) InternetCloseHandle(hRequest);
	if (hConnection) InternetCloseHandle(hConnection);
	if (hSession) InternetCloseHandle(hSession);
	switch(status) {
	case 1:
		PrintStatus(3000, TRUE, "Updates: Unable to connect to the internet.\n");
		break;
	case 2:
		PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n");
		break;
	case 3:
	case 4:
		PrintStatus(3000, FALSE, "%s new version of " APPLICATION_NAME " %s\n",
		found_new_version?"A":"No", found_new_version?"is available!":"was found.");
	default:
		break;
	}
	// Start the new download after cleanup
	if (found_new_version) {
		// User may have started an operation while we were checking
		while ((!force_update_check) && (iso_op_in_progress || format_op_in_progress || (dialog_showing>0))) {
			Sleep(15000);
		}
		DownloadNewVersion();
	}
	force_update_check = FALSE;
	update_check_in_progress = FALSE;
	ExitThread(0);
}
Пример #23
0
static void boost(void)
{
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
}
Пример #24
0
// Launch the auth server
extern int main(int argc, char **argv)
{
    sLog->SetLogDB(false);
    // Command line parsing to get the configuration file name
    char const* cfg_file = _AUTHSERVER_CONFIG;
    int c = 1;
    while(c < argc)
    {
        if (strcmp(argv[c], "-c") == 0)
        {
            if (++c >= argc)
            {
                sLog->outError("Runtime-Error: -c option requires an input argument");
                usage(argv[0]);
                return 1;
            }
            else
                cfg_file = argv[c];
        }
        ++c;
    }

    if (!ConfigMgr::Load(cfg_file))
    {
        sLog->outError("Invalid or missing configuration file : %s", cfg_file);
        sLog->outError("Verify that the file exists and has \'[authserver]\' written in the top of the file!");
        return 1;
    }
    sLog->Initialize();

    sLog->outString( "%s (authserver)", _FULLVERSION);
    sLog->outString( "<Ctrl-C> to stop.\n");
    sLog->outString( "Using configuration file %s.", cfg_file);

		sLog->outString(" ");
		sLog->outString(" A World of Warcraft: Cataclysm Core Emulator	");
		sLog->outString("       _/_/              _/          _/_/_/    _/_/    _/_/_/    _/_/_/_/  ");
		sLog->outString("    _/    _/  _/  _/_/  _/  _/    _/        _/    _/  _/    _/  _/         ");
		sLog->outString("   _/_/_/_/  _/_/      _/_/      _/        _/    _/  _/_/_/    _/_/_/      ");
		sLog->outString("  _/    _/  _/        _/  _/    _/        _/    _/  _/    _/  _/           ");
		sLog->outString(" _/    _/  _/        _/    _/    _/_/_/    _/_/    _/    _/  _/_/_/_/  	");
		sLog->outString(" Arkania Community (c) 2012");
		sLog->outString("      <http://arkania.net/>");
		sLog->outString(" ");
		sLog->outString("<Ctrl-C> to stop.\n");

    sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));

#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
    ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true);
#else
    ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true);
#endif

    sLog->outBasic("Max allowed open files is %d", ACE::max_handles());

    // authserver PID file creation
    std::string pidfile = ConfigMgr::GetStringDefault("PidFile", "");
    if (!pidfile.empty())
    {
        uint32 pid = CreatePIDFile(pidfile);
        if (!pid)
        {
            sLog->outError("Cannot create PID file %s.\n", pidfile.c_str());
            return 1;
        }

        sLog->outString("Daemon PID: %u\n", pid);
    }

    // Initialize the database connection
    if (!StartDB())
        return 1;

    // Initialize the log database
    sLog->SetLogDBLater(ConfigMgr::GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished.
    sLog->SetLogDB(false);
    sLog->SetRealmID(0);                                               // ensure we've set realm to 0 (authserver realmid)

    // Get the list of realms for the server
    sRealmList->Initialize(ConfigMgr::GetIntDefault("RealmsStateUpdateDelay", 20));
    if (sRealmList->size() == 0)
    {
        sLog->outError("No valid realms specified.");
        return 1;
    }

    // Launch the listening network socket
    RealmAcceptor acceptor;

    uint16 rmport = ConfigMgr::GetIntDefault("RealmServerPort", 3724);
    std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0");

    ACE_INET_Addr bind_addr(rmport, bind_ip.c_str());

    if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
    {
        sLog->outError("Auth server can not bind to %s:%d", bind_ip.c_str(), rmport);
        return 1;
    }

    // Initialize the signal handlers
    AuthServerSignalHandler SignalINT, SignalTERM;

    // Register authservers's signal handlers
    ACE_Sig_Handler Handler;
    Handler.register_handler(SIGINT, &SignalINT);
    Handler.register_handler(SIGTERM, &SignalTERM);

    ///- Handle affinity for multiple processors and process priority on Windows
#ifdef _WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0);
        if (Aff > 0)
        {
            ULONG_PTR appAff;
            ULONG_PTR sysAff;

            if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
            {
                ULONG_PTR curAff = Aff & appAff;            // remove non accessible processors

                if (!curAff)
                    sLog->outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for authserver. Accessible processors bitmask (hex): %x", Aff, appAff);
                else if (SetProcessAffinityMask(hProcess, curAff))
                    sLog->outString("Using processors (bitmask, hex): %x", curAff);
                else
                    sLog->outError("Can't set used processors (hex): %x", curAff);
            }
            sLog->outString();
        }

        bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false);

        if (Prio)
        {
            if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
                sLog->outString("The auth server process priority class has been set to HIGH");
            else
                sLog->outError("Can't set auth server process priority class.");
            sLog->outString();
        }
    }
#endif

    // maximum counter for next ping
    uint32 numLoops = (ConfigMgr::GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
    uint32 loopCounter = 0;

    // possibly enable db logging; avoid massive startup spam by doing it here.
    if (sLog->GetLogDBLater())
    {
        sLog->outString("Enabling database logging...");
        sLog->SetLogDBLater(false);
        // login db needs thread for logging
        sLog->SetLogDB(true);
    }
    else
        sLog->SetLogDB(false);

    // Wait for termination signal
    while (!stopEvent)
    {
        // dont move this outside the loop, the reactor will modify it
        ACE_Time_Value interval(0, 100000);

        if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1)
            break;

        if ((++loopCounter) == numLoops)
        {
            loopCounter = 0;
            sLog->outDetail("Ping MySQL to keep connection alive");
            LoginDatabase.KeepAlive();
        }
    }

    // Close the Database Pool and library
    StopDB();

    sLog->outString("Halting process...");
    return 0;
}
Пример #25
0
int
Ns_ExecArgblk(char *exec, char *dir, int fdin, int fdout,
		char *args, Ns_Set *env)
{
#ifndef _WIN32
    int    pid;
    char **argv;
    Ns_DString vds;

    Ns_DStringInit(&vds);
    if (args == NULL) {
        argv = NULL;
    } else {
	while (*args != '\0') {
            Ns_DStringNAppend(&vds, (char *) &args, sizeof(args));
            args += strlen(args) + 1;
	}
	args = NULL;
	Ns_DStringNAppend(&vds, (char *) &args, sizeof(args));
	argv = (char **) vds.string;
    }
    pid = Ns_ExecArgv(exec, dir, fdin, fdout, argv, env);
    Ns_DStringFree(&vds);
    return pid;
#else
    STARTUPINFO     si;
    PROCESS_INFORMATION pi;
    HANDLE          hCurrentProcess;
    int             pid;
    Ns_DString      cds, xds, eds;
    char           *envp;
    OSVERSIONINFO   oinfo;
    char           *cmd;

    if (exec == NULL) {
        return -1;
    }
    oinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (GetVersionEx(&oinfo) == TRUE && oinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) {
        cmd = "command.com";
    } else {
        cmd = "cmd.exe";
    }

    /*
     * Setup STARTUPINFO with stdin, stdout, and stderr.
     */
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = (HANDLE) _get_osfhandle(_fileno(stderr));
    hCurrentProcess = GetCurrentProcess();
    if (fdout < 0) {
        fdout = 1;
    }
    if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdout), hCurrentProcess,
            &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) {
        Ns_Log(Error, "exec: failed to duplicate handle: %s",
        NsWin32ErrMsg(GetLastError()));
        return -1;
    }
    if (fdin < 0) {
        fdin = 0;
    }
    if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdin), hCurrentProcess,
            &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) {
        Ns_Log(Error, "exec: failed to duplicate handle: %s",
        NsWin32ErrMsg(GetLastError()));
        (void) CloseHandle(si.hStdOutput);
        return -1;
    }

    /*
     * Setup the command line and environment block and create the new
     * subprocess.
     */

    Ns_DStringInit(&cds);
    Ns_DStringInit(&xds);
    Ns_DStringInit(&eds);
    if (args == NULL) {
        /* NB: exec specifies a complete cmd.exe command string. */
        Ns_DStringVarAppend(&cds, cmd, " /c ", exec, NULL);
        exec = NULL;
    } else {
        char           *s;

        s = args;
        while (*s != '\0') {
            int             len;

            len = strlen(s);
            Ns_DStringNAppend(&cds, s, len);
            s += len + 1;
            if (*s != '\0') {
                Ns_DStringNAppend(&cds, " ", 1);
            }
        }
    Ns_NormalizePath(&xds, exec);
    s = xds.string;
    while (*s != '\0') {
        if (*s == '/') {
            *s = '\\';
        }
        ++s;
    }
    exec = xds.string;
    }
    if (env == NULL) {
        envp = NULL;
    } else {
        Set2Argv(&eds, env);
        envp = eds.string;
    }
    if (CreateProcess(exec, cds.string, NULL, NULL, TRUE, 0, envp, dir, &si, &pi) != TRUE) {
        Ns_Log(Error, "exec: failed to create process: %s: %s",
        exec ? exec : cds.string, NsWin32ErrMsg(GetLastError()));
        pid = -1;
    } else {
        CloseHandle(pi.hThread);
        pid = (int) pi.hProcess;
    }
    Ns_DStringFree(&cds);
    Ns_DStringFree(&xds);
    Ns_DStringFree(&eds);
    CloseHandle(si.hStdInput);
    CloseHandle(si.hStdOutput);
    return pid;
#endif
}
sLONG XWinProcessLauncher::Start(const EnvVarNamesAndValuesMap &inVarToUse)
{
	sLONG			err = 0;
	sLONG			pathLen = 0;
	STARTUPINFO				theStartupInfo;
	PROCESS_INFORMATION		theProcessInformation;
	SECURITY_ATTRIBUTES		theSecurityAttributes;

	char		*envVarsBlock = NULL;
	char		*argsAsCString= NULL;

	if(fBinaryPath == NULL)
		return -50;	// Invalid parameter

	pathLen = (sLONG) strlen(fBinaryPath);
	if(pathLen == 0)
		return -50;	// Invalid parameter

	// Sets the bInheritHandle flag so that pipes are inherited
	theSecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
	theSecurityAttributes.bInheritHandle = TRUE;
	theSecurityAttributes.lpSecurityDescriptor = NULL;
	
	::SetLastError(0);

	// ______________________________________________ STDIN pipes
	if(err == 0 && fRedirectStandardInput)
	{
	// Creates a pipe for the child process STDIN
		if(!CreatePipe(&fChildStdInRead, &fChildStdInWrite, &theSecurityAttributes, 0))
			err = ::GetLastError();

	// Duplicates the write handle so that it is not inherited
		if(err == 0)
		{
			if(!DuplicateHandle(GetCurrentProcess(), fChildStdInWrite, GetCurrentProcess(), &fChildStdInWriteDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
				err = ::GetLastError();
		}

		_CloseAndInvalidateHandle(&fChildStdInWrite);
	}
	
	// ______________________________________________ STDOUT/STDERR pipes
	if(err == 0 && fRedirectStandardOutput)
	{
	// Creates a pipe for the child process's STDOUT
		if(!CreatePipe(&fChildStdOutRead, &fChildStdOutWrite, &theSecurityAttributes, 0))
			err = ::GetLastError();

		if (err == 0) {

			DWORD	mode = PIPE_NOWAIT;
			
			if (!SetNamedPipeHandleState(fChildStdOutRead, &mode, NULL, NULL))
		
				err = ::GetLastError();

		}

	// Duplicates the read handle to the pipe so that it is not inherited
		if(err == 0)
		{
			if(!DuplicateHandle(GetCurrentProcess(), fChildStdOutRead, GetCurrentProcess(), &fChildStdOutReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
				err = ::GetLastError();
		}

		_CloseAndInvalidateHandle(&fChildStdOutRead);

	// The same for STDERR
		if(err == 0)
		{
			if(!CreatePipe(&fChildStdErrRead, &fChildStdErrWrite, &theSecurityAttributes, 0))
				err = ::GetLastError();
		}

		if (err == 0) {

			DWORD	mode = PIPE_NOWAIT;
			
			if (!SetNamedPipeHandleState(fChildStdErrRead, &mode, NULL, NULL))
		
				err = ::GetLastError();

		}

		if(err == 0)
		{
			if(!DuplicateHandle(GetCurrentProcess(), fChildStdErrRead, GetCurrentProcess(), &fChildStdErrReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
				err = ::GetLastError();
		}
		
		_CloseAndInvalidateHandle(&fChildStdErrRead);
	} // if(err == 0 && fRedirectStandardOutput)
	
	// ______________________________________________ Setup CreateProcess() parameters
	if(err == 0)
	{
	// Sets up members of the PROCESS_INFORMATION structure
		ZeroMemory(&theProcessInformation, sizeof(PROCESS_INFORMATION));
		
	// Sets up members of the STARTUPINFO structure
		ZeroMemory(&theStartupInfo, sizeof(STARTUPINFO));
		theStartupInfo.cb = sizeof(STARTUPINFO);
		if(fRedirectStandardInput || fRedirectStandardOutput)
			theStartupInfo.dwFlags |= STARTF_USESTDHANDLES;
		theStartupInfo.hStdInput = NULL;
		theStartupInfo.hStdOutput = NULL;
		theStartupInfo.hStdError = NULL;
		if(fRedirectStandardInput)
			theStartupInfo.hStdInput = fChildStdInRead;
		if(fRedirectStandardOutput)
		{
			theStartupInfo.hStdOutput = fChildStdOutWrite;
			theStartupInfo.hStdError = fChildStdErrWrite;
		}
		
	// Hides the command window if specified
		if(fHideWindow)
		{
			theStartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
			theStartupInfo.wShowWindow = SW_HIDE;
		}
		
	// Create the environment variables block
		envVarsBlock = _CreateEnvironmentVariablesBlock(inVarToUse);
		
	// Create the CString arguments. See _CreateConcatenetedArguments().
		argsAsCString = _CreateConcatenetedArguments();
		if(argsAsCString == NULL)
		{
			assert(false);
			err = -108;
		}
	} // if(err == 0)
	
	// ______________________________________________ CreateProcess()
	if(err == 0)
	{
		sLONG	argsLen = (sLONG) strlen(argsAsCString);
		sLONG	commandFullSize = pathLen + 1; //'\0'
		if(argsLen > 0)
			commandFullSize += 1 + argsLen;// ' '
		
		char *commandLine = NULL;
		
		if(argsLen > 0)
		{
			commandLine = new char[commandFullSize];
			if(commandLine == NULL)
			{
				err = -108;
			}
			else
			{
				memcpy(commandLine, fBinaryPath, pathLen);
				if(argsLen > 0)
				{
					commandLine[pathLen] = ' ';
					memcpy(commandLine + pathLen + 1, argsAsCString, argsLen);
				}
				commandLine[commandFullSize - 1] = 0;
			}
		}
		else
		{
			sLONG	theSize = (sLONG) strlen(fBinaryPath) + 1;
			commandLine = new char[theSize];
			memcpy(commandLine, fBinaryPath, theSize);
		}
		
		if(err == 0)
		{
			bool	bInheritHandles = fRedirectStandardInput || fRedirectStandardOutput ? TRUE : FALSE;
			char *lpCurrentDirectory = (fCurrentDirectory != NULL && fCurrentDirectory[0] > 0) ? fCurrentDirectory : NULL;
			
			SetLastError(0);

			long	tempLastError = 0;
			long creaProcResult = CreateProcess(NULL,					// Application name
												commandLine,			// Command line
												NULL,					// Process security attributes
												NULL,					// Primary thread security attributes
												bInheritHandles,		// Handles are inherited
												0,						// DETACHED_PROCESS creation flag
												envVarsBlock,			// NULL == use parent's environment
												lpCurrentDirectory,		// NULL == use parent's directory
												&theStartupInfo,		// STARTUPINFO pointer
												&theProcessInformation	// Receives PROCESS_INFORMATION
												);
			tempLastError = GetLastError(); // For debug
			if(creaProcResult == 0)	// "If the function succeeds, the return value is nonzero"
			{
				err = ::GetLastError();

				fIsRunning = false;
				fProcessID = 0;
				ZeroMemory(&fProcInfo, sizeof(PROCESS_INFORMATION));
			}
			else
			{
				fIsRunning = true;
				fProcInfo = theProcessInformation;
				fProcessID = fProcInfo.dwProcessId;
			
				// If process is independant and we don't need to retrieve exit status at
				// termination, immediatly close those handles from our part
				if(!fWaitClosingChildProcess && !fCanGetExitStatus)
				{
					CloseHandle(theProcessInformation.hProcess);
					CloseHandle(theProcessInformation.hThread);
					
				}
			
			}
		} // if(err == 0)
		
		delete [] commandLine;
		
	} //  if(err == 0)
	
	if(err != 0)
		_CloseAllPipes();
	
	delete [] argsAsCString;
	delete [] envVarsBlock;
	
	return err;
}
Пример #27
0
/// Do 'logf' instruction.
/// 
/// Return AGENT_RET_SUCCESS if succeed, or AGENT_RET_FAIL if fail
static MBA_AGENT_RETURN export_log( SOCKET sClientSocket )
{
    LARGE_INTEGER fileSize;
    
    DWORDLONG nBytesRead;
    DWORDLONG nBytesWrite;
    DWORDLONG nBytesWriteOneTime;
    DWORDLONG nErrorBytesRead;
    DWORD      sendRound;                // rounds of content sent
    DWORD      ptrSetFile;
    
    HANDLE hLog;
    
    char fBuf[SZ_MAX_FILECHUNK];   // export buffer
    char errorbuf[sizeof(MSG_REC_SUCCESS)];
    
    // Duplicate the global log handle and check the result
    if ( !DuplicateHandle( 
          GetCurrentProcess(),
          g_hLog,
          GetCurrentProcess(),
          &hLog,
          0,
          FALSE,
          DUPLICATE_SAME_ACCESS ) ) {
        display_error("export_log - GetFileSizeEx", FALSE);
        send(sClientSocket, MSG_REC_FAIL, sizeof(MSG_REC_FAIL), 0);
        return AGENT_RET_FAIL;
    }
    else
        send(sClientSocket, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS), 0);
    
    // Set the file pointer of hLog and check the result
    ptrSetFile = SetFilePointer(hLog, 0, NULL, FILE_BEGIN);
    if ( ptrSetFile ==  INVALID_SET_FILE_POINTER ) {
        display_error("export_log - GetFileSizeEx", FALSE);
        send(sClientSocket, MSG_REC_FAIL, sizeof(MSG_REC_FAIL), 0);
        return AGENT_RET_FAIL;
    }
    else
        send(sClientSocket, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS), 0);
    
    // Read log file size
    if (!GetFileSizeEx(hLog, &fileSize)) {
        display_error("export_log - GetFileSizeEx", FALSE);
        send(sClientSocket, MSG_REC_FAIL, sizeof(MSG_REC_FAIL), 0);
        CloseHandle( hLog );
        return AGENT_RET_FAIL;
    }
    else
        send(sClientSocket, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS), 0);
    
    // Send log file size
    nBytesWrite = send(sClientSocket, (const char*)&fileSize.QuadPart, sizeof(fileSize.QuadPart), 0);
    if( nBytesWrite != sizeof(fileSize.QuadPart) ) {
        display_error("export_log - send", TRUE);
        CloseHandle( hLog );
        return AGENT_RET_FAIL;
    }
    
    // --------Check if client can open file successfully-------- //
    nErrorBytesRead = recv( sClientSocket, errorbuf, sizeof(MSG_REC_SUCCESS), MSG_WAITALL );
    if ( nErrorBytesRead != sizeof(MSG_REC_SUCCESS) ) {
        display_error("export_cmd - CheckClient - can't check client open file successfully", FALSE);
        CloseHandle( hLog );
        return AGENT_RET_FAIL;
    }
    if ( strncmp(errorbuf, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS)) != 0 ) {
        display_error("export_cmd - CheckClient - client can't open file", FALSE);
        CloseHandle( hLog );
        return AGENT_RET_FAIL;
    }
    
    // calculate how many rounds to send file content
    sendRound = fileSize.QuadPart / SZ_MAX_FILECHUNK;

    // start to deliver the file content to QEMU
    nBytesWrite = 0;
    while (sendRound) {

        // Read log file contents
        if( ReadFile(hLog, fBuf, SZ_MAX_FILECHUNK, (LPDWORD)&nBytesRead, NULL) == 0 ) {
            display_error( "export_log - ReadFile", TRUE);
            send(sClientSocket, MSG_REC_FAIL, sizeof(MSG_REC_FAIL), 0);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        else
            send(sClientSocket, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS), 0);
            
        // send the contents
        nBytesWriteOneTime = send(sClientSocket, fBuf, nBytesRead, 0);
        if ( nBytesWriteOneTime != nBytesRead ){
            display_error("export_cmd - CheckClient - can't send file successfully", FALSE);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        nBytesWrite += nBytesWriteOneTime;
        
        // --------Check if client can write file successfully-------- //
        nErrorBytesRead = recv( sClientSocket, errorbuf, sizeof(MSG_REC_SUCCESS), MSG_WAITALL );
        if ( nErrorBytesRead != sizeof(MSG_REC_SUCCESS) ) {
            display_error("export_cmd - CheckClient - can't check client write file successfully", FALSE);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        if ( strncmp(errorbuf, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS)) != 0 ) {
            display_error("export_cmd - CheckClient - client can't write file", FALSE);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        
        sprintf_s(g_sLogMessage, SZ_MAX_LOG, "fread %ld bytes, Sending out %zd bytes\r\n", nBytesRead, nBytesWrite);
        write_log();
        
        --sendRound;
    }

    // send the remaining file content
    nBytesRead = fileSize.QuadPart % SZ_MAX_FILECHUNK;
    if( nBytesRead ) {

        // read the remaining file contents
        if( ReadFile(hLog, fBuf, nBytesRead, (LPDWORD)&nBytesRead, NULL) == 0 ) {
            display_error("export_log - ReadFile", TRUE);
            send(sClientSocket, MSG_REC_FAIL, sizeof(MSG_REC_FAIL), 0);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        else
            send(sClientSocket, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS), 0);
        
        // send the contents
        nBytesWriteOneTime = send(sClientSocket, fBuf, nBytesRead, 0);
        if ( nBytesWriteOneTime != nBytesRead ){
            display_error("export_cmd - CheckClient - can't send file successfully", FALSE);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        nBytesWrite += nBytesWriteOneTime;
        
        // --------Check if client can write file successfully-------- //
        nErrorBytesRead = recv( sClientSocket, errorbuf, sizeof(MSG_REC_SUCCESS), MSG_WAITALL );
        if ( nErrorBytesRead != sizeof(MSG_REC_SUCCESS) ) {
            display_error("export_cmd - CheckClient - can't check client write file successfully", FALSE);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        if ( strncmp(errorbuf, MSG_REC_SUCCESS, sizeof(MSG_REC_SUCCESS)) != 0 ) {
            display_error("export_cmd - CheckClient - client can't write file", FALSE);
            CloseHandle( hLog );
            return AGENT_RET_FAIL;
        }
        
    }
    
    CloseHandle( hLog );
    
    return AGENT_RET_SUCCESS;
}
/** @copydoc VBOXSERVICE::pfnInit */
static DECLCALLBACK(int) VBoxServiceTimeSyncInit(void)
{
    /*
     * If not specified, find the right interval default.
     * Then create the event sem to block on.
     */
    if (!g_TimeSyncInterval)
        g_TimeSyncInterval = g_DefaultInterval * 1000;
    if (!g_TimeSyncInterval)
        g_TimeSyncInterval = 10 * 1000;

    VbglR3GetSessionId(&g_idTimeSyncSession);
    /* The status code is ignored as this information is not available with VBox < 3.2.10. */

    int rc = RTSemEventMultiCreate(&g_TimeSyncEvent);
    AssertRC(rc);
#ifdef RT_OS_WINDOWS
    if (RT_SUCCESS(rc))
    {
        /*
         * Adjust privileges of this process so we can make system time adjustments.
         */
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &g_hTokenProcess))
        {
            TOKEN_PRIVILEGES tkPriv;
            RT_ZERO(tkPriv);
            tkPriv.PrivilegeCount = 1;
            tkPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            if (LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkPriv.Privileges[0].Luid))
            {
                DWORD cbRet = sizeof(g_TkOldPrivileges);
                if (AdjustTokenPrivileges(g_hTokenProcess, FALSE, &tkPriv, sizeof(TOKEN_PRIVILEGES), &g_TkOldPrivileges, &cbRet))
                    rc = VINF_SUCCESS;
                else
                {
                    DWORD dwErr = GetLastError();
                    rc = RTErrConvertFromWin32(dwErr);
                    VBoxServiceError("VBoxServiceTimeSyncInit: Adjusting token privileges (SE_SYSTEMTIME_NAME) failed with status code %u/%Rrc!\n", dwErr, rc);
                }
            }
            else
            {
                DWORD dwErr = GetLastError();
                rc = RTErrConvertFromWin32(dwErr);
                VBoxServiceError("VBoxServiceTimeSyncInit: Looking up token privileges (SE_SYSTEMTIME_NAME) failed with status code %u/%Rrc!\n", dwErr, rc);
            }
            if (RT_FAILURE(rc))
            {
                CloseHandle(g_hTokenProcess);
                g_hTokenProcess = NULL;
            }
        }
        else
        {
            DWORD dwErr = GetLastError();
            rc = RTErrConvertFromWin32(dwErr);
            VBoxServiceError("VBoxServiceTimeSyncInit: Opening process token (SE_SYSTEMTIME_NAME) failed with status code %u/%Rrc!\n", dwErr, rc);
            g_hTokenProcess = NULL;
        }
    }

    if (GetSystemTimeAdjustment(&g_dwWinTimeAdjustment, &g_dwWinTimeIncrement, &g_bWinTimeAdjustmentDisabled))
        VBoxServiceVerbose(3, "VBoxServiceTimeSyncInit: Initially %ld (100ns) units per %ld (100 ns) units interval, disabled=%d\n",
                           g_dwWinTimeAdjustment, g_dwWinTimeIncrement, g_bWinTimeAdjustmentDisabled ? 1 : 0);
    else
    {
        DWORD dwErr = GetLastError();
        rc = RTErrConvertFromWin32(dwErr);
        VBoxServiceError("VBoxServiceTimeSyncInit: Could not get time adjustment values! Last error: %ld!\n", dwErr);
    }
#endif /* RT_OS_WINDOWS */

    return rc;
}
Пример #29
0
/// Main function
int Master::Run()
{
    sLog.outString( "%s (core-daemon)", _FULLVERSION );
    sLog.outString( "<Ctrl-C> to stop.\n" );

    sLog.outString( " ______                       __");
    sLog.outString( "/\\__  _\\       __          __/\\ \\__");
    sLog.outString( "\\/_/\\ \\/ _ __ /\\_\\    ___ /\\_\\ \\ ,_\\  __  __");
    sLog.outString( "   \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\");
    sLog.outString( "    \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\");
    sLog.outString( "     \\ \\_\\ \\_\\  \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\");
    sLog.outString( "      \\/_/\\/_/   \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\");
    sLog.outString( "                                 C O R E  /\\___/");
    sLog.outString( "http://TrinityCore.org                    \\/__/\n");

    /// worldd PID file creation
    std::string pidfile = sConfig.GetStringDefault("PidFile", "");
    if(!pidfile.empty())
    {
        uint32 pid = CreatePIDFile(pidfile);
        if( !pid )
        {
            sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() );
            return 1;
        }

        sLog.outString( "Daemon PID: %u\n", pid );
    }

    ///- Start the databases
    if (!_StartDB())
        return 1;

    ///- Initialize the World
    sWorld.SetInitialWorldSettings();

    ///- Catch termination signals
    _HookSignals();

    ///- Launch WorldRunnable thread
    ACE_Based::Thread world_thread(new WorldRunnable);
    world_thread.setPriority(ACE_Based::Highest);

    // set server online
    loginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID);

    ACE_Based::Thread* cliThread = NULL;

#ifdef WIN32
    if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
#else
    if (sConfig.GetBoolDefault("Console.Enable", true))
#endif
    {
        ///- Launch CliRunnable thread
        cliThread = new ACE_Based::Thread(new CliRunnable);
    }

    ACE_Based::Thread rar_thread(new RARunnable);

    ///- Handle affinity for multiple processors and process priority on Windows
    #ifdef WIN32
    {
        HANDLE hProcess = GetCurrentProcess();

        uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
        if(Aff > 0)
        {
            ULONG_PTR appAff;
            ULONG_PTR sysAff;

            if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
            {
                ULONG_PTR curAff = Aff & appAff;            // remove non accessible processors

                if(!curAff )
                {
                    sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for Trinityd. Accessible processors bitmask (hex): %x",Aff,appAff);
                }
                else
                {
                    if(SetProcessAffinityMask(hProcess,curAff))
                        sLog.outString("Using processors (bitmask, hex): %x", curAff);
                    else
                        sLog.outError("Can't set used processors (hex): %x",curAff);
                }
            }
            sLog.outString("");
        }

        bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);

//        if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/)
        if(Prio)
        {
            if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
                sLog.outString("TrinityCore process priority class set to HIGH");
            else
                sLog.outError("ERROR: Can't set Trinityd process priority class.");
            sLog.outString("");
        }
    }
    #endif

    uint32 realCurrTime, realPrevTime;
    realCurrTime = realPrevTime = getMSTime();

    uint32 socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME);

    // maximum counter for next ping
    uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / socketSelecttime));
    uint32 loopCounter = 0;

    ///- Start up freeze catcher thread
    if(uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0))
    {
        FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable();
        fdr->SetDelayTime(freeze_delay*1000);
        ACE_Based::Thread freeze_thread(fdr);
        freeze_thread.setPriority(ACE_Based::Highest);
    }

    ///- Launch the world listener socket
    port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD);
    std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0");

    if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1)
    {
        sLog.outError ("Failed to start network");
        World::StopNow(ERROR_EXIT_CODE);
        // go down and shutdown the server
    }

    sWorldSocketMgr->Wait ();

    // set server offline
    loginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID);

    ///- Remove signal handling before leaving
    _UnhookSignals();

    // when the main thread closes the singletons get unloaded
    // since worldrunnable uses them, it will crash if unloaded after master
    world_thread.wait();
    rar_thread.wait ();

    ///- Clean database before leaving
    clearOnlineAccounts();

    ///- Wait for delay threads to end
    CharacterDatabase.HaltDelayThread();
    WorldDatabase.HaltDelayThread();
    loginDatabase.HaltDelayThread();

    sLog.outString( "Halting process..." );

    if (cliThread)
    {
        #ifdef WIN32

        // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API)
        //_exit(1);
        // send keyboard input to safely unblock the CLI thread
        INPUT_RECORD b[5];
        HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
        b[0].EventType = KEY_EVENT;
        b[0].Event.KeyEvent.bKeyDown = TRUE;
        b[0].Event.KeyEvent.uChar.AsciiChar = 'X';
        b[0].Event.KeyEvent.wVirtualKeyCode = 'X';
        b[0].Event.KeyEvent.wRepeatCount = 1;

        b[1].EventType = KEY_EVENT;
        b[1].Event.KeyEvent.bKeyDown = FALSE;
        b[1].Event.KeyEvent.uChar.AsciiChar = 'X';
        b[1].Event.KeyEvent.wVirtualKeyCode = 'X';
        b[1].Event.KeyEvent.wRepeatCount = 1;

        b[2].EventType = KEY_EVENT;
        b[2].Event.KeyEvent.bKeyDown = TRUE;
        b[2].Event.KeyEvent.dwControlKeyState = 0;
        b[2].Event.KeyEvent.uChar.AsciiChar = '\r';
        b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
        b[2].Event.KeyEvent.wRepeatCount = 1;
        b[2].Event.KeyEvent.wVirtualScanCode = 0x1c;

        b[3].EventType = KEY_EVENT;
        b[3].Event.KeyEvent.bKeyDown = FALSE;
        b[3].Event.KeyEvent.dwControlKeyState = 0;
        b[3].Event.KeyEvent.uChar.AsciiChar = '\r';
        b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
        b[3].Event.KeyEvent.wVirtualScanCode = 0x1c;
        b[3].Event.KeyEvent.wRepeatCount = 1;
        DWORD numb;
        BOOL ret = WriteConsoleInput(hStdIn, b, 4, &numb);

        cliThread->wait();

        #else 

        cliThread->destroy();

        #endif

        delete cliThread;
    }

    // for some unknown reason, unloading scripts here and not in worldrunnable
    // fixes a memory leak related to detaching threads from the module
    UnloadScriptingModule();

    // Exit the process with specified return value
    return World::GetExitCode();
}
Пример #30
0
void CmdLib_Exit( int exitCode )
{
	TerminateProcess( GetCurrentProcess(), 1 );
}