diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llvfs/lldir_win32.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llvfs/lldir_win32.cpp')
-rw-r--r-- | linden/indra/llvfs/lldir_win32.cpp | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/linden/indra/llvfs/lldir_win32.cpp b/linden/indra/llvfs/lldir_win32.cpp new file mode 100644 index 0000000..8dcaa5c --- /dev/null +++ b/linden/indra/llvfs/lldir_win32.cpp | |||
@@ -0,0 +1,401 @@ | |||
1 | /** | ||
2 | * @file lldir_win32.cpp | ||
3 | * @brief Implementation of directory utilities for windows | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #if LL_WINDOWS | ||
29 | |||
30 | #include "linden_common.h" | ||
31 | |||
32 | #include "lldir_win32.h" | ||
33 | #include "llerror.h" | ||
34 | #include "llrand.h" // for gLindenLabRandomNumber | ||
35 | #include "shlobj.h" | ||
36 | |||
37 | #include <direct.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) | ||
43 | DWORD GetDllVersion(LPCTSTR lpszDllName); | ||
44 | |||
45 | LLDir_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 | // Local Settings\Application Data is where cache files should | ||
57 | // go, they don't get copied to the server if the user moves his | ||
58 | // profile around on the network. JC | ||
59 | // | ||
60 | // TODO: patch the installer to remove old cache files on update, then | ||
61 | // enable this code. | ||
62 | //SHGetSpecialFolderPath(NULL, w_str, CSIDL_LOCAL_APPDATA, TRUE); | ||
63 | //mOSUserCacheDir = utf16str_to_utf8str(llutf16string(w_str)); | ||
64 | |||
65 | if (GetTempPath(MAX_PATH, w_str)) | ||
66 | { | ||
67 | if (wcslen(w_str)) | ||
68 | { | ||
69 | w_str[wcslen(w_str)-1] = '\0'; // remove trailing slash | ||
70 | } | ||
71 | mTempDir = utf16str_to_utf8str(llutf16string(w_str)); | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | mTempDir = mOSUserDir; | ||
76 | } | ||
77 | |||
78 | // fprintf(stderr, "mTempDir = <%s>",mTempDir); | ||
79 | |||
80 | #if 1 | ||
81 | // Don't use the real app path for now, as we'll have to add parsing to detect if | ||
82 | // we're in a developer tree, which has a different structure from the installed product. | ||
83 | |||
84 | S32 size = GetModuleFileName(NULL, w_str, MAX_PATH); | ||
85 | if (size) | ||
86 | { | ||
87 | w_str[size] = '\0'; | ||
88 | mExecutablePathAndName = utf16str_to_utf8str(llutf16string(w_str)); | ||
89 | S32 path_end = mExecutablePathAndName.find_last_of('\\'); | ||
90 | if (path_end != std::string::npos) | ||
91 | { | ||
92 | mExecutableDir = mExecutablePathAndName.substr(0, path_end); | ||
93 | mExecutableFilename = mExecutablePathAndName.substr(path_end+1, std::string::npos); | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | mExecutableFilename = mExecutablePathAndName; | ||
98 | } | ||
99 | GetCurrentDirectory(MAX_PATH, w_str); | ||
100 | mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); | ||
101 | |||
102 | } | ||
103 | else | ||
104 | { | ||
105 | fprintf(stderr, "Couldn't get APP path, assuming current directory!"); | ||
106 | GetCurrentDirectory(MAX_PATH, w_str); | ||
107 | mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); | ||
108 | // Assume it's the current directory | ||
109 | } | ||
110 | #else | ||
111 | GetCurrentDirectory(MAX_PATH, w_str); | ||
112 | mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); | ||
113 | #endif | ||
114 | if (strstr(mExecutableDir.c_str(), "indra\\newview")) | ||
115 | mAppRODataDir = getCurPath(); | ||
116 | else | ||
117 | mAppRODataDir = mExecutableDir; | ||
118 | } | ||
119 | |||
120 | LLDir_Win32::~LLDir_Win32() | ||
121 | { | ||
122 | } | ||
123 | |||
124 | // Implementation | ||
125 | |||
126 | void LLDir_Win32::initAppDirs(const std::string &app_name) | ||
127 | { | ||
128 | mAppName = app_name; | ||
129 | mOSUserAppDir = mOSUserDir; | ||
130 | mOSUserAppDir += "\\"; | ||
131 | mOSUserAppDir += app_name; | ||
132 | |||
133 | int res = LLFile::mkdir(mOSUserAppDir.c_str()); | ||
134 | if (res == -1) | ||
135 | { | ||
136 | if (errno != EEXIST) | ||
137 | { | ||
138 | llwarns << "Couldn't create app user dir " << mOSUserAppDir << llendl; | ||
139 | llwarns << "Default to base dir" << mOSUserDir << llendl; | ||
140 | mOSUserAppDir = mOSUserDir; | ||
141 | } | ||
142 | } | ||
143 | //dumpCurrentDirectories(); | ||
144 | |||
145 | res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,"").c_str()); | ||
146 | if (res == -1) | ||
147 | { | ||
148 | if (errno != EEXIST) | ||
149 | { | ||
150 | llwarns << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << llendl; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,"").c_str()); | ||
155 | if (res == -1) | ||
156 | { | ||
157 | if (errno != EEXIST) | ||
158 | { | ||
159 | llwarns << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << llendl; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,"").c_str()); | ||
164 | if (res == -1) | ||
165 | { | ||
166 | if (errno != EEXIST) | ||
167 | { | ||
168 | llwarns << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << llendl; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | res = LLFile::mkdir(getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"").c_str()); | ||
173 | if (res == -1) | ||
174 | { | ||
175 | if (errno != EEXIST) | ||
176 | { | ||
177 | llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem"); | ||
182 | } | ||
183 | |||
184 | U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &mask) | ||
185 | { | ||
186 | HANDLE count_search_h; | ||
187 | U32 file_count; | ||
188 | |||
189 | file_count = 0; | ||
190 | |||
191 | WIN32_FIND_DATA FileData; | ||
192 | |||
193 | llutf16string pathname = utf8str_to_utf16str(dirname); | ||
194 | pathname += utf8str_to_utf16str(mask); | ||
195 | |||
196 | if ((count_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE) | ||
197 | { | ||
198 | file_count++; | ||
199 | |||
200 | while (FindNextFile(count_search_h, &FileData)) | ||
201 | { | ||
202 | file_count++; | ||
203 | } | ||
204 | |||
205 | FindClose(count_search_h); | ||
206 | } | ||
207 | |||
208 | return (file_count); | ||
209 | } | ||
210 | |||
211 | |||
212 | // get the next file in the directory | ||
213 | // automatically wrap if we've hit the end | ||
214 | BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) | ||
215 | { | ||
216 | llutf16string dirnamew = utf8str_to_utf16str(dirname); | ||
217 | return getNextFileInDir(dirnamew, mask, fname, wrap); | ||
218 | |||
219 | } | ||
220 | |||
221 | BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap) | ||
222 | { | ||
223 | WIN32_FIND_DATAW FileData; | ||
224 | |||
225 | fname = ""; | ||
226 | llutf16string pathname = dirname; | ||
227 | pathname += utf8str_to_utf16str(mask); | ||
228 | |||
229 | if (pathname != mCurrentDir) | ||
230 | { | ||
231 | // different dir specified, close old search | ||
232 | if (mCurrentDir[0]) | ||
233 | { | ||
234 | FindClose(mDirSearch_h); | ||
235 | } | ||
236 | mCurrentDir = pathname; | ||
237 | |||
238 | // and open new one | ||
239 | // Check error opening Directory structure | ||
240 | if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) == INVALID_HANDLE_VALUE) | ||
241 | { | ||
242 | // llinfos << "Unable to locate first file" << llendl; | ||
243 | return(FALSE); | ||
244 | } | ||
245 | } | ||
246 | else // get next file in list | ||
247 | { | ||
248 | // Find next entry | ||
249 | if (!FindNextFile(mDirSearch_h, &FileData)) | ||
250 | { | ||
251 | if (GetLastError() == ERROR_NO_MORE_FILES) | ||
252 | { | ||
253 | // No more files, so reset to beginning of directory | ||
254 | FindClose(mDirSearch_h); | ||
255 | mCurrentDir[0] = NULL; | ||
256 | |||
257 | if (wrap) | ||
258 | { | ||
259 | return(getNextFileInDir(pathname,"",fname,TRUE)); | ||
260 | } | ||
261 | else | ||
262 | { | ||
263 | fname[0] = 0; | ||
264 | return(FALSE); | ||
265 | } | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | // Error | ||
270 | // llinfos << "Unable to locate next file" << llendl; | ||
271 | return(FALSE); | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | // convert from TCHAR to char | ||
277 | fname = utf16str_to_utf8str(FileData.cFileName); | ||
278 | |||
279 | // fname now first name in list | ||
280 | return(TRUE); | ||
281 | } | ||
282 | |||
283 | |||
284 | // get a random file in the directory | ||
285 | // automatically wrap if we've hit the end | ||
286 | void LLDir_Win32::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) | ||
287 | { | ||
288 | U32 num_files; | ||
289 | U32 which_file; | ||
290 | HANDLE random_search_h; | ||
291 | |||
292 | fname = ""; | ||
293 | |||
294 | llutf16string pathname = utf8str_to_utf16str(dirname); | ||
295 | pathname += utf8str_to_utf16str(mask); | ||
296 | |||
297 | WIN32_FIND_DATA FileData; | ||
298 | fname[0] = NULL; | ||
299 | |||
300 | num_files = countFilesInDir(dirname,mask); | ||
301 | if (!num_files) | ||
302 | { | ||
303 | return; | ||
304 | } | ||
305 | |||
306 | which_file = gLindenLabRandomNumber.llrand() % num_files; | ||
307 | |||
308 | // llinfos << "Random select mp3 #" << which_file << llendl; | ||
309 | |||
310 | // which_file now indicates the (zero-based) index to which file to play | ||
311 | |||
312 | if ((random_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE) | ||
313 | { | ||
314 | while (which_file--) | ||
315 | { | ||
316 | if (!FindNextFile(random_search_h, &FileData)) | ||
317 | { | ||
318 | return; | ||
319 | } | ||
320 | } | ||
321 | FindClose(random_search_h); | ||
322 | |||
323 | fname = utf16str_to_utf8str(llutf16string(FileData.cFileName)); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | std::string LLDir_Win32::getCurPath() | ||
328 | { | ||
329 | WCHAR w_str[MAX_PATH]; | ||
330 | GetCurrentDirectory(MAX_PATH, w_str); | ||
331 | |||
332 | return utf16str_to_utf8str(llutf16string(w_str)); | ||
333 | } | ||
334 | |||
335 | |||
336 | BOOL LLDir_Win32::fileExists(const std::string &filename) | ||
337 | { | ||
338 | llstat stat_data; | ||
339 | // Check the age of the file | ||
340 | // Now, we see if the files we've gathered are recent... | ||
341 | int res = LLFile::stat(filename.c_str(), &stat_data); | ||
342 | if (!res) | ||
343 | { | ||
344 | return TRUE; | ||
345 | } | ||
346 | else | ||
347 | { | ||
348 | return FALSE; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | |||
353 | #if 0 | ||
354 | // Utility function to get version number of a DLL | ||
355 | |||
356 | #define PACKVERSION(major,minor) MAKELONG(minor,major) | ||
357 | |||
358 | DWORD GetDllVersion(LPCTSTR lpszDllName) | ||
359 | { | ||
360 | |||
361 | HINSTANCE hinstDll; | ||
362 | DWORD dwVersion = 0; | ||
363 | |||
364 | hinstDll = LoadLibrary(lpszDllName); | ||
365 | |||
366 | if(hinstDll) | ||
367 | { | ||
368 | DLLGETVERSIONPROC pDllGetVersion; | ||
369 | |||
370 | pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion"); | ||
371 | |||
372 | /*Because some DLLs might not implement this function, you | ||
373 | must test for it explicitly. Depending on the particular | ||
374 | DLL, the lack of a DllGetVersion function can be a useful | ||
375 | indicator of the version. | ||
376 | */ | ||
377 | if(pDllGetVersion) | ||
378 | { | ||
379 | DLLVERSIONINFO dvi; | ||
380 | HRESULT hr; | ||
381 | |||
382 | ZeroMemory(&dvi, sizeof(dvi)); | ||
383 | dvi.cbSize = sizeof(dvi); | ||
384 | |||
385 | hr = (*pDllGetVersion)(&dvi); | ||
386 | |||
387 | if(SUCCEEDED(hr)) | ||
388 | { | ||
389 | dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | FreeLibrary(hinstDll); | ||
394 | } | ||
395 | return dwVersion; | ||
396 | } | ||
397 | #endif | ||
398 | |||
399 | #endif | ||
400 | |||
401 | |||