// get a random file in the directory // automatically wrap if we've hit the end void LLDir_Win32::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) { S32 num_files; S32 which_file; HANDLE random_search_h; fname = ""; llutf16string pathname = utf8str_to_utf16str(dirname); pathname += utf8str_to_utf16str(mask); WIN32_FIND_DATA FileData; fname[0] = NULL; num_files = countFilesInDir(dirname,mask); if (!num_files) { return; } which_file = ll_rand(num_files); // llinfos << "Random select mp3 #" << which_file << llendl; // which_file now indicates the (zero-based) index to which file to play if ((random_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE) { while (which_file--) { if (!FindNextFile(random_search_h, &FileData)) { return; } } FindClose(random_search_h); fname = utf16str_to_utf8str(llutf16string(FileData.cFileName)); } }
static void utf8str_to_HFSUniStr255(HFSUniStr255 *dest, const char* src) { llutf16string utf16str = utf8str_to_utf16str(src); dest->length = utf16str.size(); if(dest->length > 255) { // There's onl room for 255 chars in a HFSUniStr25.. // Truncate to avoid stack smaching or other badness. dest->length = 255; } memcpy(dest->unicode, utf16str.data(), sizeof(UniChar)* dest->length); /* Flawfinder: ignore */ }
// <FS:ND> Special case for UTF-8 filenames under windows. As we cannot pass UTF-16 filenames into apr use a shortfilename, those are always ASCII std::string ndConvertFilename( std::string const &aFilename ) { #ifdef LL_WINDOWS // For safety reason (don't change any behaviour) do nothing different if filename is already ASCII std::string::const_iterator itr = std::find_if( aFilename.begin(), aFilename.end(), [&]( char const & aVal ){ return aVal < 0; } ); if( aFilename.end() == itr ) return aFilename; wchar_t aShort[ MAX_PATH ] = {0}; DWORD nRes = ::GetShortPathNameW( utf8str_to_utf16str( aFilename ).c_str(), aShort, _countof( aShort ) ); if( nRes == 0 || nRes >= _countof( aShort ) ) return aFilename; return utf16str_to_utf8str( aShort ); #else return aFilename; #endif }
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { if( mLocked ) { return FALSE; } BOOL success = FALSE; mOFN.lpstrFile = mFilesW; if (!filename.empty()) { llutf16string tstring = utf8str_to_utf16str(filename); wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ else { mFilesW[0] = '\0'; } mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); switch( filter ) { case FFSAVE_ALL: mOFN.lpstrDefExt = NULL; mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ L"WAV Sounds (*.wav)\0*.wav\0" \ L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ L"\0"; break; case FFSAVE_WAV: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"wav"; mOFN.lpstrFilter = L"WAV Sounds (*.wav)\0*.wav\0" \ L"\0"; break; case FFSAVE_TGA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"tga"; mOFN.lpstrFilter = L"Targa Images (*.tga)\0*.tga\0" \ L"\0"; break; case FFSAVE_BMP: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"bmp"; mOFN.lpstrFilter = L"Bitmap Images (*.bmp)\0*.bmp\0" \ L"\0"; break; case FFSAVE_PNG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"png"; mOFN.lpstrFilter = L"PNG Images (*.png)\0*.png\0" \ L"\0"; break; case FFSAVE_JPEG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"jpeg"; mOFN.lpstrFilter = L"JPEG Images (*.jpeg)\0*.jpeg\0" \ L"\0"; break; case FFSAVE_AVI: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"avi"; mOFN.lpstrFilter = L"AVI Movie File (*.avi)\0*.avi\0" \ L"\0"; break; case FFSAVE_ANIM: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"xaf"; mOFN.lpstrFilter = L"XAF Anim File (*.xaf)\0*.xaf\0" \ L"\0"; break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"slg"; mOFN.lpstrFilter = L"SLG SL Geometry File (*.slg)\0*.slg\0" \ L"\0"; break; #endif case FFSAVE_XML: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"xml"; mOFN.lpstrFilter = L"XML File (*.xml)\0*.xml\0" \ L"\0"; break; case FFSAVE_COLLADA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"collada"; mOFN.lpstrFilter = L"COLLADA File (*.collada)\0*.collada\0" \ L"\0"; break; case FFSAVE_RAW: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"raw"; mOFN.lpstrFilter = RAW_FILTER \ L"\0"; break; case FFSAVE_J2C: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"j2c"; mOFN.lpstrFilter = L"Compressed Images (*.j2c)\0*.j2c\0" \ L"\0"; break; default: return FALSE; } mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; reset(); // Modal, so pause agent send_agent_pause(); { // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetSaveFileName(&mOFN); if (success) { std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } gKeyboard->resetKeys(); } send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { if( mLocked ) { return FALSE; } BOOL success = FALSE; mOFN.lpstrFile = mFilesW; if (!filename.empty()) { llutf16string tstring = utf8str_to_utf16str(filename); wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ else { mFilesW[0] = '\0'; } mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); switch( filter ) { case FFSAVE_ALL: mOFN.lpstrDefExt = NULL; mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ L"WAV Sounds (*.wav)\0*.wav\0" \ L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ L"\0"; break; case FFSAVE_WAV: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"wav"; mOFN.lpstrFilter = L"WAV Sounds (*.wav)\0*.wav\0" \ L"\0"; break; case FFSAVE_TGA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"tga"; mOFN.lpstrFilter = L"Targa Images (*.tga)\0*.tga\0" \ L"\0"; break; case FFSAVE_BMP: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"bmp"; mOFN.lpstrFilter = L"Bitmap Images (*.bmp)\0*.bmp\0" \ L"\0"; break; case FFSAVE_PNG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"png"; mOFN.lpstrFilter = L"PNG Images (*.png)\0*.png\0" \ L"\0"; break; case FFSAVE_JPEG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"jpg"; mOFN.lpstrFilter = L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \ L"\0"; break; case FFSAVE_AVI: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"avi"; mOFN.lpstrFilter = L"AVI Movie File (*.avi)\0*.avi\0" \ L"\0"; break; case FFSAVE_ANIM: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.bvh", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"bvh"; mOFN.lpstrFilter = L"Anim File (*.bvh)\0*.bvh\0" \ L"\0"; break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"slg"; mOFN.lpstrFilter = L"SLG SL Geometry File (*.slg)\0*.slg\0" \ L"\0"; break; #endif case FFSAVE_XML: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"xml"; mOFN.lpstrFilter = L"XML File (*.xml)\0*.xml\0" \ L"\0"; break; case FFSAVE_COLLADA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"collada"; mOFN.lpstrFilter = L"COLLADA File (*.collada)\0*.collada\0" \ L"\0"; break; case FFSAVE_RAW: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"raw"; mOFN.lpstrFilter = RAW_FILTER \ L"\0"; break; case FFSAVE_J2C: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"j2c"; mOFN.lpstrFilter = L"Compressed Images (*.j2c)\0*.j2c\0" \ L"\0"; break; // <edit> case FFSAVE_ANIMATN: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.animatn", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"animatn"; mOFN.lpstrFilter = L"SL Animations (*.animatn)\0*.animatn\0" \ L"\0"; break; case FFSAVE_OGG: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.ogg", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"ogg"; mOFN.lpstrFilter = L"Ogg (*.ogg)\0*.ogg\0" \ L"\0"; break; case FFSAVE_NOTECARD: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.notecard", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"notecard"; mOFN.lpstrFilter = L"Notecards (*.notecard)\0*.notecard\0" \ L"\0"; break; case FFSAVE_GESTURE: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.gesture", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"gesture"; mOFN.lpstrFilter = L"Gestures (*.gesture)\0*.gesture\0" \ L"\0"; break; case FFSAVE_LSL: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"lsl"; mOFN.lpstrFilter = L"LSL (*.lsl)\0*.lsl\0" \ L"Text files (*.txt)\0*.txt\0" L"RTF Files (*.rtf)\0*.rtf\0" L"\0"; break; case FFSAVE_SHAPE: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.shape", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"shape"; mOFN.lpstrFilter = L"Shapes (*.shape)\0*.shape\0" \ L"\0"; break; case FFSAVE_SKIN: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.skin", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"skin"; mOFN.lpstrFilter = L"Skins (*.skin)\0*.skin\0" \ L"\0"; break; case FFSAVE_HAIR: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.hair", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"hair"; mOFN.lpstrFilter = L"Hair (*.hair)\0*.hair\0" \ L"\0"; break; case FFSAVE_EYES: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.eyes", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"eyes"; mOFN.lpstrFilter = L"Eyes (*.eyes)\0*.eyes\0" \ L"\0"; break; case FFSAVE_SHIRT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.shirt", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"shirt"; mOFN.lpstrFilter = L"Shirts (*.shirt)\0*.shirt\0" \ L"\0"; break; case FFSAVE_PANTS: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.pants", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"pants"; mOFN.lpstrFilter = L"Pants (*.pants)\0*.pants\0" \ L"\0"; break; case FFSAVE_SHOES: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.shoes", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"shoes"; mOFN.lpstrFilter = L"Shoes (*.shoes)\0*.shoes\0" \ L"\0"; break; case FFSAVE_SOCKS: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.socks", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"socks"; mOFN.lpstrFilter = L"Socks (*.socks)\0*.socks\0" \ L"\0"; break; case FFSAVE_JACKET: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.jacket", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"jacket"; mOFN.lpstrFilter = L"Jackets (*.jacket)\0*.jacket\0" \ L"\0"; break; case FFSAVE_GLOVES: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.gloves", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"gloves"; mOFN.lpstrFilter = L"Gloves (*.gloves)\0*.gloves\0" \ L"\0"; break; case FFSAVE_UNDERSHIRT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.undershirt", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"undershirt"; mOFN.lpstrFilter = L"Undershirts (*.undershirt)\0*.undershirt\0" \ L"\0"; break; case FFSAVE_UNDERPANTS: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.underpants", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"underpants"; mOFN.lpstrFilter = L"Underpants (*.underpants)\0*.underpants\0" \ L"\0"; break; case FFSAVE_SKIRT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.skirt", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"skirt"; mOFN.lpstrFilter = L"Skirts (*.skirt)\0*.skirt\0" \ L"\0"; break; case FFSAVE_LANDMARK: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.landmark", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"landmark"; mOFN.lpstrFilter = L"Landmarks (*.landmark)\0*.landmark\0" \ L"\0"; break; case FFSAVE_AO: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.ao", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"ao"; mOFN.lpstrFilter = L"Animation overrides (*.ao)\0*.ao\0" \ L"\0"; break; case FFSAVE_INVGZ: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.inv", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L".inv"; mOFN.lpstrFilter = L"InvCache (*.inv)\0*.inv\0" \ L"\0"; break; case FFSAVE_BLACKLIST: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.blacklist", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L".blacklist"; mOFN.lpstrFilter = L"Asset Blacklists (*.blacklist)\0*.blacklist\0" \ L"\0"; break; // </edit> default: return FALSE; } mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; reset(); // Modal, so pause agent send_agent_pause(); { // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetSaveFileName(&mOFN); if (success) { std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } gKeyboard->resetKeys(); } send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { WIN32_FIND_DATAW FileData; fname = ""; llutf16string pathname = dirname; pathname += utf8str_to_utf16str(mask); if (pathname != mCurrentDir) { // different dir specified, close old search if (mCurrentDir[0]) { FindClose(mDirSearch_h); } mCurrentDir = pathname; // and open new one // Check error opening Directory structure if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) == INVALID_HANDLE_VALUE) { // llinfos << "Unable to locate first file" << llendl; return(FALSE); } } else // get next file in list { // Find next entry if (!FindNextFile(mDirSearch_h, &FileData)) { if (GetLastError() == ERROR_NO_MORE_FILES) { // No more files, so reset to beginning of directory FindClose(mDirSearch_h); mCurrentDir[0] = NULL; if (wrap) { return(getNextFileInDir(pathname,"",fname,TRUE)); } else { fname[0] = 0; return(FALSE); } } else { // Error // llinfos << "Unable to locate next file" << llendl; return(FALSE); } } } // convert from TCHAR to char fname = utf16str_to_utf8str(FileData.cFileName); // fname now first name in list return(TRUE); }
// get the next file in the directory // automatically wrap if we've hit the end BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { llutf16string dirnamew = utf8str_to_utf16str(dirname); return getNextFileInDir(dirnamew, mask, fname, wrap); }
LLDir_Win32::LLDir_Win32() { mDirDelimiter = "\\"; WCHAR w_str[MAX_PATH]; // Application Data is where user settings go SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE); mOSUserDir = utf16str_to_utf8str(llutf16string(w_str)); // We want cache files to go on the local disk, even if the // user is on a network with a "roaming profile". // // On XP this is: // C:\Docments and Settings\James\Local Settings\Application Data // On Vista this is: // C:\Users\James\AppData\Local // // We used to store the cache in AppData\Roaming, and the installer // cleans up that version on upgrade. JC SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str)); if (GetTempPath(MAX_PATH, w_str)) { if (wcslen(w_str)) /* Flawfinder: ignore */ { w_str[wcslen(w_str)-1] = '\0'; /* Flawfinder: ignore */ // remove trailing slash } mTempDir = utf16str_to_utf8str(llutf16string(w_str)); } else { mTempDir = mOSUserDir; } // fprintf(stderr, "mTempDir = <%s>",mTempDir); #if 1 // Don't use the real app path for now, as we'll have to add parsing to detect if // we're in a developer tree, which has a different structure from the installed product. S32 size = GetModuleFileName(NULL, w_str, MAX_PATH); if (size) { w_str[size] = '\0'; mExecutablePathAndName = utf16str_to_utf8str(llutf16string(w_str)); S32 path_end = mExecutablePathAndName.find_last_of('\\'); if (path_end != std::string::npos) { mExecutableDir = mExecutablePathAndName.substr(0, path_end); mExecutableFilename = mExecutablePathAndName.substr(path_end+1, std::string::npos); } else { mExecutableFilename = mExecutablePathAndName; } GetCurrentDirectory(MAX_PATH, w_str); mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); } else { fprintf(stderr, "Couldn't get APP path, assuming current directory!"); GetCurrentDirectory(MAX_PATH, w_str); mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); // Assume it's the current directory } #else GetCurrentDirectory(MAX_PATH, w_str); mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); #endif if (mExecutableDir.find("indra") == std::string::npos) { // Running from installed directory. Make sure current // directory isn't something crazy (e.g. if invoking from // command line). SetCurrentDirectory(utf8str_to_utf16str(mExecutableDir).c_str()); GetCurrentDirectory(MAX_PATH, w_str); mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); } mAppRODataDir = mWorkingDir; llinfos << "mAppRODataDir = " << mAppRODataDir << llendl; mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; // Build the default cache directory mDefaultCacheDir = buildSLOSCacheDir(); // Make sure it exists int res = LLFile::mkdir(mDefaultCacheDir); if (res == -1) { if (errno != EEXIST) { llwarns << "Couldn't create LL_PATH_CACHE dir " << mDefaultCacheDir << llendl; } } mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; }
bool LLCrashLookupWindows::initFromDump(const std::string& strDumpPath) { m_nInstructionAddr = m_nModuleBaseAddr = 0; m_strModule.clear(); m_nModuleTimeStamp = m_nModuleChecksum = 0; m_nModuleVersion = 0; // Sanity check - make sure we have all the class instances if ( (!m_pDbgClient) || (!m_pDbgControl) || (!m_pDbgSymbols) ) return false; std::wstring strDumpPathW = utf8str_to_utf16str( strDumpPath ); // Open the minidump and wait to finish processing HRESULT hRes(S_OK); if( !m_pDbgClient4 ) hRes = m_pDbgClient->OpenDumpFile (strDumpPath.c_str()); else hRes = m_pDbgClient4->OpenDumpFileWide (strDumpPathW.c_str(),0); if (FAILED(hRes)) return false; m_pDbgControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); // Try to find an event that describes an exception ULONG nEventType = 0, nProcessId = 0, nThreadId = 0; BYTE bufContext[1024] = {0}; ULONG szContext = 0; hRes = m_pDbgControl->GetStoredEventInformation( &nEventType, &nProcessId, &nThreadId, bufContext, sizeof(bufContext), &szContext, NULL, 0, 0); if ( (FAILED(hRes)) || (DEBUG_EVENT_EXCEPTION != nEventType) ) return false; // Get the stack trace for the exception DEBUG_STACK_FRAME dbgStackFrames[MAX_STACK_FRAMES]; ULONG cntStackFrames = 0; BYTE* pbufStackFrameContexts = new BYTE[MAX_STACK_FRAMES * szContext]; hRes = m_pDbgControl->GetContextStackTrace( bufContext, szContext, dbgStackFrames, ARRAYSIZE(dbgStackFrames), pbufStackFrameContexts, MAX_STACK_FRAMES * szContext, szContext, &cntStackFrames); if ( (FAILED(hRes)) || (cntStackFrames < 1) ) return false; // Since the user won't have any debug symbols present we're really only interested in the top stack frame m_nInstructionAddr = dbgStackFrames[0].InstructionOffset; ULONG idxModule = 0; hRes = m_pDbgSymbols->GetModuleByOffset(m_nInstructionAddr, 0, &idxModule, &m_nModuleBaseAddr); if (FAILED(hRes)) return false; // Lookup the name of the module where the crash occurred CHAR strModule[MAX_PATH] = {0}; hRes = m_pDbgSymbols->GetModuleNameString( DEBUG_MODNAME_MODULE, DEBUG_ANY_ID, m_nModuleBaseAddr, strModule, ARRAYSIZE(strModule) - 1, NULL); if (FAILED(hRes)) return false; m_strModule = strModule; // Grab some basic properties we use for verification of the image DEBUG_MODULE_PARAMETERS dbgModuleParams; hRes = m_pDbgSymbols->GetModuleParameters(1, &m_nModuleBaseAddr, 0, &dbgModuleParams); if ( (SUCCEEDED(hRes)) && (DEBUG_INVALID_OFFSET != dbgModuleParams.Base) ) { m_nModuleTimeStamp = dbgModuleParams.TimeDateStamp; m_nModuleChecksum = dbgModuleParams.Checksum; } // Grab the version number as well BYTE bufVersionInfo[1024] = {0}; hRes = m_pDbgSymbols->GetModuleVersionInformation(DEBUG_ANY_ID, m_nModuleBaseAddr, "\\", bufVersionInfo, 1024, NULL); if (SUCCEEDED(hRes)) { VS_FIXEDFILEINFO* pFileInfo = (VS_FIXEDFILEINFO*)bufVersionInfo; m_nModuleVersion = ((U64)pFileInfo->dwFileVersionMS << 32) + pFileInfo->dwFileVersionLS; } return true; }