lldir_win32.cpp

Go to the documentation of this file.
00001 
00032 #if LL_WINDOWS
00033 
00034 #include "linden_common.h"
00035 
00036 #include "lldir_win32.h"
00037 #include "llerror.h"
00038 #include "llrand.h"             // for gLindenLabRandomNumber
00039 #include "shlobj.h"
00040 
00041 #include <direct.h>
00042 #include <errno.h>
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <errno.h>
00046 
00047 // Utility stuff to get versions of the sh
00048 #define PACKVERSION(major,minor) MAKELONG(minor,major)
00049 DWORD GetDllVersion(LPCTSTR lpszDllName);
00050 
00051 LLDir_Win32::LLDir_Win32()
00052 {
00053         mDirDelimiter = "\\";
00054 
00055         WCHAR w_str[MAX_PATH];
00056 
00057         // Application Data is where user settings go
00058         SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE);
00059 
00060         mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
00061 
00062         // Local Settings\Application Data is where cache files should
00063         // go, they don't get copied to the server if the user moves his
00064         // profile around on the network. JC
00065         //
00066         // TODO: patch the installer to remove old cache files on update, then
00067         // enable this code.
00068         //SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE);
00069         //mOSUserCacheDir = utf16str_to_utf8str(llutf16string(w_str));
00070 
00071         if (GetTempPath(MAX_PATH, w_str))
00072         {
00073                 if (wcslen(w_str))      /* Flawfinder: ignore */ 
00074                 {
00075                         w_str[wcslen(w_str)-1] = '\0'; /* Flawfinder: ignore */ // remove trailing slash
00076                 }
00077                 mTempDir = utf16str_to_utf8str(llutf16string(w_str));
00078         }
00079         else
00080         {
00081                 mTempDir = mOSUserDir;
00082         }
00083 
00084 //      fprintf(stderr, "mTempDir = <%s>",mTempDir);
00085 
00086 #if 1
00087         // Don't use the real app path for now, as we'll have to add parsing to detect if
00088         // we're in a developer tree, which has a different structure from the installed product.
00089 
00090         S32 size = GetModuleFileName(NULL, w_str, MAX_PATH);
00091         if (size)
00092         {
00093                 w_str[size] = '\0';
00094                 mExecutablePathAndName = utf16str_to_utf8str(llutf16string(w_str));
00095                 S32 path_end = mExecutablePathAndName.find_last_of('\\');
00096                 if (path_end != std::string::npos)
00097                 {
00098                         mExecutableDir = mExecutablePathAndName.substr(0, path_end);
00099                         mExecutableFilename = mExecutablePathAndName.substr(path_end+1, std::string::npos);
00100                 }
00101                 else
00102                 {
00103                         mExecutableFilename = mExecutablePathAndName;
00104                 }
00105                 GetCurrentDirectory(MAX_PATH, w_str);
00106                 mWorkingDir = utf16str_to_utf8str(llutf16string(w_str));
00107 
00108         }
00109         else
00110         {
00111                 fprintf(stderr, "Couldn't get APP path, assuming current directory!");
00112                 GetCurrentDirectory(MAX_PATH, w_str);
00113                 mExecutableDir = utf16str_to_utf8str(llutf16string(w_str));
00114                 // Assume it's the current directory
00115         }
00116 #else
00117         GetCurrentDirectory(MAX_PATH, w_str);
00118         mExecutableDir = utf16str_to_utf8str(llutf16string(w_str));
00119 #endif
00120         if (strstr(mExecutableDir.c_str(), "indra\\newview"))
00121                 mAppRODataDir = getCurPath();
00122         else
00123                 mAppRODataDir = mExecutableDir;
00124 }
00125 
00126 LLDir_Win32::~LLDir_Win32()
00127 {
00128 }
00129 
00130 // Implementation
00131 
00132 void LLDir_Win32::initAppDirs(const std::string &app_name)
00133 {
00134         mAppName = app_name;
00135         mOSUserAppDir = mOSUserDir;
00136         mOSUserAppDir += "\\";
00137         mOSUserAppDir += app_name;
00138 
00139         int res = LLFile::mkdir(mOSUserAppDir.c_str());
00140         if (res == -1)
00141         {
00142                 if (errno != EEXIST)
00143                 {
00144                         llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
00145                         llwarns << "Default to base dir" << mOSUserDir << llendl;
00146                         mOSUserAppDir = mOSUserDir;
00147                 }
00148         }
00149         //dumpCurrentDirectories();
00150 
00151         res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,"").c_str());
00152         if (res == -1)
00153         {
00154                 if (errno != EEXIST)
00155                 {
00156                         llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
00157                 }
00158         }
00159         
00160         res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,"").c_str());
00161         if (res == -1)
00162         {
00163                 if (errno != EEXIST)
00164                 {
00165                         llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
00166                 }
00167         }
00168         
00169         res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,"").c_str());
00170         if (res == -1)
00171         {
00172                 if (errno != EEXIST)
00173                 {
00174                         llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
00175                 }
00176         }
00177         
00178         res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"").c_str());
00179         if (res == -1)
00180         {
00181                 if (errno != EEXIST)
00182                 {
00183                         llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
00184                 }
00185         }
00186         
00187         mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
00188 }
00189 
00190 U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &mask)
00191 {
00192         HANDLE count_search_h;
00193         U32 file_count;
00194 
00195         file_count = 0;
00196 
00197         WIN32_FIND_DATA FileData;
00198 
00199         llutf16string pathname = utf8str_to_utf16str(dirname);
00200         pathname += utf8str_to_utf16str(mask);
00201         
00202         if ((count_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
00203         {
00204                 file_count++;
00205 
00206                 while (FindNextFile(count_search_h, &FileData))
00207                 {
00208                         file_count++;
00209                 }
00210                    
00211                 FindClose(count_search_h);
00212         }
00213 
00214         return (file_count);
00215 }
00216 
00217 
00218 // get the next file in the directory
00219 // automatically wrap if we've hit the end
00220 BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
00221 {
00222         llutf16string dirnamew = utf8str_to_utf16str(dirname);
00223         return getNextFileInDir(dirnamew, mask, fname, wrap);
00224 
00225 }
00226 
00227 BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
00228 {
00229         WIN32_FIND_DATAW FileData;
00230 
00231         fname = "";
00232         llutf16string pathname = dirname;
00233         pathname += utf8str_to_utf16str(mask);
00234 
00235         if (pathname != mCurrentDir)
00236         {
00237                 // different dir specified, close old search
00238                 if (mCurrentDir[0])
00239                 {
00240                         FindClose(mDirSearch_h);
00241                 }
00242                 mCurrentDir = pathname;
00243 
00244                 // and open new one
00245                 // Check error opening Directory structure
00246                 if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) == INVALID_HANDLE_VALUE)   
00247                 {
00248 //                      llinfos << "Unable to locate first file" << llendl;
00249                         return(FALSE);
00250                 }
00251         }
00252         else // get next file in list
00253         {
00254                 // Find next entry
00255                 if (!FindNextFile(mDirSearch_h, &FileData))
00256                 {
00257                         if (GetLastError() == ERROR_NO_MORE_FILES)
00258                         {
00259                 // No more files, so reset to beginning of directory
00260                                 FindClose(mDirSearch_h);
00261                                 mCurrentDir[0] = NULL;
00262 
00263                                 if (wrap)
00264                                 {
00265                                         return(getNextFileInDir(pathname,"",fname,TRUE));
00266                                 }
00267                                 else
00268                                 {
00269                                         fname[0] = 0;
00270                                         return(FALSE);
00271                                 }
00272                         }
00273                         else
00274                         {
00275                                 // Error
00276 //                              llinfos << "Unable to locate next file" << llendl;
00277                                 return(FALSE);
00278                         }
00279                 }
00280         }
00281 
00282         // convert from TCHAR to char
00283         fname = utf16str_to_utf8str(FileData.cFileName);
00284         
00285         // fname now first name in list
00286         return(TRUE);
00287 }
00288 
00289 
00290 // get a random file in the directory
00291 // automatically wrap if we've hit the end
00292 void LLDir_Win32::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
00293 {
00294         S32 num_files;
00295         S32 which_file;
00296         HANDLE random_search_h;
00297 
00298         fname = "";
00299 
00300         llutf16string pathname = utf8str_to_utf16str(dirname);
00301         pathname += utf8str_to_utf16str(mask);
00302 
00303         WIN32_FIND_DATA FileData;
00304         fname[0] = NULL;
00305 
00306         num_files = countFilesInDir(dirname,mask);
00307         if (!num_files)
00308         {
00309                 return;
00310         }
00311 
00312         which_file = ll_rand(num_files);
00313 
00314 //      llinfos << "Random select mp3 #" << which_file << llendl;
00315 
00316     // which_file now indicates the (zero-based) index to which file to play
00317 
00318         if ((random_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
00319         {
00320                 while (which_file--)
00321                 {
00322                         if (!FindNextFile(random_search_h, &FileData))
00323                         {
00324                                 return;
00325                         }
00326                 }                  
00327                 FindClose(random_search_h);
00328 
00329                 fname = utf16str_to_utf8str(llutf16string(FileData.cFileName));
00330         }
00331 }
00332 
00333 std::string LLDir_Win32::getCurPath()
00334 {
00335         WCHAR w_str[MAX_PATH];
00336         GetCurrentDirectory(MAX_PATH, w_str);
00337 
00338         return utf16str_to_utf8str(llutf16string(w_str));
00339 }
00340 
00341 
00342 BOOL LLDir_Win32::fileExists(const std::string &filename)
00343 {
00344         llstat stat_data;
00345         // Check the age of the file
00346         // Now, we see if the files we've gathered are recent...
00347         int res = LLFile::stat(filename.c_str(), &stat_data);
00348         if (!res)
00349         {
00350                 return TRUE;
00351         }
00352         else
00353         {
00354                 return FALSE;
00355         }
00356 }
00357 
00358 
00359 #if 0
00360 // Utility function to get version number of a DLL
00361 
00362 #define PACKVERSION(major,minor) MAKELONG(minor,major)
00363 
00364 DWORD GetDllVersion(LPCTSTR lpszDllName)
00365 {
00366 
00367     HINSTANCE hinstDll;
00368     DWORD dwVersion = 0;
00369 
00370     hinstDll = LoadLibrary(lpszDllName);        /* Flawfinder: ignore */ 
00371         
00372     if(hinstDll)
00373     {
00374         DLLGETVERSIONPROC pDllGetVersion;
00375 
00376         pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
00377 
00378 /*Because some DLLs might not implement this function, you
00379   must test for it explicitly. Depending on the particular 
00380   DLL, the lack of a DllGetVersion function can be a useful
00381   indicator of the version.
00382 */
00383         if(pDllGetVersion)
00384         {
00385             DLLVERSIONINFO dvi;
00386             HRESULT hr;
00387 
00388             ZeroMemory(&dvi, sizeof(dvi));
00389             dvi.cbSize = sizeof(dvi);
00390 
00391             hr = (*pDllGetVersion)(&dvi);
00392 
00393             if(SUCCEEDED(hr))
00394             {
00395                 dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
00396             }
00397         }
00398         
00399         FreeLibrary(hinstDll);
00400     }
00401     return dwVersion;
00402 }
00403 #endif
00404 
00405 #endif
00406 
00407 

Generated on Thu Jul 1 06:08:24 2010 for Second Life Viewer by  doxygen 1.4.7