Exemplo n.º 1
0
static void RefreshAspect(HWND hwnd, int cx, int cy)
{
    int divisor = gcd(cx, cy);

    String aspect = Str("Settings.Video.AspectRatioFormat");
    aspect.FindReplace(L"$1", UIntString(cx / divisor));
    aspect.FindReplace(L"$2", UIntString(cy / divisor));

    SetWindowText(GetDlgItem(hwnd, IDC_ASPECT), aspect.Array());
}
Exemplo n.º 2
0
    ~BandwidthAnalyzer()
    {
        QWORD bytesPerSec = totalBytesTransmitted/MAX(numSeconds, 1);

        String strReport;
        strReport << TEXT("Stream report:\r\n\r\n");

        /*strReport << App->GetVideoEncoder()->GetInfoString() << TEXT("\r\n\r\n");
        strReport << App->GetAudioEncoder()->GetInfoString() << TEXT("\r\n\r\n");*/

        strReport << TEXT("Total Bytes transmitted: ") << UInt64String(totalBytesTransmitted, 10) <<
                     TEXT("\r\nTotal time of stream in seconds: ") << UIntString(numSeconds) <<
                     TEXT("\r\nAverage Bytes/Bits per second: ") << UInt64String(bytesPerSec, 10) << TEXT(", ") << UInt64String(bytesPerSec*8, 10) <<
                     TEXT("\r\nHighest Bytes/Bits in a second: ") << UIntString(highestBytes) << TEXT(", ") << UIntString(highestBytes*8);

        App->SetStreamReport(strReport);
    }
Exemplo n.º 3
0
void Compiler::CreateSourceEnum(EnumDefinition *enumDef)
{
    String str;

    if(!enumDef->name.IsEmpty())
        str << TEXT("\r\nenum ") << enumDef->name << TEXT("\r\n{\r\n");
    else
        str << TEXT("\r\nenum\r\n{\r\n");

    int id = 0;
    for(int i=0; i<enumDef->Items.Num(); i++)
    {
        EnumItem *item = &enumDef->Items[i];
        if(item->val != id)
        {
            if((unsigned int)item->val >= 0x1000)
                str << TEXT("    ") << item->name << TEXT("=0x") << UIntString(item->val, 16) << TEXT(",\r\n");
            else
                str << TEXT("    ") << item->name << TEXT("=") << UIntString(item->val) << TEXT(",\r\n");
            id = item->val;
        }
        else
            str << TEXT("    ") << item->name << TEXT(",\r\n");

        ++id;
    }

    str << TEXT("};\r\n");

    //----------------------------------

    strCurEnums << str;

    //----------------------------------

    if(!enumDef->name.IsEmpty())
        strForwards << TEXT("enum ") << enumDef->name << TEXT(";\r\n");
}
Exemplo n.º 4
0
bool MemoryCapture::Init(CaptureInfo &info)
{
    this->height = info.cy;
    this->pitch = info.pitch;

    String strFileMapName;
    strFileMapName << TEXTURE_MEMORY << UIntString(info.mapID);

    hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, strFileMapName);
    if(hFileMap == NULL)
    {
        AppWarning(TEXT("MemoryCapture::Init: Could not open file mapping"));
        return false;
    }

    sharedMemory = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, info.mapSize);
    if(!sharedMemory)
    {
        AppWarning(TEXT("MemoryCapture::Init: Could not map view of file"));
        return false;
    }

    hMemoryMutex = OSCreateMutex();
    if(!hMemoryMutex)
    {
        AppWarning(TEXT("MemoryCapture::Init: Could not create memory mutex"));
        return false;
    }

    //---------------------------------------

    Log(TEXT("using memory capture"));

    copyData = (MemoryCopyData*)sharedMemory;
    textureBuffers[0] = sharedMemory+copyData->texture1Offset;
    textureBuffers[1] = sharedMemory+copyData->texture2Offset;
    copyData->frameTime = 1000000/API->GetMaxFPS();

    texture = CreateTexture(info.cx, info.cy, (GSColorFormat)info.format, NULL, NULL, FALSE);
    if(!texture)
    {
        AppWarning(TEXT("MemoryCapture::Init: Could not create texture"));
        return false;
    }

    bInitialized = true;
    return true;
}
Exemplo n.º 5
0
bool SharedTexCapture::Init(CaptureInfo &info)
{
    String strFileMapName;
    strFileMapName << TEXTURE_MEMORY << UIntString(info.mapID);

    hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, strFileMapName);
    if(hFileMap == NULL)
    {
        AppWarning(TEXT("SharedTexCapture::Init: Could not open file mapping: %d"), GetLastError());
        return false;
    }

    sharedMemory = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, info.mapSize);
    if(!sharedMemory)
    {
        AppWarning(TEXT("SharedTexCapture::Init: Could not map view of file"));
        return false;
    }

    //Log(TEXT("using shared texture capture"));

    //---------------------------------------

    texData = (SharedTexData*)sharedMemory;
    texData->frameTime = 1000000/API->GetMaxFPS()/2;

    sharedTexture = GS->CreateTextureFromSharedHandle(info.cx, info.cy, (HANDLE)texData->texHandle);
    if(!sharedTexture)
    {
        AppWarning(TEXT("SharedTexCapture::Init: Could not create shared texture"));
        return false;
    }

    copyTexture = GS->CreateTexture(info.cx, info.cy, (GSColorFormat)info.format, 0, FALSE, TRUE);

    Log(TEXT("SharedTexCapture hooked"));

    bInitialized = true;
    return true;
}
Exemplo n.º 6
0
String ExpandRecordingFilename(String filename)
{
    SYSTEMTIME st;
    GetLocalTime(&st);
    filename.FindReplace(L"$Y", UIntString(st.wYear).Array());
    filename.FindReplace(L"$M", UIntString(st.wMonth).Array());
    filename.FindReplace(L"$0M", FormattedString(L"%02u", st.wMonth).Array());
    filename.FindReplace(L"$D", UIntString(st.wDay).Array());
    filename.FindReplace(L"$0D", FormattedString(L"%02u", st.wDay).Array());
    filename.FindReplace(L"$h", UIntString(st.wHour).Array());
    filename.FindReplace(L"$0h", FormattedString(L"%02u", st.wHour).Array());
    filename.FindReplace(L"$m", UIntString(st.wMinute).Array());
    filename.FindReplace(L"$0m", FormattedString(L"%02u", st.wMinute).Array());
    filename.FindReplace(L"$s", UIntString(st.wSecond).Array());
    filename.FindReplace(L"$0s", FormattedString(L"%02u", st.wSecond).Array());

    filename.FindReplace(L"$T", FormattedString(L"%u-%02u-%02u-%02u%02u-%02u", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond).Array());
    return filename;
}
Exemplo n.º 7
0
void SettingsPublish::SetWarningInfo()
{
    int serviceID = (int)SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETCURSEL, 0, 0), 0);

    bool bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0;
    int maxBitRate = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
    int keyframeInt = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0);
    int audioBitRate = AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96);
    String currentx264Profile = AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), L"high");
    String currentAudioCodec = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC"));
    float currentAspect = AppConfig->GetInt(L"Video", L"BaseWidth") / (float)max(1, AppConfig->GetInt(L"Video", L"BaseHeight"));

    //ignore for non-livestreams
    if (data.mode != 0)
    {
        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
        return;
    }

    bool hasErrors = false;
    bool canOptimize = false;
    String strWarnings;

    XConfig serverData;
    if(serverData.Open(TEXT("services.xconfig")))
    {
        XElement *services = serverData.GetElement(TEXT("services"));
        if(services)
        {
            UINT numServices = services->NumElements();

            for(UINT i=0; i<numServices; i++)
            {
                XElement *service = services->GetElementByID(i);
                if (service->GetInt(TEXT("id")) == serviceID)
                {
                    strWarnings = FormattedString(Str("Settings.Publish.Warning.BadSettings"), service->GetName());

                    //check to see if the service we're using has recommendations
                    if (!service->HasItem(TEXT("recommended")))
                    {
                        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
                        return;
                    }

                    XElement *r = service->GetElement(TEXT("recommended"));

                    if (r->HasItem(TEXT("ratecontrol")))
                    {
                        CTSTR rc = r->GetString(TEXT("ratecontrol"));
                        if (!scmp (rc, TEXT("cbr")) && !bUseCBR)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << Str("Settings.Publish.Warning.UseCBR");
                        }
                    }

                    if (r->HasItem(TEXT("max bitrate")))
                    {
                        int max_bitrate = r->GetInt(TEXT("max bitrate"));
                        if (maxBitRate > max_bitrate)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.Maxbitrate"), max_bitrate);
                        }
                    }

                    if (r->HasItem(L"supported audio codec"))
                    {
                        StringList codecs;
                        r->GetStringList(L"supported audio codec", codecs);
                        if (codecs.FindValueIndex(currentAudioCodec) == INVALID)
                        {
                            String msg = Str("Settings.Publish.Warning.UnsupportedAudioCodec"); //good thing OBS only supports MP3 (and AAC), otherwise I'd have to come up with a better translation solution
                            msg.FindReplace(L"$1", codecs[0].Array());
                            msg.FindReplace(L"$2", currentAudioCodec.Array());
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << msg;
                        }
                    }

                    if (r->HasItem(TEXT("max audio bitrate aac")) && (!scmp(currentAudioCodec, TEXT("AAC"))))
                    {
                        int maxaudioaac = r->GetInt(TEXT("max audio bitrate aac"));
                        if (audioBitRate > maxaudioaac)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.MaxAudiobitrate"), maxaudioaac);
                        }
                    }

                    if (r->HasItem(TEXT("max audio bitrate mp3")) && (!scmp(currentAudioCodec, TEXT("MP3"))))
                    {
                        int maxaudiomp3 = r->GetInt(TEXT("max audio bitrate mp3"));
                        if (audioBitRate > maxaudiomp3)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.MaxAudiobitrate"), maxaudiomp3);
                        }
                    }

                    if (r->HasItem(L"video aspect ratio"))
                    {
                        String aspectRatio = r->GetString(L"video aspect ratio");
                        StringList numbers;
                        aspectRatio.GetTokenList(numbers, ':');
                        if (numbers.Num() == 2)
                        {
                            float aspect = numbers[0].ToInt() / max(1.f, numbers[1].ToFloat());
                            if (!CloseFloat(aspect, currentAspect))
                            {
                                String aspectLocalized = Str("Settings.Video.AspectRatioFormat");
                                aspectLocalized.FindReplace(L"$1", UIntString(numbers[0].ToInt()));
                                aspectLocalized.FindReplace(L"$2", UIntString(numbers[1].ToInt()));

                                String msg = Str("Settings.Publish.Warning.VideoAspectRatio");
                                msg.FindReplace(L"$1", aspectLocalized);
                                strWarnings << msg;
                                hasErrors = true;
                            }
                        }
                    }

                    if (r->HasItem(TEXT("profile")))
                    {
                        String expectedProfile = r->GetString(TEXT("profile"));

                        if (!expectedProfile.CompareI(currentx264Profile))
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << Str("Settings.Publish.Warning.RecommendMainProfile");
                        }
                    }

                    if (r->HasItem(TEXT("keyint")))
                    {
                        int keyint = r->GetInt(TEXT("keyint"));
                        if (!keyframeInt || keyframeInt * 1000 > keyint)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.Keyint"), keyint / 1000);
                        }
                    }

                    break;
                }
            }
        }
    }

    if (hasErrors)
    {
        if (canOptimize)
            strWarnings << Str("Settings.Publish.Warning.CanOptimize");
        SetDlgItemText(hwnd, IDC_WARNINGS, strWarnings.Array());
    }
    else
        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
    SetCanOptimizeSettings(canOptimize);
}
Exemplo n.º 8
0
void GraphicsCaptureSource::AttemptCapture()
{
    //Log(TEXT("attempting to capture.."));

    if (!bUseHotkey)
        hwndTarget = FindWindow(strWindowClass, NULL);
    else
    {
        hwndTarget = hwndNextTarget;
        hwndNextTarget = NULL;
    }

    if (hwndTarget)
    {
        GetWindowThreadProcessId(hwndTarget, &targetProcessID);
        if(!targetProcessID)
        {
            AppWarning(TEXT("GraphicsCaptureSource::BeginScene: GetWindowThreadProcessId failed, GetLastError = %u"), GetLastError());
            bErrorAcquiring = true;
            return;
        }
    }
    else
    {
        if (!bUseHotkey && !warningID)
            warningID = API->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), StreamInfoPriority_High);

        bCapturing = false;

        return;
    }

    if(warningID)
    {
        API->RemoveStreamInfo(warningID);
        warningID = 0;
    }

    //-------------------------------------------
    // see if we already hooked the process.  if not, inject DLL

    char pOPStr[12];
    mcpy(pOPStr, "NpflUvhel{x", 12); //OpenProcess obfuscated
    for (int i=0; i<11; i++) pOPStr[i] ^= i^1;

    OPPROC pOpenProcess = (OPPROC)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), pOPStr);

    HANDLE hProcess = (*pOpenProcess)(PROCESS_ALL_ACCESS, FALSE, targetProcessID);
    if(hProcess)
    {
        //-------------------------------------------
        // load keepalive event

        hOBSIsAlive = CreateEvent(NULL, FALSE, FALSE, String() << OBS_KEEPALIVE_EVENT << UINT(targetProcessID));

        //-------------------------------------------

        hwndCapture = hwndTarget;

        hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << UINT(targetProcessID));
        if(hSignalRestart)
        {
            SetEvent(hSignalRestart);
            bCapturing = true;
            captureWaitCount = 0;
        }
        else
        {
            BOOL bSameBit = TRUE;

            if(Is64BitWindows())
            {
                BOOL bCurrentProcessWow64, bTargetProcessWow64;
                IsWow64Process(GetCurrentProcess(), &bCurrentProcessWow64);
                IsWow64Process(hProcess, &bTargetProcessWow64);

                bSameBit = (bCurrentProcessWow64 == bTargetProcessWow64);
            }

            if(bSameBit)
            {
                String strDLL;
                DWORD dwDirSize = GetCurrentDirectory(0, NULL);
                strDLL.SetLength(dwDirSize);
                GetCurrentDirectory(dwDirSize, strDLL);

                strDLL << TEXT("\\plugins\\GraphicsCapture\\GraphicsCaptureHook");

                BOOL b32bit = TRUE;
                if(Is64BitWindows())
                    IsWow64Process(hProcess, &b32bit);

                if(!b32bit)
                    strDLL << TEXT("64");

                strDLL << TEXT(".dll");

                if(InjectLibrary(hProcess, strDLL))
                {
                    captureWaitCount = 0;
                    bCapturing = true;
                }
                else
                {
                    AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Failed to inject library, GetLastError = %u"), GetLastError());

                    CloseHandle(hProcess);
                    hProcess = NULL;
                    bErrorAcquiring = true;
                }
            }
            else
            {
                String strDLLPath;
                DWORD dwDirSize = GetCurrentDirectory(0, NULL);
                strDLLPath.SetLength(dwDirSize);
                GetCurrentDirectory(dwDirSize, strDLLPath);

                strDLLPath << TEXT("\\plugins\\GraphicsCapture");

                BOOL b32bit = TRUE;
                if(Is64BitWindows())
                    IsWow64Process(hProcess, &b32bit);

                String strHelper = strDLLPath;
                strHelper << ((b32bit) ? TEXT("\\injectHelper.exe") : TEXT("\\injectHelper64.exe"));

                String strCommandLine;
                strCommandLine << TEXT("\"") << strHelper << TEXT("\" ") << UIntString(targetProcessID);

                //---------------------------------------

                PROCESS_INFORMATION pi;
                STARTUPINFO si;

                zero(&pi, sizeof(pi));
                zero(&si, sizeof(si));
                si.cb = sizeof(si);

                if(CreateProcess(strHelper, strCommandLine, NULL, NULL, FALSE, 0, NULL, strDLLPath, &si, &pi))
                {
                    int exitCode = 0;

                    WaitForSingleObject(pi.hProcess, INFINITE);
                    GetExitCodeProcess(pi.hProcess, (DWORD*)&exitCode);
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);

                    if(exitCode == 0)
                    {
                        captureWaitCount = 0;
                        bCapturing = true;
                    }
                    else
                    {
                        AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Failed to inject library, error code = %d"), exitCode);
                        bErrorAcquiring = true;
                    }
                }
                else
                {
                    AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Could not create inject helper, GetLastError = %u"), GetLastError());
                    bErrorAcquiring = true;
                }
            }
        }

        CloseHandle(hProcess);
        hProcess = NULL;

        if (!bCapturing)
        {
            CloseHandle(hOBSIsAlive);
            hOBSIsAlive = NULL;
        }
    }
    else
    {
        AppWarning(TEXT("GraphicsCaptureSource::BeginScene: OpenProcess failed, GetLastError = %u"), GetLastError());
        bErrorAcquiring = true;
    }
}
Exemplo n.º 9
0
void GraphicsCaptureSource::AttemptCapture()
{
    OSDebugOut(TEXT("attempting to capture..\n"));

    if (scmpi(strWindowClass, L"dwm") == 0)
    {
        hwndTarget = FindWindow(strWindowClass, NULL);
    }
    else
    {
        FindWindowData fwd;

        //FIXME: duplicated code, but we need OpenProcess here
        char pOPStr[12];
        mcpy(pOPStr, "NpflUvhel{x", 12); //OpenProcess obfuscated
        for (int i = 0; i<11; i++) pOPStr[i] ^= i ^ 1;

        fwd.pOpenProcess = (OPPROC)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), pOPStr);
        fwd.classname = strWindowClass;
        fwd.exename = strExecutable;
        fwd.hwnd = nullptr;

        EnumWindows(GraphicsCaptureFindWindow, (LPARAM)&fwd);

        hwndTarget = fwd.hwnd;
    }
    
    // use foregroundwindow as fallback (should be NULL if not using hotkey capture)
    if (!hwndTarget)
        hwndTarget = hwndNextTarget;

    hwndNextTarget = nullptr;
    
    OSDebugOut(L"Window: %s: ", strWindowClass.Array());
    if (hwndTarget)
    {
        OSDebugOut(L"Valid window\n");
        targetThreadID = GetWindowThreadProcessId(hwndTarget, &targetProcessID);
        if (!targetThreadID || !targetProcessID)
        {
            AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: GetWindowThreadProcessId failed, GetLastError = %u"), GetLastError());
            bErrorAcquiring = true;
            return;
        }
    }
    else
    {
        OSDebugOut(L"Bad window\n");
        if (!bUseHotkey && !warningID)
        {
            //Log(TEXT("GraphicsCaptureSource::AttemptCapture: Window '%s' [%s] not found."), strWindowClass.Array(), strExecutable.Array());
            //warningID = API->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), StreamInfoPriority_High);
        }

        bCapturing = false;

        return;
    }

    if (injectHelperProcess && WaitForSingleObject(injectHelperProcess, 0) == WAIT_TIMEOUT)
        return;

    if(warningID)
    {
        //API->RemoveStreamInfo(warningID);
        warningID = 0;
    }

    //-------------------------------------------
    // see if we already hooked the process.  if not, inject DLL

    char pOPStr[12];
    mcpy(pOPStr, "NpflUvhel{x", 12); //OpenProcess obfuscated
    for (int i=0; i<11; i++) pOPStr[i] ^= i^1;

    OPPROC pOpenProcess = (OPPROC)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), pOPStr);

    DWORD permission = useSafeHook ? (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ) : (PROCESS_ALL_ACCESS);

    HANDLE hProcess = (*pOpenProcess)(permission, FALSE, targetProcessID);
    if(hProcess)
    {
        DWORD dwSize = MAX_PATH;
        wchar_t processName[MAX_PATH];
        memset(processName, 0, sizeof(processName));

        QueryFullProcessImageName(hProcess, 0, processName, &dwSize);

        if (dwSize != 0 && scmpi(processName, lastProcessName) != 0)
        {
            if (processName[0])
            {
                wchar_t *fileName = srchr(processName, '\\');
                Log(L"Trying to hook process: %s", (fileName ? fileName+1 : processName));
            }
            scpy_n(lastProcessName, processName, MAX_PATH-1);
        }

        //-------------------------------------------
        // load keepalive event

        hOBSIsAlive = CreateEvent(NULL, FALSE, FALSE, String() << OBS_KEEPALIVE_EVENT << UINT(targetProcessID));

        //-------------------------------------------

        hwndCapture = hwndTarget;

        hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << UINT(targetProcessID));
        if(hSignalRestart)
        {
            OSDebugOut(L"Setting signal for process ID %u\n", targetProcessID);

            SetEvent(hSignalRestart);
            bCapturing = true;
            captureWaitCount = 0;
        }
        else
        {
            BOOL bSameBit = TRUE;
            BOOL b32bit = TRUE;

            if (Is64BitWindows())
            {
                BOOL bCurrentProcessWow64, bTargetProcessWow64;
                IsWow64Process(GetCurrentProcess(), &bCurrentProcessWow64);
                IsWow64Process(hProcess, &bTargetProcessWow64);

                bSameBit = (bCurrentProcessWow64 == bTargetProcessWow64);
            }

            if(Is64BitWindows())
                IsWow64Process(hProcess, &b32bit);

            //verify the hook DLL is accessible
            String strDLL;
            DWORD dwDirSize = GetCurrentDirectory(0, NULL);
            strDLL.SetLength(dwDirSize);
            GetCurrentDirectory(dwDirSize, strDLL);

            strDLL << TEXT("\\plugins\\GraphicsCapture\\GraphicsCaptureHook");

            if (!b32bit)
                strDLL << TEXT("64");

            strDLL << TEXT(".dll");

            if (!CheckFileIntegrity(strDLL.Array()))
            {
                OSDebugOut(L"Error acquiring\n");
                bErrorAcquiring = true;
            }
            else
            {

                if (bSameBit && !useSafeHook)
                {
                    if (InjectLibrary(hProcess, strDLL))
                    {
                        captureWaitCount = 0;
                        OSDebugOut(L"Inject successful\n");
                        bCapturing = true;
                    }
                    else
                    {
                        AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: Failed to inject library, GetLastError = %u"), GetLastError());
                        bErrorAcquiring = true;
                    }
                }
                else
                {
                    String strDLLPath;
                    DWORD dwDirSize = GetCurrentDirectory(0, NULL);
                    strDLLPath.SetLength(dwDirSize);
                    GetCurrentDirectory(dwDirSize, strDLLPath);

                    strDLLPath << TEXT("\\plugins\\GraphicsCapture");

                    String strHelper = strDLLPath;
                    strHelper << ((b32bit) ? TEXT("\\injectHelper.exe") : TEXT("\\injectHelper64.exe"));

                    if (!CheckFileIntegrity(strHelper.Array()))
                    {
                        bErrorAcquiring = true;
                    }
                    else
                    {
                        String strCommandLine;
                        strCommandLine << TEXT("\"") << strHelper << TEXT("\" ");
                        if (useSafeHook)
                            strCommandLine << UIntString(targetThreadID) << " 1";
                        else
                            strCommandLine << UIntString(targetProcessID) << " 0";

                        //---------------------------------------

                        PROCESS_INFORMATION pi;
                        STARTUPINFO si;

                        zero(&pi, sizeof(pi));
                        zero(&si, sizeof(si));
                        si.cb = sizeof(si);

                        if (CreateProcess(strHelper, strCommandLine, NULL, NULL, FALSE, 0, NULL, strDLLPath, &si, &pi))
                        {
                            int exitCode = 0;

                            CloseHandle(pi.hThread);

                            if (!useSafeHook)
                            {
                                WaitForSingleObject(pi.hProcess, INFINITE);
                                GetExitCodeProcess(pi.hProcess, (DWORD*)&exitCode);
                                CloseHandle(pi.hProcess);
                            }
                            else
                            {
                                injectHelperProcess = pi.hProcess;
                            }

                            if (exitCode == 0)
                            {
                                captureWaitCount = 0;
                                bCapturing = true;
                            }
                            else
                            {
                                AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: Failed to inject library, error code = %d"), exitCode);
                                bErrorAcquiring = true;
                            }
                        }
                        else
                        {
                            AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: Could not create inject helper, GetLastError = %u"), GetLastError());
                            bErrorAcquiring = true;
                        }
                    }
                }
            }
        }

        //save a copy of the process handle which we injected into, this lets us check for process exit in Tick()
        if (!hTargetProcess)
        {
            if (!DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hTargetProcess, 0, FALSE, DUPLICATE_SAME_ACCESS))
            {
                Log(TEXT("Warning: Couldn't DuplicateHandle, %d"), GetLastError());
            }
        }

        CloseHandle(hProcess);

        if (!bCapturing)
        {
            CloseHandle(hOBSIsAlive);
            hOBSIsAlive = NULL;
        }
    }
    else
    {
        AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: OpenProcess failed, GetLastError = %u"), GetLastError());
        bErrorAcquiring = true;
    }
}
Exemplo n.º 10
0
void Compiler::CreateSourceNativeFuncDef(ClassDefinition *classDef, StructDefinition *structDef, FunctionDefinition *func, String& funcName)
{
    String str;

    int count=0;

    if(classDef)
    {
        FunctionDefinition *curFunc = NULL;
        for(int i=0; i<classDef->Functions.Num(); i++)
        {
            curFunc = &classDef->Functions[i];
            if(curFunc == func)
                break;
            else if(scmp(curFunc->name, func->name) == 0)
                ++count;
        }
    }
    else if(!(func->flags & FUNC_OPERATOR))
    {
        if(structDef)
        {
            FunctionDefinition *curFunc = NULL;
            for(int i=0; i<structDef->Functions.Num(); i++)
            {
                curFunc = &structDef->Functions[i];
                if(curFunc == func)
                    break;
                else if(scmp(curFunc->name, func->name) == 0)
                    ++count;
            }
        }
        else
        {
            ModuleScriptData *module = Scripting->GetModule(curModule);
            FunctionDefinition *curFunc = NULL;
            for(int i=0; i<module->GlobalFunctionList.Num(); i++)
            {
                curFunc = &module->GlobalFunctionList[i];
                if(curFunc == func)
                    break;
                else if(scmp(curFunc->name, func->name) == 0)
                    ++count;
            }
        }
    }

    if(count)
        funcName << TEXT("_") << UIntString(count+1);

    str << TEXT("\r\nvoid ");

    if(func->flags & FUNC_STATIC)
        str << TEXT("ENGINEAPI ");

    if(classDef)
        str << classDef->classData->name << TEXT("::");
    else if(structDef)
        str << structDef->name << TEXT("::");
    else
        str << TEXT("ENGINEAPI ");

    str << funcName << TEXT("(CallStruct &cs)\r\n{\r\n");

    BOOL bFoundSomething = FALSE;

    if(func->returnType.type != DataType_Void)
    {
        String paramDefiner = ConvertTypeToString(func->returnType);

        str << TEXT("    ") << paramDefiner << TEXT("& returnVal = ");

        if( (func->returnType.type == DataType_Object) ||
            (func->returnType.type == DataType_Struct) ||
            ((func->returnType.type == DataType_Integer) && (scmp(func->returnType.name, TEXT("int")) != 0)))
        {
            str << TEXT("(") << paramDefiner << TEXT("&)");
        }

        str << TEXT("cs.Get");

        if(func->returnType.type == DataType_Object)
            str << TEXT("Object");
        else if(func->returnType.type == DataType_Handle)
            str << TEXT("Handle");
        else if(func->returnType.type == DataType_String)
            str << TEXT("String");
        else if(func->returnType.type == DataType_Struct)
            str << TEXT("Struct");
        else if(func->returnType.name == TEXT("bool"))
            str << TEXT("Bool");
        else if(func->returnType.type == DataType_Integer)
            str << TEXT("Int");
        else if(func->returnType.type == DataType_Float)
            str << TEXT("Float");
        else if(func->returnType.type == DataType_Type)
            str << TEXT("TypeInfo");

        str << TEXT("Out");

        str << TEXT("(RETURNVAL);\r\n");

        bFoundSomething = TRUE;
    }

    for(int i=0; i<func->Params.Num(); i++)
    {
        DefaultVariable *var = &func->Params[i];

        String paramDefiner = ConvertTypeToString(var->typeInfo, &var->subTypeInfo);

        if(var->flags & VAR_OUT)
        {
            str << TEXT("    ") << paramDefiner << TEXT(" &") << var->name << TEXT(" = ");
            if( (var->typeInfo.type == DataType_Object) ||
                (var->typeInfo.type == DataType_Struct) ||
                (var->typeInfo.type == DataType_List)   ||
                ((var->typeInfo.type == DataType_Integer) && (scmp(var->typeInfo.name, TEXT("int")) != 0)))
            {
                str << TEXT("(") << paramDefiner << TEXT("&)");
            }
        }
        else
        {
            if( (var->typeInfo.type == DataType_Struct) ||
                (var->typeInfo.type == DataType_List)   )
            {
                paramDefiner.InsertString(0, TEXT("const "));
                str << TEXT("    ") << paramDefiner << TEXT(" &") << var->name << TEXT(" = ");
                str << TEXT("(") << paramDefiner << TEXT("&)");
            }
            else
            {
                str << TEXT("    ") << paramDefiner << TEXT(" ") << var->name << TEXT(" = ");
                if( (var->typeInfo.type == DataType_Object) ||
                    ((var->typeInfo.type == DataType_Integer) && (scmp(var->typeInfo.name, TEXT("int")) != 0)))
                {
                    str << TEXT("(") << paramDefiner << TEXT(")");
                }
            }
        }

        str << TEXT("cs.Get");

        if(var->typeInfo.type == DataType_Object)
            str << TEXT("Object");
        else if(var->typeInfo.type == DataType_Handle)
            str << TEXT("Handle");
        else if(var->typeInfo.type == DataType_String)
            str << TEXT("String");
        else if(var->typeInfo.type == DataType_Struct)
            str << TEXT("Struct");
        else if(var->typeInfo.name == TEXT("bool"))
            str << TEXT("Bool");
        else if(var->typeInfo.type == DataType_Integer)
            str << TEXT("Int");
        else if(var->typeInfo.type == DataType_List)
            str << TEXT("List");
        else if(var->typeInfo.type == DataType_Float)
            str << TEXT("Float");

        if(var->flags & VAR_OUT)
            str << TEXT("Out");

        str << FormattedString(TEXT("(%d);\r\n"), i);

        bFoundSomething = TRUE;
    }

    if(bFoundSomething)
        str << TEXT("\r\n");

    //------------------------------------------------

    //str << TEXT("    //code goes here\r\n}\r\n");

    if(func->returnType.type != DataType_Void)
        str << TEXT("    returnVal = ");
    else
        str << TEXT("    ");

    if(func->flags & FUNC_OPERATOR)
    {
        if(structDef)
        {
            if(func->Params.Num() == 1)
                str << TEXT("(") << TEXT("*this ") << func->name << TEXT(" ") << func->Params[0].name;
            else
                str << func->name << TEXT("(*this");
        }
        else
        {
            if(func->Params.Num() == 2)
                str << TEXT("(") << func->Params[0].name << TEXT(" ") << func->name << TEXT(" ") << func->Params[1].name;
            else
                str << TEXT("(") << func->name << func->Params[0].name;
        }
    }
    else
    {
        str << func->name << TEXT("(");

        for(int i=0; i<func->Params.Num(); i++)
        {
            Variable *var = &func->Params[i];

            if(i)
                str << TEXT(", ");

            str << var->name;
        }
    }

    str << TEXT(");\r\n}\r\n");

    //------------------------------------------------

    if(classDef)
        strCurNativeClassDefs << str;
    else if(structDef)
        strCurNativeStructDefs << str;
    else
        strCurNativeDefs << str;
}
Exemplo n.º 11
0
void Compiler::CreateSourceGlobalNative(FunctionDefinition *func)
{
    String funcName;

    if(func->flags & FUNC_OPERATOR)
    {
        String operatorName;
        if((func->name == TEXT("-")) && (func->Params.Num() == 1))
            operatorName = TEXT("Negate");
        else
            operatorName = GetOperatorName(func->name);

        if(func->Params.Num() == 2)
            funcName << TEXT("Native_operator_") << func->Params[0].typeInfo.name << TEXT("_") << operatorName << TEXT("_") << func->Params[1].typeInfo.name;
        if(func->Params.Num() == 1)
            funcName << TEXT("Native_operator_") << func->returnType.name << TEXT("_") << operatorName;
    }
    else
        funcName << TEXT("NativeGlobal_") << func->name;

    CreateSourceNativeFuncDef(NULL, NULL, func, funcName);

    //----------------------------------

    strNativeLinks << TEXT("    Scripting->DefineNativeGlobal((NATIVECALLBACK)&") << funcName << TEXT(", 0x") << UIntString(func->funcOffset, 16) << TEXT(");\r\n");

    //----------------------------------

    strCurNativeDecs << TEXT("Declare_Native_Global(") << funcName << TEXT(");\r\n");
}
Exemplo n.º 12
0
void Compiler::CreateSourceClass(ClassDefinition *classDef)
{
    if(classDef->classData->bPureScriptClass)
        return;

    String str;

    String parentName = classDef->Parent ? classDef->Parent->classData->name : TEXT("OrphanageWorker");

    str << TEXT("\r\nclass ") << classDef->classData->name;
    str << TEXT(" : public ") << parentName;
    str << TEXT("\r\n{\r\n    ");

    str << TEXT("DeclareClass(");

    str << classDef->classData->name << TEXT(", ") << parentName << TEXT(");\r\n");

    BOOL bFoundNativeClassLinks = FALSE;

    if(classDef->Variables.Num() || classDef->Functions.Num())
        str << TEXT("\r\npublic:\r\n");

    BOOL bFoundSomething = FALSE;
    BOOL bFoundVars = FALSE;

    if(classDef->Variables.Num())
    {
        if(strNativeClassLinks.IsEmpty())
            strNativeClassLinks << TEXT("\r\n    Class* curClass;\r\n");
        strNativeClassLinks << TEXT("\r\n    curClass = GetClass(") << classDef->classData->name << TEXT(");\r\n    assert(curClass);\r\n\r\n    if(curClass)\r\n    {\r\n");

        bFoundNativeClassLinks = TRUE;
        bFoundVars = TRUE;

        if(!bFoundSomething)
        {
            str << TEXT("    //<Script module=\"") << curModule << TEXT("\" classdecs=\"") << classDef->classData->name << ("\">");
            bFoundSomething = TRUE;
        }

        for(int i=0; i<classDef->Variables.Num(); i++)
        {
            DefaultVariable *var = &classDef->Variables[i];

            str << TEXT("\r\n    ");

            str << ConvertTypeToString(var->typeInfo) << TEXT(" ") << var->name;

            if(var->numElements)
                str << FormattedString(TEXT("[%d]"), var->numElements);

            str << TEXT(";");

            strNativeClassLinks << TEXT("        curClass->DefineNativeVariable(offsetof(") << classDef->classData->name
                                << TEXT(", ") << var->name << TEXT("), ") << IntString(i) << TEXT(");\r\n");
        }
    }

    String classDecs;
    String internalDecs;

    BOOL bFoundInternalFunc = FALSE;
    BOOL bFoundImplementable = FALSE;

    for(int i=0; i<classDef->Functions.Num(); i++)
    {
        FunctionDefinition *func = &classDef->Functions[i];

        if(func->flags & FUNC_IMPLEMENTABLE)
        {
            if(!bFoundSomething)
            {
                classDecs << TEXT("    //<Script module=\"") << curModule << TEXT("\" classdecs=\"") << classDef->classData->name << ("\">");
                bFoundSomething = TRUE;
            }

            if(!bFoundImplementable)
            {
                if(bFoundVars)
                    classDecs << TEXT("\r\n");
                bFoundImplementable = TRUE;
            }

            classDecs << TEXT("\r\n    ") << ConvertTypeToString(func->returnType) << TEXT(" script") << func->name << TEXT("(");

            for(int j=0; j<func->Params.Num(); j++)
            {
                if(j) classDecs << TEXT(", ");
                DefaultVariable *var = &func->Params[j];

                classDecs << ConvertParamTypeToString(var) << TEXT(" ") << var->name;
            }

            if(func->Params.Num())
                classDecs << TEXT(")\r\n    {\r\n        CallStruct cs;\r\n        cs.SetNumParams(") << UIntString(func->Params.Num()) << TEXT(");\r\n");
            else
                classDecs << TEXT(")\r\n    {\r\n        CallStruct cs;");

            for(int j=0; j<func->Params.Num(); j++)
            {
                DefaultVariable *var = &func->Params[j];

                classDecs << TEXT("        cs.Set");
                
                switch(var->typeInfo.type)
                {
                    case DataType_Integer: classDecs << TEXT("Int");          break;
                    case DataType_Float:   classDecs << TEXT("Float");        break;
                    case DataType_Handle:  classDecs << TEXT("Handle");       break;
                    case DataType_Object:  classDecs << TEXT("Object");       break;
                    case DataType_String:  classDecs << TEXT("String");       break;
                    case DataType_Struct:  classDecs << TEXT("Struct");       break;
                    case DataType_Type:    classDecs << TEXT("TypeDataInfo"); break;
                }

                classDecs << TEXT("(") << UIntString(j) << TEXT(", ");

                if(var->typeInfo.type == DataType_Object)
                    classDecs << TEXT("(Object*)");
                else if((var->typeInfo.type == DataType_Integer) && (scmp(var->typeInfo.name, TEXT("int")) != 0))
                    classDecs << TEXT("(int)");

                if(var->typeInfo.type == DataType_Struct)
                    classDecs << TEXT("&") << var->name << TEXT(", ") << UIntString(var->typeInfo.size);
                else
                    classDecs << var->name;

                classDecs << TEXT(");\r\n");
            }

            classDecs << TEXT("\r\n        GetLocalClass()->CallScriptMember(this, ") << UIntString(func->funcOffset-classDef->functionStartIndex) << TEXT(", cs);\r\n");

            if(func->returnType.type != DataType_Void)
            {
                classDecs << TEXT("\r\n        return ");

                if(func->returnType.type == DataType_Struct)
                    classDecs << TEXT("(") << func->returnType.name << TEXT("&)cs.GetStruct(RETURNVAL);\r\n");
                else
                {
                    classDecs << TEXT("cs.Get");
                    switch(func->returnType.type)
                    {
                        case DataType_Integer: classDecs << TEXT("Int");      break;
                        case DataType_Float:   classDecs << TEXT("Float");    break;
                        case DataType_Struct:  classDecs << TEXT("Struct");   break;
                        case DataType_Handle:  classDecs << TEXT("Handle");   break;
                        case DataType_Object:  classDecs << TEXT("Object");   break;
                        case DataType_String:  classDecs << TEXT("String");   break;
                        case DataType_Type:    classDecs << TEXT("TypeInfo"); break;
                    }

                    classDecs << TEXT("(RETURNVAL);\r\n"); 
                }
            }

            classDecs << TEXT("    }\r\n");
        }
        if(func->flags & FUNC_INTERNAL)
        {
            if(!bFoundSomething)
            {
                classDecs << TEXT("    //<Script module=\"") << curModule << TEXT("\" classdecs=\"") << classDef->classData->name << ("\">");
                bFoundSomething = TRUE;
            }

            String funcName;
            funcName << TEXT("native_");
            if(func->name.IsEmpty()) //constructor
                funcName << classDef->classData->name;
            else
                funcName << func->name;
            CreateSourceNativeFuncDef(classDef, NULL, func, funcName);

            if(!bFoundNativeClassLinks)
            {
                if(strNativeClassLinks.IsEmpty())
                    strNativeClassLinks << TEXT("\r\n    Class* curClass;\r\n");
                strNativeClassLinks << TEXT("\r\n    curClass = GetClass(") << classDef->classData->name << TEXT(");\r\n    assert(curClass);\r\n\r\n    if(curClass)\r\n    {\r\n");

                bFoundNativeClassLinks = TRUE;
            }
            else if(!bFoundInternalFunc)
                strNativeClassLinks << TEXT("\r\n");

            if(func->flags & FUNC_STATIC)
            {
                strNativeClassLinks << FormattedString(TEXT("        curClass->DefineNativeStaticMember((NATIVECALLBACK)&%s::%s, 0x%lX);\r\n"), classDef->classData->name, funcName.Array(), i);
                internalDecs << TEXT("    Declare_Internal_StaticMember(") << funcName << TEXT(");\r\n");
            }
            else
            {
                strNativeClassLinks << FormattedString(TEXT("        curClass->DefineNativeMember((OBJECTCALLBACK)&%s::%s, 0x%lX);\r\n"), classDef->classData->name, funcName.Array(), i);
                internalDecs << TEXT("    Declare_Internal_Member(") << funcName << TEXT(");\r\n");
            }

            bFoundInternalFunc = TRUE;
        }
    }

    if(bFoundNativeClassLinks)
    {
        strNativeClassLinks << TEXT("    }\r\n");

        if(bFoundVars && !bFoundImplementable && internalDecs.IsValid())
            classDecs << TEXT("\r\n");

        classDecs << TEXT("\r\n") << internalDecs;
    }

    if(bFoundSomething)
    {
        classDecs << TEXT("    //</Script>");
        str << classDecs;
    }

    str << TEXT("\r\n};\r\n");

    //----------------------------------

    strCurClasses << str;

    //----------------------------------

    strForwards << TEXT("class ") << classDef->classData->name << TEXT(";\r\n");

    //----------------------------------

    if(classDef->classData->IsAbstract())
        strCurClassDefs << TEXT("DefineAbstractClass(");
    else
        strCurClassDefs << TEXT("DefineClass("); 
    strCurClassDefs << classDef->classData->name << TEXT(");\r\n");
}
Exemplo n.º 13
0
void GraphicsCaptureSource::AttemptCapture()
{
    hwndTarget = FindWindow(strWindowClass, NULL);
    if(hwndTarget)
    {
        GetWindowThreadProcessId(hwndTarget, &targetProcessID);
        if(!targetProcessID)
        {
            AppWarning(TEXT("GraphicsCaptureSource::BeginScene: GetWindowThreadProcessId failed, GetLastError = %u"), GetLastError());
            bErrorAcquiring = true;
            return;
        }
    }
    else
    {
        if(!warningID)
            warningID = API->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), StreamInfoPriority_High);

        bCapturing = false;

        return;
    }

    if(warningID)
    {
        API->RemoveStreamInfo(warningID);
        warningID = 0;
    }

    //-------------------------------------------
    // see if we already hooked the process.  if not, inject DLL

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetProcessID);
    if(hProcess)
    {
        hwndCapture = hwndTarget;

        hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << int(targetProcessID));
        if(hSignalRestart)
        {
            SetEvent(hSignalRestart);
            bCapturing = true;
            captureWaitCount = 0;
        }
        else
        {
            String strDLLPath;
            DWORD dwDirSize = GetCurrentDirectory(0, NULL);
            strDLLPath.SetLength(dwDirSize);
            GetCurrentDirectory(dwDirSize, strDLLPath);

            strDLLPath << TEXT("\\plugins\\GraphicsCapture");

            BOOL b32bit = TRUE;
            if(Is64BitWindows())
                IsWow64Process(hProcess, &b32bit);

            String strHelper = strDLLPath;
            strHelper << ((b32bit) ? TEXT("\\injectHelper.exe") : TEXT("\\injectHelper64.exe"));

            String strCommandLine;
            strCommandLine << TEXT("\"") << strHelper << TEXT("\" ") << UIntString(targetProcessID);

            //---------------------------------------

            PROCESS_INFORMATION pi;
            STARTUPINFO si;

            zero(&pi, sizeof(pi));
            zero(&si, sizeof(si));
            si.cb = sizeof(si);

            if(CreateProcess(strHelper, strCommandLine, NULL, NULL, FALSE, 0, NULL, strDLLPath, &si, &pi))
            {
                int exitCode = 0;

                WaitForSingleObject(pi.hProcess, INFINITE);
                GetExitCodeProcess(pi.hProcess, (DWORD*)&exitCode);
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);

                if(exitCode == 0)
                {
                    captureWaitCount = 0;
                    bCapturing = true;
                }
                else
                {
                    AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Failed to inject library, error code = %d"), exitCode);
                    bErrorAcquiring = true;
                }
            }
            else
            {
                AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Could not create inject helper, GetLastError = %u"), GetLastError());
                bErrorAcquiring = true;
            }
        }

        CloseHandle(hProcess);
        hProcess = NULL;
    }
    else
    {
        AppWarning(TEXT("GraphicsCaptureSource::BeginScene: OpenProcess failed, GetLastError = %u"), GetLastError());
        bErrorAcquiring = true;
    }
}