bool ProcessTracker::HandleRequest(HTTPRequestHeader* pRequestHeader, CommunicationID requestID, NetSocket* pClientSocket, bool renderLoopStalled) { char* ptr = pRequestHeader->GetUrl(); char* sCmd = &ptr[1]; #ifdef CODEXL_GRAPHICS #ifdef USE_GRAPHICS_SERVER_STATUS_RETURN_CODES // Handle process not running condition if (pRequestHeader->CheckProcessStillRunning() == false) { Log(logMESSAGE, "Rejecting the command above due to process no longer running: %s\n", pRequestHeader->GetUrl()); // Need to return the correct error data for process not running HandleServerStatusResponse(GRAPHICS_SERVER_STATE_PROCESS_NOT_RUNNING, pRequestHeader, pClientSocket); // This request never gets passed to the graphics server. return true; } // Check if renering has stalled. if (renderLoopStalled == true) { Log(logMESSAGE, "Rejecting the command above due to render stall: %s\n", pRequestHeader->GetUrl()); // Need to return the correct error data for process not running HandleServerStatusResponse(GRAPHICS_SERVER_STATE_STALLED, pRequestHeader, pClientSocket); // This request never gets passed to the graphics server. return true; } #else UNREFERENCED_PARAMETER(renderLoopStalled); #endif #else PS_UNREFERENCED_PARAMETER(renderLoopStalled); #endif #ifdef _WIN32 // if using AppInit_Dll, clear the registry as soon as a process.xml request is sent. // TODO: move this to where a connection has definately been made if (SG_GET_BOOL(OptionAppInitDll) == true) { if (registryCleared == false) { RestoreAppInit(); registryCleared = true; } } #endif if (IsToken(&sCmd, "inject?")) { DoInjectCommand(requestID, &sCmd, pClientSocket); } else { // do commands that depend on PID for (WrapperMap::iterator wrapperIter = g_activeWrappersMap.begin(); wrapperIter != g_activeWrappersMap.end(); ++wrapperIter) { // parse out the process ID unsigned long pid = 0; sscanf_s(wrapperIter->first.c_str(), "%lu/", &pid); // make PID string for easier parsing of the command gtASCIIString strPID; strPID.appendFormattedString("%lu", pid); gtASCIIString strPidSlashPlugin = wrapperIter->first.c_str(); // the key in the activeWrappersMap is formatted as pid/plugin (ie: "435/DX11") // and this conveniently matches the format of the commands coming into the server, so parse for matching commands gtASCIIString tmpString = strPidSlashPlugin; tmpString += "/"; if (IsToken(&sCmd, tmpString.asCharArray())) { // we know this command is targetting the current plugin pRequestHeader->SetUrl(sCmd); // pass the request to the plugin #ifdef _WIN32 const char* memoryName = strPidSlashPlugin.asCharArray(); #else // the '/' character can't be used as a filename in Linux, so just use the plugin name as the shared memory name // (ignore the process ID) char memoryName[PS_MAX_PATH]; char pluginShortDesc[ PS_MAX_PATH ]; sscanf_s(strPidSlashPlugin.asCharArray(), "%lu/%s", &pid, pluginShortDesc, sizeof(pluginShortDesc)); sprintf_s(memoryName, PS_MAX_PATH, "%lu %s", pid, pluginShortDesc); #endif if (PassRequestToPlugin(memoryName, pRequestHeader, pid, pClientSocket)) { return true; } else { Log(logERROR, "Request '%s' is not targeted to an active plugin.\n", GetRequestText(requestID)); SendHTMLResponse(requestID, "<html>Error: Targeted plugin is not currently active.</html>", pClientSocket); } } else { tmpString = strPID; tmpString += "/Kill"; if (IsToken(&sCmd, tmpString.asCharArray())) { if (KillProcess(pid)) { SendTextResponse(requestID, "Ok", pClientSocket); // if the app was launched from the command line or drag and drop // then killing the app should cause the server to shutdown also if (g_bAppSpecifiedAtCmdLine) { g_shutdownEvent.Signal(); CloseStreamThread(); CloseStreamSockets(); SendTextResponse(requestID, "OK", pClientSocket); return true; } } else { Log(logERROR, "Failed to Kill the process\n"); SendTextResponse(requestID, "Error: Failed to Kill the process.", pClientSocket); } } } } } return false; }
//-------------------------------------------------------------------------- /// Process a new request received by the server plugin. /// \param inRequestId The Id associated with the new incoming request. /// \return True if the request was handled successfully. //-------------------------------------------------------------------------- bool ModernAPILayerManager::ProcessRequestFromCommId(CommunicationID inRequestId) { CommandObject command(inRequestId, (char*)GetRequestText(inRequestId)); return Process(command); }