PageRenderTime 28ms CodeModel.GetById 12ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llvfs/lldir_win32.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 330 lines | 253 code | 42 blank | 35 comment | 23 complexity | 386cca0829b070e73affbdbb3680c981 MD5 | raw file
  1/** 
  2 * @file lldir_win32.cpp
  3 * @brief Implementation of directory utilities for windows
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#if LL_WINDOWS
 28
 29#include "linden_common.h"
 30
 31#include "lldir_win32.h"
 32#include "llerror.h"
 33#include "llrand.h"		// for gLindenLabRandomNumber
 34#include "shlobj.h"
 35
 36#include <direct.h>
 37#include <errno.h>
 38#include <sys/types.h>
 39#include <sys/stat.h>
 40
 41// Utility stuff to get versions of the sh
 42#define PACKVERSION(major,minor) MAKELONG(minor,major)
 43DWORD GetDllVersion(LPCTSTR lpszDllName);
 44
 45LLDir_Win32::LLDir_Win32()
 46{
 47	mDirDelimiter = "\\";
 48
 49	WCHAR w_str[MAX_PATH];
 50
 51	// Application Data is where user settings go
 52	SHGetSpecialFolderPath(NULL, w_str, CSIDL_APPDATA, TRUE);
 53
 54	mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
 55
 56	// We want cache files to go on the local disk, even if the
 57	// user is on a network with a "roaming profile".
 58	//
 59	// On XP this is:
 60	//   C:\Docments and Settings\James\Local Settings\Application Data
 61	// On Vista this is:
 62	//   C:\Users\James\AppData\Local
 63	//
 64	// We used to store the cache in AppData\Roaming, and the installer
 65	// cleans up that version on upgrade.  JC
 66	SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE);
 67	mOSCacheDir = utf16str_to_utf8str(llutf16string(w_str));
 68
 69	if (GetTempPath(MAX_PATH, w_str))
 70	{
 71		if (wcslen(w_str))	/* Flawfinder: ignore */ 
 72		{
 73			w_str[wcslen(w_str)-1] = '\0'; /* Flawfinder: ignore */ // remove trailing slash
 74		}
 75		mTempDir = utf16str_to_utf8str(llutf16string(w_str));
 76	}
 77	else
 78	{
 79		mTempDir = mOSUserDir;
 80	}
 81
 82//	fprintf(stderr, "mTempDir = <%s>",mTempDir);
 83
 84	// Set working directory, for LLDir::getWorkingDir()
 85	GetCurrentDirectory(MAX_PATH, w_str);
 86	mWorkingDir = utf16str_to_utf8str(llutf16string(w_str));
 87
 88	// Set the executable directory
 89	S32 size = GetModuleFileName(NULL, w_str, MAX_PATH);
 90	if (size)
 91	{
 92		w_str[size] = '\0';
 93		mExecutablePathAndName = utf16str_to_utf8str(llutf16string(w_str));
 94		S32 path_end = mExecutablePathAndName.find_last_of('\\');
 95		if (path_end != std::string::npos)
 96		{
 97			mExecutableDir = mExecutablePathAndName.substr(0, path_end);
 98			mExecutableFilename = mExecutablePathAndName.substr(path_end+1, std::string::npos);
 99		}
100		else
101		{
102			mExecutableFilename = mExecutablePathAndName;
103		}
104
105	}
106	else
107	{
108		fprintf(stderr, "Couldn't get APP path, assuming current directory!");
109		mExecutableDir = mWorkingDir;
110		// Assume it's the current directory
111	}
112
113	// mAppRODataDir = ".";	
114
115	// Determine the location of the App-Read-Only-Data
116	// Try the working directory then the exe's dir.
117	mAppRODataDir = mWorkingDir;	
118
119
120//	if (mExecutableDir.find("indra") == std::string::npos)
121	
122	// *NOTE:Mani - It is a mistake to put viewer specific code in
123	// the LLDir implementation. The references to 'skins' and 
124	// 'llplugin' need to go somewhere else.
125	// alas... this also gets called during static initialization 
126	// time due to the construction of gDirUtil in lldir.cpp.
127	if(! LLFile::isdir(mAppRODataDir + mDirDelimiter + "skins"))
128	{
129		// What? No skins in the working dir?
130		// Try the executable's directory.
131		mAppRODataDir = mExecutableDir;
132	}
133
134	llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
135
136	mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
137
138	// Build the default cache directory
139	mDefaultCacheDir = buildSLOSCacheDir();
140	
141	// Make sure it exists
142	int res = LLFile::mkdir(mDefaultCacheDir);
143	if (res == -1)
144	{
145		if (errno != EEXIST)
146		{
147			llwarns << "Couldn't create LL_PATH_CACHE dir " << mDefaultCacheDir << llendl;
148		}
149	}
150
151	mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
152}
153
154LLDir_Win32::~LLDir_Win32()
155{
156}
157
158// Implementation
159
160void LLDir_Win32::initAppDirs(const std::string &app_name,
161							  const std::string& app_read_only_data_dir)
162{
163	// Allow override so test apps can read newview directory
164	if (!app_read_only_data_dir.empty())
165	{
166		mAppRODataDir = app_read_only_data_dir;
167		mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
168	}
169	mAppName = app_name;
170	mOSUserAppDir = mOSUserDir;
171	mOSUserAppDir += "\\";
172	mOSUserAppDir += app_name;
173
174	int res = LLFile::mkdir(mOSUserAppDir);
175	if (res == -1)
176	{
177		if (errno != EEXIST)
178		{
179			llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl;
180			llwarns << "Default to base dir" << mOSUserDir << llendl;
181			mOSUserAppDir = mOSUserDir;
182		}
183	}
184	//dumpCurrentDirectories();
185
186	res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,""));
187	if (res == -1)
188	{
189		if (errno != EEXIST)
190		{
191			llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl;
192		}
193	}
194	
195	res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,""));
196	if (res == -1)
197	{
198		if (errno != EEXIST)
199		{
200			llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl;
201		}
202	}
203	
204	res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,""));
205	if (res == -1)
206	{
207		if (errno != EEXIST)
208		{
209			llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl;
210		}
211	}
212	
213	mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
214}
215
216U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &mask)
217{
218	HANDLE count_search_h;
219	U32 file_count;
220
221	file_count = 0;
222
223	WIN32_FIND_DATA FileData;
224
225	llutf16string pathname = utf8str_to_utf16str(dirname);
226	pathname += utf8str_to_utf16str(mask);
227	
228	if ((count_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
229	{
230		file_count++;
231
232		while (FindNextFile(count_search_h, &FileData))
233		{
234			file_count++;
235		}
236		   
237		FindClose(count_search_h);
238	}
239
240	return (file_count);
241}
242
243std::string LLDir_Win32::getCurPath()
244{
245	WCHAR w_str[MAX_PATH];
246	GetCurrentDirectory(MAX_PATH, w_str);
247
248	return utf16str_to_utf8str(llutf16string(w_str));
249}
250
251
252BOOL LLDir_Win32::fileExists(const std::string &filename) const
253{
254	llstat stat_data;
255	// Check the age of the file
256	// Now, we see if the files we've gathered are recent...
257	int res = LLFile::stat(filename, &stat_data);
258	if (!res)
259	{
260		return TRUE;
261	}
262	else
263	{
264		return FALSE;
265	}
266}
267
268
269/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
270{
271	return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
272		"SLPlugin.exe";
273}
274
275/*virtual*/ std::string LLDir_Win32::getLLPluginFilename(std::string base_name)
276{
277	return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
278		base_name + ".dll";
279}
280
281
282#if 0
283// Utility function to get version number of a DLL
284
285#define PACKVERSION(major,minor) MAKELONG(minor,major)
286
287DWORD GetDllVersion(LPCTSTR lpszDllName)
288{
289
290    HINSTANCE hinstDll;
291    DWORD dwVersion = 0;
292
293    hinstDll = LoadLibrary(lpszDllName);	/* Flawfinder: ignore */ 
294	
295    if(hinstDll)
296    {
297        DLLGETVERSIONPROC pDllGetVersion;
298
299        pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
300
301/*Because some DLLs might not implement this function, you
302  must test for it explicitly. Depending on the particular 
303  DLL, the lack of a DllGetVersion function can be a useful
304  indicator of the version.
305*/
306        if(pDllGetVersion)
307        {
308            DLLVERSIONINFO dvi;
309            HRESULT hr;
310
311            ZeroMemory(&dvi, sizeof(dvi));
312            dvi.cbSize = sizeof(dvi);
313
314            hr = (*pDllGetVersion)(&dvi);
315
316            if(SUCCEEDED(hr))
317            {
318                dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
319            }
320        }
321        
322        FreeLibrary(hinstDll);
323    }
324    return dwVersion;
325}
326#endif
327
328#endif
329
330