summaryrefslogtreecommitdiff
path: root/indra/llvfs/lldir_win32.cpp
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/llvfs/lldir_win32.cpp
Print done when done.
Diffstat (limited to 'indra/llvfs/lldir_win32.cpp')
-rw-r--r--indra/llvfs/lldir_win32.cpp382
1 files changed, 382 insertions, 0 deletions
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
new file mode 100644
index 0000000000..0c5b0ecf19
--- /dev/null
+++ b/indra/llvfs/lldir_win32.cpp
@@ -0,0 +1,382 @@
+/**
+ * @file lldir_win32.cpp
+ * @brief Implementation of directory utilities for windows
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#if LL_WINDOWS
+
+#include "linden_common.h"
+
+#include "lldir_win32.h"
+#include "llerror.h"
+#include "llrand.h" // for gLindenLabRandomNumber
+#include "shlobj.h"
+
+#include <direct.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+// Utility stuff to get versions of the sh
+#define PACKVERSION(major,minor) MAKELONG(minor,major)
+DWORD GetDllVersion(LPCTSTR lpszDllName);
+
+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));
+
+ // Local Settings\Application Data is where cache files should
+ // go, they don't get copied to the server if the user moves his
+ // profile around on the network. JC
+ //
+ // TODO: patch the installer to remove old cache files on update, then
+ // enable this code.
+ //SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE);
+ //mOSUserCacheDir = utf16str_to_utf8str(llutf16string(w_str));
+
+ if (GetTempPath(MAX_PATH, w_str))
+ {
+ if (wcslen(w_str))
+ {
+ w_str[wcslen(w_str)-1] = '\0'; // 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 (strstr(mExecutableDir.c_str(), "indra\\newview"))
+ mAppRODataDir = getCurPath();
+ else
+ mAppRODataDir = mExecutableDir;
+}
+
+LLDir_Win32::~LLDir_Win32()
+{
+}
+
+// Implementation
+
+void LLDir_Win32::initAppDirs(const std::string &app_name)
+{
+ mAppName = app_name;
+ mOSUserAppDir = mOSUserDir;
+ mOSUserAppDir += "\\";
+ mOSUserAppDir += app_name;
+
+ int res = LLFile::mkdir(mOSUserAppDir.c_str());
+ if (res == -1)
+ {
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
+ llwarns << "Default to base dir" << mOSUserDir << llendl;
+ mOSUserAppDir = mOSUserDir;
+ }
+ }
+ //dumpCurrentDirectories();
+
+ res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,"").c_str());
+ if (res == -1)
+ {
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
+ }
+ }
+
+ res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,"").c_str());
+ if (res == -1)
+ {
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
+ }
+ }
+
+ res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,"").c_str());
+ if (res == -1)
+ {
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
+ }
+ }
+
+ res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"").c_str());
+ if (res == -1)
+ {
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
+ }
+ }
+
+ mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
+}
+
+U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &mask)
+{
+ HANDLE count_search_h;
+ U32 file_count;
+
+ file_count = 0;
+
+ WIN32_FIND_DATA FileData;
+
+ llutf16string pathname = utf8str_to_utf16str(dirname);
+ pathname += utf8str_to_utf16str(mask);
+
+ if ((count_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)
+ {
+ file_count++;
+
+ while (FindNextFile(count_search_h, &FileData))
+ {
+ file_count++;
+ }
+
+ FindClose(count_search_h);
+ }
+
+ return (file_count);
+}
+
+
+// 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);
+
+}
+
+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 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)
+{
+ U32 num_files;
+ U32 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 = gLindenLabRandomNumber.llrand() % 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));
+ }
+}
+
+std::string LLDir_Win32::getCurPath()
+{
+ WCHAR w_str[MAX_PATH];
+ GetCurrentDirectory(MAX_PATH, w_str);
+
+ return utf16str_to_utf8str(llutf16string(w_str));
+}
+
+
+BOOL LLDir_Win32::fileExists(const std::string &filename)
+{
+ llstat stat_data;
+ // Check the age of the file
+ // Now, we see if the files we've gathered are recent...
+ int res = LLFile::stat(filename.c_str(), &stat_data);
+ if (!res)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+#if 0
+// Utility function to get version number of a DLL
+
+#define PACKVERSION(major,minor) MAKELONG(minor,major)
+
+DWORD GetDllVersion(LPCTSTR lpszDllName)
+{
+
+ HINSTANCE hinstDll;
+ DWORD dwVersion = 0;
+
+ hinstDll = LoadLibrary(lpszDllName);
+
+ if(hinstDll)
+ {
+ DLLGETVERSIONPROC pDllGetVersion;
+
+ pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
+
+/*Because some DLLs might not implement this function, you
+ must test for it explicitly. Depending on the particular
+ DLL, the lack of a DllGetVersion function can be a useful
+ indicator of the version.
+*/
+ if(pDllGetVersion)
+ {
+ DLLVERSIONINFO dvi;
+ HRESULT hr;
+
+ ZeroMemory(&dvi, sizeof(dvi));
+ dvi.cbSize = sizeof(dvi);
+
+ hr = (*pDllGetVersion)(&dvi);
+
+ if(SUCCEEDED(hr))
+ {
+ dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
+ }
+ }
+
+ FreeLibrary(hinstDll);
+ }
+ return dwVersion;
+}
+#endif
+
+#endif
+
+