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;
}
Esempio n. 2
0
//--------------------------------------------------------------------------
/// 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);
}