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

Generated on Fri May 16 08:33:01 2008 for SecondLife by  doxygen 1.5.5