XBOOL XFile::LoadText(XPCTSTR strFile, XString8 &strTxt) { XFile file; if(!file.Open(strFile,XFile::XREAD)) return XFALSE; int l=file.GetLength(); if(l<=0) {file.Close();return XFALSE;} strTxt.SetSize(l+1,XFALSE); file.Read(strTxt.GetData(),l); file.Close(); return XTRUE; }
BOOL ConfigFile::LoadFile(DWORD dwOpenMode) { XFile file; if(!file.Open(strFileName, XFILE_READ, dwOpenMode)) { //Log(TEXT("Couldn't load config file: \"%s\""), (TSTR)strFileName); return 0; } if(bOpen) Close(); dwLength = (DWORD)file.GetFileSize(); LPSTR lpTempFileData = (LPSTR)Allocate(dwLength+5); file.Read(&lpTempFileData[2], dwLength); lpTempFileData[0] = lpTempFileData[dwLength+2] = 13; lpTempFileData[1] = lpTempFileData[dwLength+3] = 10; lpTempFileData[dwLength+4] = 0; file.Close(); lpFileData = utf8_createTstr(lpTempFileData); dwLength = slen(lpFileData); Free(lpTempFileData); bOpen = 1; return 1; }
BOOL MyAppWindow :: SaveFile( void ) { XFile savefile; XString s; mle->GetText( &s ); /* now open the file, create a new one if the given filename is not existing, otherwise overwrite */ /* it. open the file for write-access, dont allow any other programm to use the file while it is open*/ if( savefile.Open( path, XFILE_CREATE_IF_NEW | XFILE_REPLACE_EXISTING, XFILE_SHARE_DENYNONE | XFILE_WRITEONLY, s.GetLength()) == 0) { /* set the file-cursor to the beginning of the file */ savefile.Seek( 0, FILE_BEGIN); /*save the string */ savefile.Write ( (char*) s, s.GetLength()); /* close the file */ savefile.Close(); saved = TRUE; return TRUE; } else { XMessageBox( "could not open file", "error", MB_OK| MB_ERROR); return FALSE; } }
void STDCALL TerminateXT() { if(bBaseLoaded) { FreeProfileData(); delete locale; locale = NULL; if(MainAllocator) { Alloc *curAlloc = MainAllocator; MainAllocator = new DefaultAlloc; delete curAlloc; delete MainAllocator; MainAllocator = NULL; } bBaseLoaded = 0; if(LogFile.IsOpen()) LogFile.Close(); OSExit(); } }
LPBYTE ResourceManager::LoadSoundData(CTSTR lpName) { traceIn(ResourceManager::LoadSoundData); XFile file; LPBYTE lpData = NULL; //---------------------------------------- String path; if(!Engine::ConvertResourceName(lpName, TEXT("sounds"), path)) return NULL; //---------------------------------------- if(file.Open(path, XFILE_READ, XFILE_OPENEXISTING)) { DWORD dwFileSize = file.GetFileSize(); lpData = (LPBYTE)Allocate(dwFileSize); file.Read(lpData, dwFileSize); SoundList << lpData; SoundNames << lpName; file.Close(); } else AppWarning(TEXT("Resource Manager: Could not create sound from file \"%s\""), lpName); return lpData; traceOut; }
/* load a file */ BOOL MyAppWindow :: LoadFile ( char * p) { // is there already a file loaded or has the user entered some text? if(loaded == FALSE && saved == TRUE) { //no, we load the file in the window of the current thread XFile loadfile; /* now open the file, fail if given filename is not existing */ /* open the file for read-access, dont allow any other programm to use the file while it is open*/ if( loadfile.Open( p, XFILE_FAIL_IF_NEW | XFILE_OPEN_EXISTING, XFILE_SHARE_DENYWRITE | XFILE_READONLY ) == 0) { XString s; loading = TRUE; //how large is the file? XFileInfo info; loadfile.GetFileInfo( &info ); LONG size = info.GetFileSize(); //read the complete file loadfile.Read ( (PVOID) s.GetBuffer(info.GetFileSize() + 1), size); s.ReleaseBuffer( info.GetFileSize() ); //set the XString content to the mle mle->SetText( s ); //dontïforget to close the file loadfile.Close(); loaded = TRUE; path = p; mle->SetFocus(); GetText( &s ); s+= " - "; s+= p; SetText( s ); loading = FALSE; return TRUE; } else { XMessageBox( p, "couldnït open File!", MB_OK|MB_ERROR); return FALSE; } } else { //there is a file loaded, or the user has entered some text, so // we create a new window and load the file // XResource res( IDM_MAIN, ((MyApp*) GetProcess())->GetResourceLibrary()); MyAppWindow * win = new MyAppWindow( IDM_MAIN ); win->LoadFile(p); return TRUE; } }
BOOL CalculateFileHash (TCHAR *path, BYTE *hash) { BYTE buff[65536]; HCRYPTHASH hHash; if (!CryptCreateHash(hProvider, CALG_SHA1, 0, 0, &hHash)) return FALSE; XFile file; if (file.Open(path, XFILE_READ, OPEN_EXISTING)) { for (;;) { DWORD read = file.Read(buff, sizeof(buff)); if (!read) break; if (!CryptHashData(hHash, buff, read, 0)) { CryptDestroyHash(hHash); file.Close(); return FALSE; } } } else { CryptDestroyHash(hHash); return FALSE; } file.Close(); DWORD hashLength = 20; if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &hashLength, 0)) return FALSE; CryptDestroyHash(hHash); return TRUE; }
void STDCALL CriticalExit() { if(bBaseLoaded) { bBaseLoaded = 0; if(LogFile.IsOpen()) LogFile.Close(); OSCriticalExit(); } }
void XConfig::Save() { if(RootElement) { XFile file; file.Open(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); WriteFileData(file, 0, RootElement); file.Close(); } }
void PackageFile::Extract(std::string outPath) { if (!packageRead) { this->ReadPackage(); } // Loop the directory entries auto it = this->entries->GetContainer()->begin(); while (it != this->entries->GetContainer()->end()) { DirectoryEntry* entry = *it; std::string finalFilePath; if (outPath != "") { finalFilePath.append(outPath); finalFilePath.append("\\"); } finalFilePath.append(entry->fileName); XFile newFile = XFile(finalFilePath); // Need to ensure the file path (folders are contained in the file entry name) // coming from the package is created. std::string parentDir = GetParentDirectoryPath(finalFilePath); // This is used to skip creating the directory when going over a file without directories. if(parentDir != finalFilePath) CreatePath(parentDir); int bufSize = 0; char* buf = (char*)this->GetFile(entry->fileName, bufSize); assert(bufSize == entry->fileLength); newFile.OpenCreate(); newFile.Write(buf, entry->fileLength); newFile.Close(); it++; } }
void XConfig::Close(bool bSave) { if(RootElement && bSave) { XFile file; file.Open(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); WriteFileData(file, 0, RootElement); file.Close(); } delete RootElement; RootElement = NULL; strFileName.Clear(); }
/*@ XBitmap::LoadBMP(const char* filename) @group loading a bitmap @remarks Load a bitmap from a file. This method works faster than Load() but can only load bitmpas in OS2-BMP format @parameters char * fileName filename of the file to load @exceptions If the method fails to create a new bitmap an exception of the type XException is thrown. */ void XBitmap :: LoadBMP(const char* filename) { if (hbm) GpiDeleteBitmap(hbm); hbm = 0; XFile file; PBITMAPFILEHEADER p; if (file.Open(filename, XFILE_FAIL_IF_NEW | XFILE_OPEN_EXISTING, XFILE_READONLY, XFILE_SHARE_DENYNONE ) == 0) { XFileInfo info; file.GetFileInfo(&info); file.Seek(0, XFILE_BEGIN); p = (PBITMAPFILEHEADER) malloc(info.GetFileSize()); file.Read(p, info.GetFileSize()); file.Close(); } else OOLThrow( "couldnït open file!", -1); if (owner ) { hps = WinGetPS(owner->GetHandle()); hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) &p->bmp, CBM_INIT, (PBYTE) p + p->offBits, (PBITMAPINFO2) &p->bmp); if(hbm == 0) OOLThrow("error creating bitmap", 3); } else SetData((BITMAPINFOHEADER2 *) &p->bmp, p->offBits); free(p); XSize s; GetDimensions(&s); width = cx = s.GetWidth(); height = cy = s.GetHeight(); if (hbm == GPI_ERROR) { ULONG error = WinGetLastError(XApplication::GetApplication()->GetAnchorBlock()); OOLThrow("couldnït load bitmap", error); } return; }
BOOL ConfigFile::LoadFile(DWORD dwOpenMode) { XFile file; if(!file.Open(strFileName, XFILE_READ, dwOpenMode)) { //Log(TEXT("Couldn't load config file: \"%s\""), (TSTR)strFileName); return 0; } if(bOpen) Close(); dwLength = (DWORD)file.GetFileSize(); if (dwLength >= 3) // remove BOM if present { char buff[3]; file.Read(&buff, 3); if (memcmp(buff, "\xEF\xBB\xBF", 3)) file.SetPos(0, XFILE_BEGIN); else dwLength -= 3; } LPSTR lpTempFileData = (LPSTR)Allocate(dwLength+5); file.Read(&lpTempFileData[2], dwLength); lpTempFileData[0] = lpTempFileData[dwLength+2] = 13; lpTempFileData[1] = lpTempFileData[dwLength+3] = 10; lpTempFileData[dwLength+4] = 0; file.Close(); lpFileData = utf8_createTstr(lpTempFileData); dwLength = slen(lpFileData); Free(lpTempFileData); bOpen = 1; return 1; }
Effect::Effect(GraphicsSystem *curSystem, CTSTR lpEffectFile) { traceIn(Effect::Effect); system = curSystem; String strEffectFile = lpEffectFile; strEffectFile.FindReplace(TEXT("\\"), TEXT("/")); strEffectDir = GetPathDirectory(strEffectFile); effectPath = strEffectFile; XFile chi; if(!chi.Open(strEffectFile, XFILE_READ, XFILE_OPENEXISTING)) ErrOut(TEXT("Could not open effect file '%s'"), strEffectFile.Array()); String strFile; chi.ReadFileToString(strFile); chi.Close(); String errors; bProcessing = TRUE; system->curProcessingEffect = this; EffectProcessor test; if(!test.ProcessEffect(this, GetPathFileName(strEffectFile, TRUE), strFile, errors)) ProgramBreak(); bProcessing = FALSE; system->curProcessingEffect = NULL; hViewProj = GetParameterByName(TEXT("ViewProj")); hWorld = GetParameterByName(TEXT("World")); hScale = GetParameterByName(TEXT("World")); traceOut; }
void XConfig::SaveTo(CTSTR lpPath) { if (RootElement) { String tmpPath = lpPath; tmpPath.AppendString(TEXT(".tmp")); XFile file; if (file.Open(tmpPath, XFILE_WRITE, XFILE_CREATEALWAYS)) { if (WriteFileData(file, 0, RootElement)) { file.Close(); OSRenameFile(tmpPath, lpPath); } else { Log(TEXT("XConfig::SaveTo: WriteFileData failed while writing %s."), lpPath); } } } }
void XConfig::Save() { if(RootElement) { String tmpPath = strFileName; tmpPath.AppendString(TEXT(".tmp")); XFile file; if (file.Open(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS)) { if (WriteFileData(file, 0, RootElement)) { file.Close(); OSRenameFile(tmpPath, strFileName); } else { Log(TEXT("XConfig::Save: WriteFileData failed while writing %s."), strFileName.Array()); } } } }
BOOL ConfigFile::SaveAs(CTSTR lpPath) { XFile newFile; String tmpPath = lpPath; tmpPath.AppendString(TEXT(".tmp")); if (newFile.Open(tmpPath, XFILE_WRITE, XFILE_CREATEALWAYS)) { if (newFile.Write("\xEF\xBB\xBF", 3) != 3) return FALSE; if (!newFile.WriteAsUTF8(lpFileData)) return FALSE; newFile.Close(); if (!OSRenameFile(tmpPath, lpPath)) Log(TEXT("ConfigFile::SaveAs: Unable to move new config file %s to %s"), tmpPath.Array(), lpPath); strFileName = lpPath; return TRUE; } return FALSE; }
~FLVFileStream() { UINT64 fileSize = fileOut.GetPos(); fileOut.Close(); XFile file; if(file.Open(strFile, XFILE_WRITE, XFILE_OPENEXISTING)) { double doubleFileSize = double(fileSize); double doubleDuration = double(lastTimeStamp/1000); file.SetPos(metaDataPos+0x28, XFILE_BEGIN); QWORD outputVal = *reinterpret_cast<QWORD*>(&doubleDuration); outputVal = fastHtonll(outputVal); file.Write(&outputVal, 8); file.SetPos(metaDataPos+0x3B, XFILE_BEGIN); outputVal = *reinterpret_cast<QWORD*>(&doubleFileSize); outputVal = fastHtonll(outputVal); file.Write(&outputVal, 8); file.Close(); } }
bool XConfig::Open(CTSTR lpFile) { if(RootElement) { if(strFileName.CompareI(lpFile)) return true; Close(); } //------------------------------------- XFile file; if(!file.Open(lpFile, XFILE_READ, XFILE_OPENALWAYS)) return false; RootElement = new XElement(this, NULL, TEXT("Root")); strFileName = lpFile; DWORD dwFileSize = (DWORD)file.GetFileSize(); LPSTR lpFileDataUTF8 = (LPSTR)Allocate(dwFileSize+1); zero(lpFileDataUTF8, dwFileSize+1); file.Read(lpFileDataUTF8, dwFileSize); TSTR lpFileData = utf8_createTstr(lpFileDataUTF8); Free(lpFileDataUTF8); //------------------------------------- // remove comments TSTR lpComment, lpEndComment; while(lpComment = sstr(lpFileData, TEXT("/*"))) { lpEndComment = sstr(lpFileData, TEXT("*/")); assert(lpEndComment); assert(lpComment < lpEndComment); if(!lpEndComment || (lpComment > lpEndComment)) { file.Close(); Close(false); Free(lpFileData); CrashError(TEXT("Error parsing X file '%s'"), strFileName.Array()); } mcpy(lpComment, lpEndComment+3, slen(lpEndComment+3)+1); } //------------------------------------- TSTR lpTemp = lpFileData; if(!ReadFileData(RootElement, 0, lpTemp)) { for(DWORD i=0; i<RootElement->SubItems.Num(); i++) delete RootElement->SubItems[i]; CrashError(TEXT("Error parsing X file '%s'"), strFileName.Array()); Free(lpFileData); Close(false); file.Close(); } Free(lpFileData); file.Close(); return true; }
BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode) { HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; URL_COMPONENTS urlComponents; BOOL secure = FALSE; BOOL ret = FALSE; String hostName, path; const TCHAR *acceptTypes[] = { TEXT("*/*"), NULL }; hostName.SetLength(256); path.SetLength(1024); zero(&urlComponents, sizeof(urlComponents)); urlComponents.dwStructSize = sizeof(urlComponents); urlComponents.lpszHostName = hostName; urlComponents.dwHostNameLength = hostName.Length(); urlComponents.lpszUrlPath = path; urlComponents.dwUrlPathLength = path.Length(); WinHttpCrackUrl(url, 0, 0, &urlComponents); if (urlComponents.nPort == 443) secure = TRUE; hSession = WinHttpOpen(OBS_VERSION_STRING, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!hSession) goto failure; hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0); if (!hConnect) goto failure; hRequest = WinHttpOpenRequest(hConnect, TEXT("GET"), path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE|WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH); if (!hRequest) goto failure; BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); else goto failure; TCHAR statusCode[8]; DWORD statusCodeLen; statusCodeLen = sizeof(statusCode); if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX)) goto failure; *responseCode = wcstoul(statusCode, NULL, 10); if (bResults && *responseCode == 200) { BYTE buffer[16384]; DWORD dwSize, dwOutSize; XFile updateFile; if (!updateFile.Open(outputPath, XFILE_WRITE, CREATE_ALWAYS)) goto failure; do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) goto failure; if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize)) { goto failure; } else { if (!dwOutSize) break; if (!updateFile.Write(buffer, dwOutSize)) goto failure; } } while (dwSize > 0); updateFile.Close(); } ret = TRUE; failure: if (hSession) WinHttpCloseHandle(hSession); if (hConnect) WinHttpCloseHandle(hConnect); if (hRequest) WinHttpCloseHandle(hRequest); return ret; }
void ConfigFile::SetKey(CTSTR lpSection, CTSTR lpKey, CTSTR newvalue) { assert(lpSection); assert(lpKey); TSTR lpTemp = lpFileData, lpEnd = &lpFileData[dwLength], lpSectionStart; DWORD dwSectionNameSize = slen(lpSection), dwKeyNameSize = slen(lpKey); BOOL bInSection = 0; do { lpTemp = sstr(lpTemp, TEXT("\n[")); if(!lpTemp) break; lpTemp += 2; if((scmpi_n(lpTemp, lpSection, dwSectionNameSize) == 0) && (lpTemp[dwSectionNameSize] == ']')) { bInSection = 1; lpSectionStart = lpTemp = schr(lpTemp, '\n')+1; break; } }while(lpTemp < lpEnd); if(!bInSection) { lpTemp -= 2; XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], dwLength-4); file.Write("\r\n[", 3); file.WriteAsUTF8(lpSection, dwSectionNameSize); file.Write("]\r\n", 3); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } do { if(*lpTemp == '[') { XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpSectionStart-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpSectionStart, slen(lpSectionStart)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } else if(*(LPWORD)lpTemp == '//') { lpTemp = schr(lpTemp, '\n')+1; continue; } else if(bInSection) { if((scmpi_n(lpTemp, lpKey, dwKeyNameSize) == 0) && (lpTemp[dwKeyNameSize] == '=')) { lpTemp = &lpTemp[dwKeyNameSize+1]; TSTR lpNextLine = schr(lpTemp, '\r'); int newlen = slen(newvalue); if ((*lpTemp == '\r' && *newvalue == '\0') || (lpNextLine - lpTemp == newlen && !scmp_n(lpTemp, newvalue, newlen))) return; String tmpFileName = strFileName; tmpFileName += TEXT(".tmp"); XFile file; if (file.Open(tmpFileName, XFILE_WRITE, XFILE_CREATEALWAYS)) { if (file.Write("\xEF\xBB\xBF", 3) != 3) return; if (!file.WriteAsUTF8(&lpFileData[2], DWORD(lpTemp - lpFileData - 2))) return; if (!file.WriteAsUTF8(newvalue, slen(newvalue))) return; if (!file.WriteAsUTF8(lpNextLine, slen(lpNextLine) - 2)) return; file.Close(); if (!OSRenameFile(tmpFileName, strFileName)) Log(TEXT("ConfigFile::SetKey: Unable to move new config file %s to %s"), tmpFileName.Array(), strFileName.Array()); } if(LoadFile(XFILE_OPENEXISTING)) LoadData(); return; } } lpTemp = schr(lpTemp, '\n')+1; }while(lpTemp < lpEnd); XFile file(strFileName, XFILE_WRITE, XFILE_CREATEALWAYS); file.Write("\xEF\xBB\xBF", 3); file.WriteAsUTF8(&lpFileData[2], DWORD(lpSectionStart-lpFileData-2)); file.WriteAsUTF8(lpKey, dwKeyNameSize); file.Write("=", 1); file.WriteAsUTF8(newvalue, slen(newvalue)); file.Write("\r\n", 2); file.WriteAsUTF8(lpSectionStart, slen(lpSectionStart)-2); file.Close(); if(LoadFile(XFILE_OPENEXISTING)) LoadData(); }
LONG CALLBACK OBSExceptionHandler (PEXCEPTION_POINTERS exceptionInfo) { HANDLE hProcess; HMODULE hDbgHelp; MINIDUMP_EXCEPTION_INFORMATION miniInfo; STACKFRAME64 frame = {0}; CONTEXT context = *exceptionInfo->ContextRecord; SYMBOL_INFO *symInfo; DWORD64 fnOffset; TCHAR logPath[MAX_PATH]; OSVERSIONINFOEX osInfo; SYSTEMTIME timeInfo; ENUMERATELOADEDMODULES64 fnEnumerateLoadedModules64; SYMSETOPTIONS fnSymSetOptions; SYMINITIALIZE fnSymInitialize; STACKWALK64 fnStackWalk64; SYMFUNCTIONTABLEACCESS64 fnSymFunctionTableAccess64; SYMGETMODULEBASE64 fnSymGetModuleBase64; SYMFROMADDR fnSymFromAddr; SYMCLEANUP fnSymCleanup; MINIDUMPWRITEDUMP fnMiniDumpWriteDump; SYMGETMODULEINFO64 fnSymGetModuleInfo64; DWORD i; DWORD64 InstructionPtr; DWORD imageType; TCHAR searchPath[MAX_PATH], *p; static BOOL inExceptionHandler = FALSE; moduleinfo_t moduleInfo; //always break into a debugger if one is present if (IsDebuggerPresent ()) return EXCEPTION_CONTINUE_SEARCH; //exception codes < 0x80000000 are typically informative only and not crash worthy //0xe06d7363 indicates a c++ exception was thrown, let's just hope it was caught. //this is no longer needed since we're an unhandled handler vs a vectored handler /*if (exceptionInfo->ExceptionRecord->ExceptionCode < 0x80000000 || exceptionInfo->ExceptionRecord->ExceptionCode == 0xe06d7363 || exceptionInfo->ExceptionRecord->ExceptionCode == 0x800706b5) return EXCEPTION_CONTINUE_SEARCH;*/ //uh oh, we're crashing inside ourselves... this is really bad! if (inExceptionHandler) return EXCEPTION_CONTINUE_SEARCH; inExceptionHandler = TRUE; //load dbghelp dynamically hDbgHelp = LoadLibrary (TEXT("DBGHELP")); if (!hDbgHelp) return EXCEPTION_CONTINUE_SEARCH; fnEnumerateLoadedModules64 = (ENUMERATELOADEDMODULES64)GetProcAddress (hDbgHelp, "EnumerateLoadedModulesW64"); fnSymSetOptions = (SYMSETOPTIONS)GetProcAddress (hDbgHelp, "SymSetOptions"); fnSymInitialize = (SYMINITIALIZE)GetProcAddress (hDbgHelp, "SymInitialize"); fnSymFunctionTableAccess64 = (SYMFUNCTIONTABLEACCESS64)GetProcAddress (hDbgHelp, "SymFunctionTableAccess64"); fnSymGetModuleBase64 = (SYMGETMODULEBASE64)GetProcAddress (hDbgHelp, "SymGetModuleBase64"); fnStackWalk64 = (STACKWALK64)GetProcAddress (hDbgHelp, "StackWalk64"); fnSymFromAddr = (SYMFROMADDR)GetProcAddress (hDbgHelp, "SymFromAddrW"); fnSymCleanup = (SYMCLEANUP)GetProcAddress (hDbgHelp, "SymCleanup"); fnSymGetModuleInfo64 = (SYMGETMODULEINFO64)GetProcAddress (hDbgHelp, "SymGetModuleInfo64"); fnMiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress (hDbgHelp, "MiniDumpWriteDump"); if (!fnEnumerateLoadedModules64 || !fnSymSetOptions || !fnSymInitialize || !fnSymFunctionTableAccess64 || !fnSymGetModuleBase64 || !fnStackWalk64 || !fnSymFromAddr || !fnSymCleanup || !fnSymGetModuleInfo64) { FreeLibrary (hDbgHelp); return EXCEPTION_CONTINUE_SEARCH; } hProcess = GetCurrentProcess(); fnSymSetOptions (SYMOPT_UNDNAME | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_LOAD_ANYTHING); GetModuleFileName (NULL, searchPath, _countof(searchPath)-1); p = srchr (searchPath, '\\'); if (p) *p = 0; //create a log file GetSystemTime (&timeInfo); for (i = 1;;) { tsprintf_s (logPath, _countof(logPath)-1, TEXT("%s\\crashDumps\\OBSCrashLog%.4d-%.2d-%.2d_%d.txt"), lpAppDataPath, timeInfo.wYear, timeInfo.wMonth, timeInfo.wDay, i); if (GetFileAttributes(logPath) == INVALID_FILE_ATTRIBUTES) break; i++; } XFile crashDumpLog; if (!crashDumpLog.Open(logPath, XFILE_WRITE, XFILE_CREATENEW)) { FreeLibrary (hDbgHelp); return EXCEPTION_CONTINUE_SEARCH; } //initialize debug symbols fnSymInitialize (hProcess, NULL, TRUE); #ifdef _WIN64 InstructionPtr = context.Rip; frame.AddrPC.Offset = InstructionPtr; frame.AddrFrame.Offset = context.Rbp; frame.AddrStack.Offset = context.Rsp; imageType = IMAGE_FILE_MACHINE_AMD64; #else InstructionPtr = context.Eip; frame.AddrPC.Offset = InstructionPtr; frame.AddrFrame.Offset = context.Ebp; frame.AddrStack.Offset = context.Esp; imageType = IMAGE_FILE_MACHINE_I386; #endif frame.AddrFrame.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; symInfo = (SYMBOL_INFO *)LocalAlloc (LPTR, sizeof(*symInfo) + 256); symInfo->SizeOfStruct = sizeof(SYMBOL_INFO); symInfo->MaxNameLen = 256; fnOffset = 0; //get os info memset (&osInfo, 0, sizeof(osInfo)); osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (!GetVersionEx ((OSVERSIONINFO *)&osInfo)) { osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx ((OSVERSIONINFO *)&osInfo); } String cpuInfo; HKEY key; // get cpu info if(RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), &key) == ERROR_SUCCESS) { DWORD dwSize = 1024; cpuInfo.SetLength(dwSize); if (RegQueryValueEx(key, TEXT("ProcessorNameString"), NULL, NULL, (LPBYTE)cpuInfo.Array(), &dwSize) != ERROR_SUCCESS) cpuInfo = TEXT("<unable to query>"); RegCloseKey(key); } else cpuInfo = TEXT("<unable to query>"); //determine which module the crash occured in scpy (moduleInfo.moduleName, TEXT("<unknown>")); moduleInfo.faultAddress = InstructionPtr; fnEnumerateLoadedModules64 (hProcess, (PENUMLOADED_MODULES_CALLBACK64)EnumerateLoadedModulesProcInfo, (VOID *)&moduleInfo); slwr (moduleInfo.moduleName); BOOL isPlugin = FALSE; if (sstr (moduleInfo.moduleName, TEXT("plugins\\"))) isPlugin = TRUE; String strModuleInfo; String crashMessage; fnEnumerateLoadedModules64(hProcess, (PENUMLOADED_MODULES_CALLBACK64)RecordAllLoadedModules, (VOID *)&strModuleInfo); crashMessage << TEXT("OBS has encountered an unhandled exception and has terminated. If you are able to\r\n") TEXT("reproduce this crash, please submit this crash report on the forums at\r\n") TEXT("http://www.obsproject.com/ - include the contents of this crash log and the\r\n") TEXT("minidump .dmp file (if available) as well as your regular OBS log files and\r\n") TEXT("a description of what you were doing at the time of the crash.\r\n") TEXT("\r\n") TEXT("This crash appears to have occured in the '") << moduleInfo.moduleName << TEXT("' module.\r\n\r\n"); crashDumpLog.WriteStr(crashMessage.Array()); crashDumpLog.WriteStr(FormattedString(TEXT("**** UNHANDLED EXCEPTION: %x\r\nFault address: %I64p (%s)\r\n"), exceptionInfo->ExceptionRecord->ExceptionCode, InstructionPtr, moduleInfo.moduleName)); crashDumpLog.WriteStr(TEXT("OBS version: ") OBS_VERSION_STRING TEXT("\r\n")); crashDumpLog.WriteStr(FormattedString(TEXT("Windows version: %d.%d (Build %d) %s\r\nCPU: %s\r\n\r\n"), osInfo.dwMajorVersion, osInfo.dwMinorVersion, osInfo.dwBuildNumber, osInfo.szCSDVersion, cpuInfo.Array())); crashDumpLog.WriteStr(TEXT("Crashing thread stack trace:\r\n")); #ifdef _WIN64 crashDumpLog.WriteStr(TEXT("Stack EIP Arg0 Arg1 Arg2 Arg3 Address\r\n")); #else crashDumpLog.WriteStr(TEXT("Stack EIP Arg0 Arg1 Arg2 Arg3 Address\r\n")); #endif crashDumpLog.FlushFileBuffers(); while (fnStackWalk64 (imageType, hProcess, GetCurrentThread(), &frame, &context, NULL, (PFUNCTION_TABLE_ACCESS_ROUTINE64)fnSymFunctionTableAccess64, (PGET_MODULE_BASE_ROUTINE64)fnSymGetModuleBase64, NULL)) { scpy (moduleInfo.moduleName, TEXT("<unknown>")); moduleInfo.faultAddress = frame.AddrPC.Offset; fnEnumerateLoadedModules64 (hProcess, (PENUMLOADED_MODULES_CALLBACK64)EnumerateLoadedModulesProcInfo, (VOID *)&moduleInfo); slwr (moduleInfo.moduleName); p = srchr (moduleInfo.moduleName, '\\'); if (p) p++; else p = moduleInfo.moduleName; #ifdef _WIN64 if (fnSymFromAddr (hProcess, frame.AddrPC.Offset, &fnOffset, symInfo) && !(symInfo->Flags & SYMFLAG_EXPORT)) { crashDumpLog.WriteStr(FormattedString(TEXT("%016I64X %016I64X %016I64X %016I64X %016I64X %016I64X %s!%s+0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, frame.Params[0], frame.Params[1], frame.Params[2], frame.Params[3], p, symInfo->Name, fnOffset)); } else { crashDumpLog.WriteStr(FormattedString(TEXT("%016I64X %016I64X %016I64X %016I64X %016I64X %016I64X %s!0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, frame.Params[0], frame.Params[1], frame.Params[2], frame.Params[3], p, frame.AddrPC.Offset)); } #else if (fnSymFromAddr (hProcess, frame.AddrPC.Offset, &fnOffset, symInfo) && !(symInfo->Flags & SYMFLAG_EXPORT)) { crashDumpLog.WriteStr(FormattedString(TEXT("%08.8I64X %08.8I64X %08.8X %08.8X %08.8X %08.8X %s!%s+0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, (DWORD)frame.Params[0], (DWORD)frame.Params[1], (DWORD)frame.Params[2], (DWORD)frame.Params[3], p, symInfo->Name, fnOffset)); } else { crashDumpLog.WriteStr(FormattedString(TEXT("%08.8I64X %08.8I64X %08.8X %08.8X %08.8X %08.8X %s!0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, (DWORD)frame.Params[0], (DWORD)frame.Params[1], (DWORD)frame.Params[2], (DWORD)frame.Params[3], p, frame.AddrPC.Offset )); } #endif crashDumpLog.FlushFileBuffers(); } //if we manually crashed due to a deadlocked thread, record some extra info if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) { HANDLE hVideoThread = NULL, hEncodeThread = NULL; App->GetThreadHandles (&hVideoThread, &hEncodeThread); if (hVideoThread) { crashDumpLog.WriteStr(TEXT("\r\nVideo thread stack trace:\r\n")); #ifdef _WIN64 crashDumpLog.WriteStr(TEXT("Stack EIP Arg0 Arg1 Arg2 Arg3 Address\r\n")); #else crashDumpLog.WriteStr(TEXT("Stack EIP Arg0 Arg1 Arg2 Arg3 Address\r\n")); #endif crashDumpLog.FlushFileBuffers(); context.ContextFlags = CONTEXT_ALL; GetThreadContext (hVideoThread, &context); ZeroMemory (&frame, sizeof(frame)); #ifdef _WIN64 InstructionPtr = context.Rip; frame.AddrPC.Offset = InstructionPtr; frame.AddrFrame.Offset = context.Rbp; frame.AddrStack.Offset = context.Rsp; imageType = IMAGE_FILE_MACHINE_AMD64; #else InstructionPtr = context.Eip; frame.AddrPC.Offset = InstructionPtr; frame.AddrFrame.Offset = context.Ebp; frame.AddrStack.Offset = context.Esp; imageType = IMAGE_FILE_MACHINE_I386; #endif frame.AddrFrame.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; while (fnStackWalk64 (imageType, hProcess, hVideoThread, &frame, &context, NULL, (PFUNCTION_TABLE_ACCESS_ROUTINE64)fnSymFunctionTableAccess64, (PGET_MODULE_BASE_ROUTINE64)fnSymGetModuleBase64, NULL)) { scpy (moduleInfo.moduleName, TEXT("<unknown>")); moduleInfo.faultAddress = frame.AddrPC.Offset; fnEnumerateLoadedModules64 (hProcess, (PENUMLOADED_MODULES_CALLBACK64)EnumerateLoadedModulesProcInfo, (VOID *)&moduleInfo); slwr (moduleInfo.moduleName); p = srchr (moduleInfo.moduleName, '\\'); if (p) p++; else p = moduleInfo.moduleName; #ifdef _WIN64 if (fnSymFromAddr (hProcess, frame.AddrPC.Offset, &fnOffset, symInfo) && !(symInfo->Flags & SYMFLAG_EXPORT)) { crashDumpLog.WriteStr(FormattedString(TEXT("%016I64X %016I64X %016I64X %016I64X %016I64X %016I64X %s!%s+0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, frame.Params[0], frame.Params[1], frame.Params[2], frame.Params[3], p, symInfo->Name, fnOffset)); } else { crashDumpLog.WriteStr(FormattedString(TEXT("%016I64X %016I64X %016I64X %016I64X %016I64X %016I64X %s!0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, frame.Params[0], frame.Params[1], frame.Params[2], frame.Params[3], p, frame.AddrPC.Offset)); } #else if (fnSymFromAddr (hProcess, frame.AddrPC.Offset, &fnOffset, symInfo) && !(symInfo->Flags & SYMFLAG_EXPORT)) { crashDumpLog.WriteStr(FormattedString(TEXT("%08.8I64X %08.8I64X %08.8X %08.8X %08.8X %08.8X %s!%s+0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, (DWORD)frame.Params[0], (DWORD)frame.Params[1], (DWORD)frame.Params[2], (DWORD)frame.Params[3], p, symInfo->Name, fnOffset)); } else { crashDumpLog.WriteStr(FormattedString(TEXT("%08.8I64X %08.8I64X %08.8X %08.8X %08.8X %08.8X %s!0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, (DWORD)frame.Params[0], (DWORD)frame.Params[1], (DWORD)frame.Params[2], (DWORD)frame.Params[3], p, frame.AddrPC.Offset )); } #endif crashDumpLog.FlushFileBuffers(); } } if (hEncodeThread) { crashDumpLog.WriteStr(TEXT("\r\nEncode thread stack trace:\r\n")); #ifdef _WIN64 crashDumpLog.WriteStr(TEXT("Stack EIP Arg0 Arg1 Arg2 Arg3 Address\r\n")); #else crashDumpLog.WriteStr(TEXT("Stack EIP Arg0 Arg1 Arg2 Arg3 Address\r\n")); #endif crashDumpLog.FlushFileBuffers(); context.ContextFlags = CONTEXT_ALL; GetThreadContext (hEncodeThread, &context); ZeroMemory (&frame, sizeof(frame)); #ifdef _WIN64 InstructionPtr = context.Rip; frame.AddrPC.Offset = InstructionPtr; frame.AddrFrame.Offset = context.Rbp; frame.AddrStack.Offset = context.Rsp; imageType = IMAGE_FILE_MACHINE_AMD64; #else InstructionPtr = context.Eip; frame.AddrPC.Offset = InstructionPtr; frame.AddrFrame.Offset = context.Ebp; frame.AddrStack.Offset = context.Esp; imageType = IMAGE_FILE_MACHINE_I386; #endif frame.AddrFrame.Mode = AddrModeFlat; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; while (fnStackWalk64 (imageType, hProcess, hEncodeThread, &frame, &context, NULL, (PFUNCTION_TABLE_ACCESS_ROUTINE64)fnSymFunctionTableAccess64, (PGET_MODULE_BASE_ROUTINE64)fnSymGetModuleBase64, NULL)) { scpy (moduleInfo.moduleName, TEXT("<unknown>")); moduleInfo.faultAddress = frame.AddrPC.Offset; fnEnumerateLoadedModules64 (hProcess, (PENUMLOADED_MODULES_CALLBACK64)EnumerateLoadedModulesProcInfo, (VOID *)&moduleInfo); slwr (moduleInfo.moduleName); p = srchr (moduleInfo.moduleName, '\\'); if (p) p++; else p = moduleInfo.moduleName; #ifdef _WIN64 if (fnSymFromAddr (hProcess, frame.AddrPC.Offset, &fnOffset, symInfo) && !(symInfo->Flags & SYMFLAG_EXPORT)) { crashDumpLog.WriteStr(FormattedString(TEXT("%016I64X %016I64X %016I64X %016I64X %016I64X %016I64X %s!%s+0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, frame.Params[0], frame.Params[1], frame.Params[2], frame.Params[3], p, symInfo->Name, fnOffset)); } else { crashDumpLog.WriteStr(FormattedString(TEXT("%016I64X %016I64X %016I64X %016I64X %016I64X %016I64X %s!0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, frame.Params[0], frame.Params[1], frame.Params[2], frame.Params[3], p, frame.AddrPC.Offset)); } #else if (fnSymFromAddr (hProcess, frame.AddrPC.Offset, &fnOffset, symInfo) && !(symInfo->Flags & SYMFLAG_EXPORT)) { crashDumpLog.WriteStr(FormattedString(TEXT("%08.8I64X %08.8I64X %08.8X %08.8X %08.8X %08.8X %s!%s+0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, (DWORD)frame.Params[0], (DWORD)frame.Params[1], (DWORD)frame.Params[2], (DWORD)frame.Params[3], p, symInfo->Name, fnOffset)); } else { crashDumpLog.WriteStr(FormattedString(TEXT("%08.8I64X %08.8I64X %08.8X %08.8X %08.8X %08.8X %s!0x%I64x\r\n"), frame.AddrStack.Offset, frame.AddrPC.Offset, (DWORD)frame.Params[0], (DWORD)frame.Params[1], (DWORD)frame.Params[2], (DWORD)frame.Params[3], p, frame.AddrPC.Offset )); } #endif crashDumpLog.FlushFileBuffers(); } } } //generate a minidump if possible if (fnMiniDumpWriteDump) { TCHAR dumpPath[MAX_PATH]; HANDLE hFile; tsprintf_s (dumpPath, _countof(dumpPath)-1, TEXT("%s\\crashDumps\\OBSCrashDump%.4d-%.2d-%.2d_%d.dmp"), lpAppDataPath, timeInfo.wYear, timeInfo.wMonth, timeInfo.wDay, i); hFile = CreateFile (dumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { MINIDUMP_TYPE dumpFlags = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithUnloadedModules | MiniDumpWithProcessThreadData); miniInfo.ClientPointers = TRUE; miniInfo.ExceptionPointers = exceptionInfo; miniInfo.ThreadId = GetCurrentThreadId (); if (fnMiniDumpWriteDump (hProcess, GetCurrentProcessId(), hFile, dumpFlags, &miniInfo, NULL, NULL)) { crashDumpLog.WriteStr(FormattedString(TEXT("\r\nA minidump was saved to %s.\r\nPlease include this file when posting a crash report.\r\n"), dumpPath)); } else { CloseHandle (hFile); DeleteFile (dumpPath); } } } else { crashDumpLog.WriteStr(TEXT("\r\nA minidump could not be created. Please check dbghelp.dll is present.\r\n")); } crashDumpLog.WriteStr("\r\nList of loaded modules:\r\n"); #ifdef _WIN64 crashDumpLog.WriteStr("Base Address Module\r\n"); #else crashDumpLog.WriteStr("Base Address Module\r\n"); #endif crashDumpLog.WriteStr(strModuleInfo); crashDumpLog.Close(); LocalFree (symInfo); fnSymCleanup (hProcess); if (OBSMessageBox(hwndMain, TEXT("Woops! OBS has crashed. Would you like to view a crash report?"), NULL, MB_ICONERROR | MB_YESNO) == IDYES) ShellExecute(NULL, NULL, logPath, NULL, searchPath, SW_SHOWDEFAULT); FreeLibrary (hDbgHelp); //we really shouldn't be returning here, if we're at the bottom of the VEH chain this is a pretty legitimate crash //and if we return we could end up invoking a second crash handler or other weird / annoying things //ExitProcess(exceptionInfo->ExceptionRecord->ExceptionCode); return EXCEPTION_CONTINUE_SEARCH; }
~MP4FileStream() { if(!bStreamOpened) return; App->EnableSceneSwitching(false); //--------------------------------------------------- //HWND hwndProgressDialog = CreateDialog(hinstMain, MAKEINTRESOURCE(IDD_BUILDINGMP4), hwndMain, (DLGPROC)MP4ProgressDialogProc); //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETRANGE32, 0, 100); mdatStop = fileOut.GetPos(); BufferOutputSerializer output(endBuffer); //set a reasonable initial buffer size endBuffer.SetSize((videoFrames.Num() + audioFrames.Num()) * 20 + 131072); UINT64 audioFrameSize = App->GetAudioEncoder()->GetFrameSize(); DWORD macTime = fastHtonl(DWORD(GetMacTime())); UINT videoDuration = fastHtonl(lastVideoTimestamp + App->GetFrameTime()); UINT audioDuration = fastHtonl(lastVideoTimestamp + DWORD(double(audioFrameSize)*1000.0/double(App->GetSampleRateHz()))); UINT width, height; App->GetOutputSize(width, height); LPCSTR lpVideoTrack = "Video Media Handler"; LPCSTR lpAudioTrack = "Sound Media Handler"; const char videoCompressionName[31] = "AVC Coding"; //------------------------------------------- // get video headers DataPacket videoHeaders; App->GetVideoHeaders(videoHeaders); List<BYTE> SPS, PPS; LPBYTE lpHeaderData = videoHeaders.lpPacket+11; SPS.CopyArray(lpHeaderData+2, fastHtons(*(WORD*)lpHeaderData)); lpHeaderData += SPS.Num()+3; PPS.CopyArray(lpHeaderData+2, fastHtons(*(WORD*)lpHeaderData)); //------------------------------------------- // get AAC headers if using AAC List<BYTE> AACHeader; if(!bMP3) { DataPacket data; App->GetAudioHeaders(data); AACHeader.CopyArray(data.lpPacket+2, data.size-2); } //------------------------------------------- EndChunkInfo(videoChunks, videoSampleToChunk, curVideoChunkOffset, numVideoSamples); EndChunkInfo(audioChunks, audioSampleToChunk, curAudioChunkOffset, numAudioSamples); if (numVideoSamples > 1) GetVideoDecodeTime(videoFrames.Last(), true); if (numAudioSamples > 1) GetAudioDecodeTime(audioFrames.Last(), true); UINT audioUnitDuration = fastHtonl(UINT(lastAudioTimeVal)); //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 25, 0); //------------------------------------------- // sound descriptor thingy. this part made me die a little inside admittedly. UINT maxBitRate = fastHtonl(App->GetAudioEncoder()->GetBitRate()*1000); List<BYTE> esDecoderDescriptor; BufferOutputSerializer esDecoderOut(esDecoderDescriptor); esDecoderOut.OutputByte(bMP3 ? 107 : 64); esDecoderOut.OutputByte(0x15); //stream/type flags. always 0x15 for my purposes. esDecoderOut.OutputByte(0); //buffer size, just set it to 1536 for both mp3 and aac esDecoderOut.OutputWord(WORD_BE(0x600)); esDecoderOut.OutputDword(maxBitRate); //max bit rate (cue bill 'o reily meme for these two) esDecoderOut.OutputDword(maxBitRate); //avg bit rate if(!bMP3) //if AAC, put in headers { esDecoderOut.OutputByte(0x5); //decoder specific descriptor type /*esDecoderOut.OutputByte(0x80); //some stuff that no one should probably care about esDecoderOut.OutputByte(0x80); esDecoderOut.OutputByte(0x80);*/ esDecoderOut.OutputByte(AACHeader.Num()); esDecoderOut.Serialize((LPVOID)AACHeader.Array(), AACHeader.Num()); } List<BYTE> esDescriptor; BufferOutputSerializer esOut(esDescriptor); esOut.OutputWord(0); //es id esOut.OutputByte(0); //stream priority esOut.OutputByte(4); //descriptor type /*esOut.OutputByte(0x80); //some stuff that no one should probably care about esOut.OutputByte(0x80); esOut.OutputByte(0x80);*/ esOut.OutputByte(esDecoderDescriptor.Num()); esOut.Serialize((LPVOID)esDecoderDescriptor.Array(), esDecoderDescriptor.Num()); esOut.OutputByte(0x6); //config descriptor type /*esOut.OutputByte(0x80); //some stuff that no one should probably care about esOut.OutputByte(0x80); esOut.OutputByte(0x80);*/ esOut.OutputByte(1); //len esOut.OutputByte(2); //SL value(? always 2) //------------------------------------------- PushBox(output, DWORD_BE('moov')); //------------------------------------------------------ // header PushBox(output, DWORD_BE('mvhd')); output.OutputDword(0); //version and flags (none) output.OutputDword(macTime); //creation time output.OutputDword(macTime); //modified time output.OutputDword(DWORD_BE(1000)); //time base (milliseconds, so 1000) output.OutputDword(videoDuration); //duration (in time base units) output.OutputDword(DWORD_BE(0x00010000)); //fixed point playback speed 1.0 output.OutputWord(WORD_BE(0x0100)); //fixed point vol 1.0 output.OutputQword(0); //reserved (10 bytes) output.OutputWord(0); output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 1 (1.0, 0.0, 0.0) output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 2 (0.0, 1.0, 0.0) output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x40000000)); //window matrix row 3 (0.0, 0.0, 16384.0) output.OutputDword(0); //prevew start time (time base units) output.OutputDword(0); //prevew duration (time base units) output.OutputDword(0); //still poster frame (timestamp of frame) output.OutputDword(0); //selection(?) start time (time base units) output.OutputDword(0); //selection(?) duration (time base units) output.OutputDword(0); //current time (0, time base units) output.OutputDword(DWORD_BE(3)); //next free track id (1-based rather than 0-based) PopBox(output); //mvhd //------------------------------------------------------ // audio track PushBox(output, DWORD_BE('trak')); PushBox(output, DWORD_BE('tkhd')); //track header output.OutputDword(DWORD_BE(0x00000007)); //version (0) and flags (0xF) output.OutputDword(macTime); //creation time output.OutputDword(macTime); //modified time output.OutputDword(DWORD_BE(1)); //track ID output.OutputDword(0); //reserved output.OutputDword(audioDuration); //duration (in time base units) output.OutputQword(0); //reserved output.OutputWord(0); //video layer (0) output.OutputWord(WORD_BE(0)); //quicktime alternate track id output.OutputWord(WORD_BE(0x0100)); //volume output.OutputWord(0); //reserved output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 1 (1.0, 0.0, 0.0) output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 2 (0.0, 1.0, 0.0) output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x40000000)); //window matrix row 3 (0.0, 0.0, 16384.0) output.OutputDword(0); //width (fixed point) output.OutputDword(0); //height (fixed point) PopBox(output); //tkhd /*PushBox(output, DWORD_BE('edts')); PushBox(output, DWORD_BE('elst')); output.OutputDword(0); //version and flags (none) output.OutputDword(DWORD_BE(1)); //count output.OutputDword(audioDuration); //duration output.OutputDword(0); //start time output.OutputDword(DWORD_BE(0x00010000)); //playback speed (1.0) PopBox(); //elst PopBox(); //tdst*/ PushBox(output, DWORD_BE('mdia')); PushBox(output, DWORD_BE('mdhd')); output.OutputDword(0); //version and flags (none) output.OutputDword(macTime); //creation time output.OutputDword(macTime); //modified time output.OutputDword(DWORD_BE(App->GetSampleRateHz())); //time scale output.OutputDword(audioUnitDuration); output.OutputDword(bMP3 ? DWORD_BE(0x55c40000) : DWORD_BE(0x15c70000)); PopBox(output); //mdhd PushBox(output, DWORD_BE('hdlr')); output.OutputDword(0); //version and flags (none) output.OutputDword(0); //quicktime type (none) output.OutputDword(DWORD_BE('soun')); //media type output.OutputDword(0); //manufacturer reserved output.OutputDword(0); //quicktime component reserved flags output.OutputDword(0); //quicktime component reserved mask output.Serialize((LPVOID)lpAudioTrack, (DWORD)strlen(lpAudioTrack)+1); //track name PopBox(output); //hdlr PushBox(output, DWORD_BE('minf')); PushBox(output, DWORD_BE('smhd')); output.OutputDword(0); //version and flags (none) output.OutputDword(0); //balance (fixed point) PopBox(output); //vdhd PushBox(output, DWORD_BE('dinf')); PushBox(output, DWORD_BE('dref')); output.OutputDword(0); //version and flags (none) output.OutputDword(DWORD_BE(1)); //count PushBox(output, DWORD_BE('url ')); output.OutputDword(DWORD_BE(0x00000001)); //version (0) and flags (1) PopBox(output); //url PopBox(output); //dref PopBox(output); //dinf PushBox(output, DWORD_BE('stbl')); PushBox(output, DWORD_BE('stsd')); output.OutputDword(0); //version and flags (none) output.OutputDword(DWORD_BE(1)); //count PushBox(output, DWORD_BE('mp4a')); output.OutputDword(0); //reserved (6 bytes) output.OutputWord(0); output.OutputWord(WORD_BE(1)); //dref index output.OutputWord(0); //quicktime encoding version output.OutputWord(0); //quicktime encoding revision output.OutputDword(0); //quicktime audio encoding vendor output.OutputWord(0); //channels (ignored) output.OutputWord(WORD_BE(16)); //sample size output.OutputWord(0); //quicktime audio compression id output.OutputWord(0); //quicktime audio packet size output.OutputDword(DWORD_BE(App->GetSampleRateHz()<<16)); //sample rate (fixed point) PushBox(output, DWORD_BE('esds')); output.OutputDword(0); //version and flags (none) output.OutputByte(3); //ES descriptor type /*output.OutputByte(0x80); output.OutputByte(0x80); output.OutputByte(0x80);*/ output.OutputByte(esDescriptor.Num()); output.Serialize((LPVOID)esDescriptor.Array(), esDescriptor.Num()); PopBox(output); PopBox(output); PopBox(output); //stsd PushBox(output, DWORD_BE('stts')); //list of keyframe (i-frame) IDs output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(audioDecodeTimes.Num())); for(UINT i=0; i<audioDecodeTimes.Num(); i++) { output.OutputDword(fastHtonl(audioDecodeTimes[i].count)); output.OutputDword(fastHtonl(audioDecodeTimes[i].val)); } PopBox(output); //stss PushBox(output, DWORD_BE('stsc')); //sample to chunk list output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(audioSampleToChunk.Num())); for(UINT i=0; i<audioSampleToChunk.Num(); i++) { SampleToChunk &stc = audioSampleToChunk[i]; output.OutputDword(fastHtonl(stc.firstChunkID)); output.OutputDword(fastHtonl(stc.samplesPerChunk)); output.OutputDword(DWORD_BE(1)); } PopBox(output); //stsc //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 30, 0); //ProcessEvents(); PushBox(output, DWORD_BE('stsz')); //sample sizes output.OutputDword(0); //version and flags (none) output.OutputDword(0); //block size for all (0 if differing sizes) output.OutputDword(fastHtonl(audioFrames.Num())); for(UINT i=0; i<audioFrames.Num(); i++) output.OutputDword(fastHtonl(audioFrames[i].size)); PopBox(output); //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 40, 0); //ProcessEvents(); if(audioChunks.Num() && audioChunks.Last() > 0xFFFFFFFFLL) { PushBox(output, DWORD_BE('co64')); //chunk offsets output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(audioChunks.Num())); for(UINT i=0; i<audioChunks.Num(); i++) output.OutputQword(fastHtonll(audioChunks[i])); PopBox(output); //co64 } else { PushBox(output, DWORD_BE('stco')); //chunk offsets output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(audioChunks.Num())); for(UINT i=0; i<audioChunks.Num(); i++) output.OutputDword(fastHtonl((DWORD)audioChunks[i])); PopBox(output); //stco } PopBox(output); //stbl PopBox(output); //minf PopBox(output); //mdia PopBox(output); //trak //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 50, 0); //ProcessEvents(); //------------------------------------------------------ // video track PushBox(output, DWORD_BE('trak')); PushBox(output, DWORD_BE('tkhd')); //track header output.OutputDword(DWORD_BE(0x00000007)); //version (0) and flags (0x7) output.OutputDword(macTime); //creation time output.OutputDword(macTime); //modified time output.OutputDword(DWORD_BE(2)); //track ID output.OutputDword(0); //reserved output.OutputDword(videoDuration); //duration (in time base units) output.OutputQword(0); //reserved output.OutputWord(0); //video layer (0) output.OutputWord(0); //quicktime alternate track id (0) output.OutputWord(0); //track audio volume (this is video, so 0) output.OutputWord(0); //reserved output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 1 (1.0, 0.0, 0.0) output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 2 (0.0, 1.0, 0.0) output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x40000000)); //window matrix row 3 (0.0, 0.0, 16384.0) output.OutputDword(fastHtonl(width<<16)); //width (fixed point) output.OutputDword(fastHtonl(height<<16)); //height (fixed point) PopBox(output); //tkhd /*PushBox(output, DWORD_BE('edts')); PushBox(output, DWORD_BE('elst')); output.OutputDword(0); //version and flags (none) output.OutputDword(DWORD_BE(1)); //count output.OutputDword(videoDuration); //duration output.OutputDword(0); //start time output.OutputDword(DWORD_BE(0x00010000)); //playback speed (1.0) PopBox(); //elst PopBox(); //tdst*/ PushBox(output, DWORD_BE('mdia')); PushBox(output, DWORD_BE('mdhd')); output.OutputDword(0); //version and flags (none) output.OutputDword(macTime); //creation time output.OutputDword(macTime); //modified time output.OutputDword(DWORD_BE(1000)); //time scale output.OutputDword(videoDuration); output.OutputDword(DWORD_BE(0x55c40000)); PopBox(output); //mdhd PushBox(output, DWORD_BE('hdlr')); output.OutputDword(0); //version and flags (none) output.OutputDword(0); //quicktime type (none) output.OutputDword(DWORD_BE('vide')); //media type output.OutputDword(0); //manufacturer reserved output.OutputDword(0); //quicktime component reserved flags output.OutputDword(0); //quicktime component reserved mask output.Serialize((LPVOID)lpVideoTrack, (DWORD)strlen(lpVideoTrack)+1); //track name PopBox(output); //hdlr PushBox(output, DWORD_BE('minf')); PushBox(output, DWORD_BE('vmhd')); output.OutputDword(DWORD_BE(0x00000001)); //version (0) and flags (1) output.OutputWord(0); //quickdraw graphic mode (copy = 0) output.OutputWord(0); //quickdraw red value output.OutputWord(0); //quickdraw green value output.OutputWord(0); //quickdraw blue value PopBox(output); //vdhd PushBox(output, DWORD_BE('dinf')); PushBox(output, DWORD_BE('dref')); output.OutputDword(0); //version and flags (none) output.OutputDword(DWORD_BE(1)); //count PushBox(output, DWORD_BE('url ')); output.OutputDword(DWORD_BE(0x00000001)); //version (0) and flags (1) PopBox(output); //url PopBox(output); //dref PopBox(output); //dinf PushBox(output, DWORD_BE('stbl')); PushBox(output, DWORD_BE('stsd')); output.OutputDword(0); //version and flags (none) output.OutputDword(DWORD_BE(1)); //count PushBox(output, DWORD_BE('avc1')); output.OutputDword(0); //reserved 6 bytes output.OutputWord(0); output.OutputWord(WORD_BE(1)); //index output.OutputWord(0); //encoding version output.OutputWord(0); //encoding revision level output.OutputDword(0); //encoding vendor output.OutputDword(0); //temporal quality output.OutputDword(0); //spatial quality output.OutputWord(fastHtons(width)); //width output.OutputWord(fastHtons(height)); //height output.OutputDword(DWORD_BE(0x00480000)); //fixed point width pixel resolution (72.0) output.OutputDword(DWORD_BE(0x00480000)); //fixed point height pixel resolution (72.0) output.OutputDword(0); //quicktime video data size output.OutputWord(WORD_BE(1)); //frame count(?) output.OutputByte((BYTE)strlen(videoCompressionName)); //compression name length output.Serialize(videoCompressionName, 31); //31 bytes for the name output.OutputWord(WORD_BE(24)); //bit depth output.OutputWord(0xFFFF); //quicktime video color table id (none = -1) PushBox(output, DWORD_BE('avcC')); output.OutputByte(1); //version output.OutputByte(100); //h264 profile ID output.OutputByte(0); //h264 compatible profiles output.OutputByte(0x1f); //h264 level output.OutputByte(0xff); //reserved output.OutputByte(0xe1); //first half-byte = no clue. second half = sps count output.OutputWord(fastHtons(SPS.Num())); //sps size output.Serialize(SPS.Array(), SPS.Num()); //sps data output.OutputByte(1); //pps count output.OutputWord(fastHtons(PPS.Num())); //pps size output.Serialize(PPS.Array(), PPS.Num()); //pps data PopBox(output); //avcC PopBox(output); //avc1 PopBox(output); //stsd PushBox(output, DWORD_BE('stts')); //frame times output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(videoDecodeTimes.Num())); for(UINT i=0; i<videoDecodeTimes.Num(); i++) { output.OutputDword(fastHtonl(videoDecodeTimes[i].count)); output.OutputDword(fastHtonl(videoDecodeTimes[i].val)); } PopBox(output); //stts //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 60, 0); //ProcessEvents(); if (IFrameIDs.Num()) { PushBox(output, DWORD_BE('stss')); //list of keyframe (i-frame) IDs output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(IFrameIDs.Num())); output.Serialize(IFrameIDs.Array(), IFrameIDs.Num()*sizeof(UINT)); PopBox(output); //stss } PushBox(output, DWORD_BE('ctts')); //list of composition time offsets output.OutputDword(0); //version (0) and flags (none) //output.OutputDword(DWORD_BE(0x01000000)); //version (1) and flags (none) output.OutputDword(fastHtonl(compositionOffsets.Num())); for(UINT i=0; i<compositionOffsets.Num(); i++) { output.OutputDword(fastHtonl(compositionOffsets[i].count)); output.OutputDword(fastHtonl(compositionOffsets[i].val)); } PopBox(output); //ctts //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 70, 0); //ProcessEvents(); PushBox(output, DWORD_BE('stsc')); //sample to chunk list output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(videoSampleToChunk.Num())); for(UINT i=0; i<videoSampleToChunk.Num(); i++) { SampleToChunk &stc = videoSampleToChunk[i]; output.OutputDword(fastHtonl(stc.firstChunkID)); output.OutputDword(fastHtonl(stc.samplesPerChunk)); output.OutputDword(DWORD_BE(1)); } PopBox(output); //stsc PushBox(output, DWORD_BE('stsz')); //sample sizes output.OutputDword(0); //version and flags (none) output.OutputDword(0); //block size for all (0 if differing sizes) output.OutputDword(fastHtonl(videoFrames.Num())); for(UINT i=0; i<videoFrames.Num(); i++) output.OutputDword(fastHtonl(videoFrames[i].size)); PopBox(output); if(videoChunks.Num() && videoChunks.Last() > 0xFFFFFFFFLL) { PushBox(output, DWORD_BE('co64')); //chunk offsets output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(videoChunks.Num())); for(UINT i=0; i<videoChunks.Num(); i++) output.OutputQword(fastHtonll(videoChunks[i])); PopBox(output); //co64 } else { PushBox(output, DWORD_BE('stco')); //chunk offsets output.OutputDword(0); //version and flags (none) output.OutputDword(fastHtonl(videoChunks.Num())); for(UINT i=0; i<videoChunks.Num(); i++) output.OutputDword(fastHtonl((DWORD)videoChunks[i])); PopBox(output); //stco } PopBox(output); //stbl PopBox(output); //minf PopBox(output); //mdia PopBox(output); //trak //SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 80, 0); //ProcessEvents(); //------------------------------------------------------ // info thingy PushBox(output, DWORD_BE('udta')); PushBox(output, DWORD_BE('meta')); output.OutputDword(0); //version and flags (none) PushBox(output, DWORD_BE('hdlr')); output.OutputDword(0); //version and flags (none) output.OutputDword(0); //quicktime type output.OutputDword(DWORD_BE('mdir')); //metadata type output.OutputDword(DWORD_BE('appl')); //quicktime manufacturer reserved thingy output.OutputDword(0); //quicktime component reserved flag output.OutputDword(0); //quicktime component reserved flag mask output.OutputByte(0); //null string PopBox(output); //hdlr PushBox(output, DWORD_BE('ilst')); PushBox(output, DWORD_BE('\xa9too')); PushBox(output, DWORD_BE('data')); output.OutputDword(DWORD_BE(1)); //version (1) + flags (0) output.OutputDword(0); //reserved LPSTR lpVersion = OBS_VERSION_STRING_ANSI; output.Serialize(lpVersion, (DWORD)strlen(lpVersion)); PopBox(output); //data PopBox(output); //@too PopBox(output); //ilst PopBox(output); //meta PopBox(output); //udta PopBox(output); //moov fileOut.Serialize(endBuffer.Array(), (DWORD)output.GetPos()); fileOut.Close(); XFile file; if(file.Open(strFile, XFILE_WRITE, XFILE_OPENEXISTING)) { #ifdef USE_64BIT_MP4 file.SetPos((INT64)mdatStart+8, XFILE_BEGIN); UINT64 size = fastHtonll(mdatStop-mdatStart); file.Write(&size, 8); #else file.SetPos((INT64)mdatStart, XFILE_BEGIN); UINT size = fastHtonl((DWORD)(mdatStop-mdatStart)); file.Write(&size, 4); #endif file.Close(); } App->EnableSceneSwitching(true); //DestroyWindow(hwndProgressDialog); }
//ugh yet more string parsing, you think you escape it for one minute and then bam! you discover yet more string parsing code needs to be written BOOL LocaleStringLookup::LoadStringFile(CTSTR lpFile, bool bClear) { if(bClear) { cache.Clear(); delete top; top = new StringLookupNode; } else if(!top) top = new StringLookupNode; //------------------------ XFile file; if(!file.Open(lpFile, XFILE_READ, XFILE_OPENEXISTING)) return FALSE; String fileString; file.ReadFileToString(fileString); file.Close(); if(fileString.IsEmpty()) return FALSE; //------------------------ fileString.FindReplace(TEXT("\r"), TEXT(" ")); TSTR lpTemp = fileString.Array()-1; TSTR lpNextLine; do { ++lpTemp; lpNextLine = schr(lpTemp, '\n'); while(*lpTemp == ' ' || *lpTemp == L' ' || *lpTemp == '\t') ++lpTemp; if(!*lpTemp || *lpTemp == '\n') continue; if(lpNextLine) *lpNextLine = 0; //---------- TSTR lpValueStart = lpTemp; while(*lpValueStart && *lpValueStart != ' ' && *lpValueStart != L' ' && *lpValueStart != '\t') ++lpValueStart; String lookupVal, strVal; TCHAR prevChar = *lpValueStart; *lpValueStart = 0; lookupVal = lpTemp; *lpValueStart = prevChar; String value = lpValueStart; value.KillSpaces(); if(value.IsValid() && value[0] == '"') { value = String::RepresentationToString(value); strVal = value; } else strVal = value; if(lookupVal.IsValid()) AddLookupString(lookupVal, strVal); //---------- if(lpNextLine) *lpNextLine = '\n'; }while(lpTemp = lpNextLine); //------------------------ return TRUE; }