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()); }
~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); }
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"); }
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; }
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; }
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; }
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); }
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; } }
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; } }
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; }
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"); }
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"); }
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; } }