// --------------------------------------------------------------------------- // Name: osTCPSocketServer::bind // // Description: Associates a local port with this socket. // I.E: Any socket client connection to this port address will be mapped // to this socket server. // // Arguments: portAddress - The address of the port to which the socket will be bound. // // Return Val: bool - Success / failure. // Author: AMD Developer Tools Team // Date: 3/1/2004 // --------------------------------------------------------------------------- bool osTCPSocketServer::bind(const osPortAddress& portAddress) { bool retVal = false; // Verify that the socket is open: if (isOpen()) { // Translate portAddress into a win32 local port address: SOCKADDR_IN win32PortAddress; bool rc = portAddress.asSockaddr(win32PortAddress, _blockOnDNS); if (rc) { // Bind this socket to the input local port address: osSocketDescriptor socketDescriptor = OSSocketDescriptor(); int rc1 = ::bind(socketDescriptor, (LPSOCKADDR)&win32PortAddress, sizeof(SOCKADDR_IN)); if (rc1 != SOCKET_ERROR) { retVal = true; _boundAddress = portAddress; } else { // An error occurred: gtString errMsg = OS_STR_bindError; errMsg += OS_STR_osReportedErrorIs; errMsg += OS_STR_host; errMsg += portAddress.hostName(); errMsg += OS_STR_port; unsigned short portNum = portAddress.portNumber(); errMsg.appendFormattedString(L"%u ", portNum); gtString systemError; osGetLastSystemErrorAsString(systemError); errMsg += systemError; GT_ASSERT_EX(false, errMsg.asCharArray()); } } } return retVal; }
//----------------------------------------------------------------------------- bool Send(Response& rResponse, const char* mime, const char* pData, unsigned long dwSize) { char sendbuffer[COMM_BUFFER_SIZE]; sendbuffer[0] = 0; // send the http header and the file contents to the browser if (rResponse.m_bNeedToSendHeader == true) { GenerateHeader(rResponse, sendbuffer, COMM_BUFFER_SIZE); rResponse.m_bNeedToSendHeader = false; } if (rResponse.m_bStreamingEnabled == true) { strncat_s(sendbuffer, COMM_BUFFER_SIZE, "--BoundaryString\r\n", COMM_BUFFER_SIZE); } DWORD len = (DWORD)strlen(sendbuffer); sprintf_s(sendbuffer + len, COMM_BUFFER_SIZE - len, "Content-Type: %s\r\n" "Content-Length: %ld\r\n" "\r\n", mime, dwSize); // send header bool res = rResponse.client_socket->Send(sendbuffer, (DWORD)strlen(sendbuffer)); if (res == true) { // if header could be sent // send data res = rResponse.client_socket->Send(pData, dwSize); } else { osSystemErrorCode systemLastError = osGetLastSystemError(); // If no system error was recorded: if (systemLastError != 0) { gtString systemErrorString; osGetLastSystemErrorAsString(systemErrorString); Log(logERROR, "Failed to send %s response data due to error %d: %s\n", mime, systemLastError, systemErrorString.asASCIICharArray()); } // there was an error sending // so close the connection and return false CloseConnection(rResponse); return false; } // if the response is not streaming, // the connection should be closed // otherwise it should be left open if (rResponse.m_bStreamingEnabled == false) { CloseConnection(rResponse); } return true; }
//-------------------------------------------------------------- // LaunchAppInNewProcess //-------------------------------------------------------------- PROCESS_INFORMATION ProcessTracker::LaunchAppInNewProcess(gtASCIIString strApp, gtASCIIString strDir, gtASCIIString strArgs, osModuleArchitecture binaryType) { #ifdef _LINUX PS_UNREFERENCED_PARAMETER(binaryType); #endif LogConsole(logMESSAGE, "About to launch: %s\n", strApp.asCharArray()); LogConsole(logMESSAGE, "Params: %s\n", strArgs.asCharArray()); LogConsole(logMESSAGE, "Working Directory: %s\n", strDir.asCharArray()); // Get app directory and make it default if (strDir.isEmpty()) { size_t pos = strApp.find_last_of("\\"); if (pos != std::string::npos) { strDir = strApp.substr(0, (int)pos); if (strApp[0] == '\"') { strDir += "\""; } } } PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); #ifdef _WIN32 DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED; SetLastError(0); STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); #endif // Cmd line has to include the exe name since many apps expect the executable name to be in argv[0]! // Note argv[0] on the command line needs to be surrounded with quotes if it contains spaces. // The arguments in strArgs have already been "quoted" as they are parsed. gtASCIIString strCmdLine = AddQuotesIfStringHasSpaces(strApp.asCharArray()); strCmdLine += " "; strCmdLine += strArgs; LogConsole(logMESSAGE, "strApp: %s\n", strApp.asCharArray()); LogConsole(logMESSAGE, "strCmdLine: %s\n", strCmdLine.asCharArray()); // Attempt to initialize the environment that the new process will run in. The child process should inherit "this" environment. if (!PrelaunchEnvironmentInitialization()) { // Log a warning if this failed- initializing the environment for the new process can fail if Mantle support isn't installed. // In these cases, if the user is attempting to debug a Mantle application, they will have bigger problems to deal with. // In cases where a DX/GL app is being debugged, this warning can be ignored without any side effects. Log(logWARNING, "Environment initialization failed. If using DX/GL, it is safe to ignore this warning.\n"); } BOOL succeeded = FALSE; #ifdef _WIN32 char microDLLPath[PS_MAX_PATH]; const char* strServerPath; strServerPath = SG_GET_PATH(ServerPath); if (SG_GET_BOOL(OptionDllReplacement) == true) { DllReplacement::SetDllDirectory(binaryType == OS_X86_64_ARCHITECTURE); } // if using manual dll replacement or the AppInit_DLLs registry setting, don't use any kind of dll injection if (SG_GET_BOOL(OptionManualDllReplacement) == true || SG_GET_BOOL(OptionAppInitDll)) { succeeded = CreateProcess(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(), NULL, NULL, TRUE, dwFlags, NULL, strDir.asCharArray(), &si, &pi); } else { #ifdef X64 // can only launch 64 bit applications if (binaryType != OS_X86_64_ARCHITECTURE) { sprintf_s(microDLLPath, PS_MAX_PATH, "%s" MICRODLLNAME "%s%s.dll", SG_GET_PATH(ServerPath), GDT_DEBUG_SUFFIX, GDT_BUILD_SUFFIX); succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(), NULL, NULL, TRUE, dwFlags, NULL, strDir.asCharArray(), &si, &pi, microDLLPath); } #else if (binaryType != OS_I386_ARCHITECTURE) { sprintf_s(microDLLPath, PS_MAX_PATH, "%s" MICRODLLNAME "-x64%s%s.dll", SG_GET_PATH(ServerPath), GDT_DEBUG_SUFFIX, GDT_BUILD_SUFFIX); succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(), NULL, NULL, TRUE, dwFlags, NULL, strDir.asCharArray(), &si, &pi, microDLLPath); } #endif // X64 else { succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(), NULL, NULL, TRUE, dwFlags, NULL, strDir.asCharArray(), &si, &pi, SG_GET_PATH(MicroDLLPath)); } } #else // Create the app process succeeded = CreateProcess(strApp.asCharArray(), strCmdLine.asCharArray(), strDir.asCharArray(), &pi); #endif // _WIN32 if (!succeeded) { osSystemErrorCode systemLastError = osGetLastSystemError(); gtString systemErrorString; osGetLastSystemErrorAsString(systemErrorString); Log(logERROR, "CreateProcessAndInjectDll failed; Error %d: %s\n", systemLastError, systemErrorString.asASCIICharArray()); pi.dwProcessId = 0; } #ifdef _WIN32 else { // Check to see if the Steam.exe has been hooked and if so, set the value in shared memory // If Steam.exe was used to launch the target application, then the checks for cmd.exe and fcx.exe // need to be ignored. if (strApp.length() > 0) { if (strstr(strApp.toLowerCase().asCharArray(), "steam.exe") != NULL) { SG_SET_BOOL(SteamInjected, true); } ShowLauncherReminder(strApp.toLowerCase().asCharArray()); } else { if (strstr(strCmdLine.toLowerCase().asCharArray(), "steam.exe") != NULL) { SG_SET_BOOL(SteamInjected, true); } ShowLauncherReminder(strCmdLine.toLowerCase().asCharArray()); } } #endif // _WIN32 return pi; }
//-------------------------------------------------------------- /// Writes information about the allowed plugins into shared memory /// and launches the application specified in s_strInjectedAppName /// \return true if the app is successfully launched; false otherwise //-------------------------------------------------------------- bool ProcessTracker::WritePluginsToSharedMemoryAndLaunchApp() { bool bGetType = false; if (OSDependentModulesInitialization() == false) { Log(logERROR, "Failed to initialize for plugins\n"); return false; } osModuleArchitecture binaryType; bGetType = OSWrappers::GetBinaryType(m_injectedAppName.c_str(), &binaryType); #ifdef _WIN32 if (!bGetType) { // try without quotes, should be W8x preference. This will update m_injectedAppName for later use also. m_injectedAppName.erase(0, 1); m_injectedAppName.resize(m_injectedAppName.size() - 1); bGetType = OSWrappers::GetBinaryType(m_injectedAppName.c_str(), &binaryType); } #endif // def _WIN32 if (!bGetType) { // file is not executable LogConsole(logERROR, "%s is not an executable file\n", m_injectedAppName.c_str()); return false; } Log(logMESSAGE, "WritePluginsToSharedMemoryAndLaunchApp()\n"); if (false == CreateSharedMemory()) { return false; } // now actually start the application PROCESS_INFORMATION pi = LaunchAppInNewProcess(m_injectedAppName.c_str(), m_injectedAppDir.c_str(), m_injectedAppArgs.c_str(), binaryType); if (pi.dwProcessId == 0) { LogConsole(logWARNING, "Failed to start application: %s %s\n\n", m_injectedAppName.c_str(), m_injectedAppArgs.c_str()); return false; } Log(logMESSAGE, "About to resume application thread\n"); #ifdef _WIN32 if (osResumeSuspendedProcess(0, 0, pi.hThread, false) == false) { osSystemErrorCode systemLastError = osGetLastSystemError(); gtString systemErrorString; osGetLastSystemErrorAsString(systemErrorString); Log(logERROR, "Resuming thread failed; Error %d: %s\n", systemLastError, systemErrorString.asASCIICharArray()); } #endif m_injectedAppID = pi.dwProcessId; return true; }