1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus-core - osal/files_win32.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2009 Richard Goedeken *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 /* This file contains the definitions for the unix-specific file handling
26 #include <sys/types.h>
35 #include "api/m64p_types.h"
36 #include "api/callbacks.h"
38 /* definitions for system directories to search when looking for shared data files */
40 #define XSTR(S) STR(S) /* this wacky preprocessor thing is necessary to generate a quote-enclosed */
41 #define STR(S) #S /* copy of the SHAREDIR macro, which is defined by the makefile via gcc -DSHAREDIR="..." */
42 static const int datasearchdirs = 2;
43 static const char *datasearchpath[2] = { XSTR(SHAREDIR), ".\\" };
47 static const int datasearchdirs = 1;
48 static const char *datasearchpath[1] = { ".\\" };
52 static int search_dir_file(char *destpath, const char *path, const char *filename)
54 struct _stat fileinfo;
56 /* sanity check to start */
57 if (destpath == NULL || path == NULL || filename == NULL)
60 /* build the full filepath */
61 strcpy(destpath, path);
62 if (destpath[strlen(destpath)-1] != '\\')
63 strcat(destpath, "\\");
64 strcat(destpath, filename);
66 /* test for a valid file */
67 if (_stat(destpath, &fileinfo) != 0)
69 if ((fileinfo.st_mode & _S_IFREG) == 0)
72 /* success - file exists and is a regular file */
76 /* global functions */
78 int osal_mkdirp(const char *dirpath, int mode)
80 char *mypath, *currpath, *lastchar;
81 struct _stat fileinfo;
83 // Create a copy of the path, so we can modify it
84 mypath = currpath = _strdup(dirpath);
88 // if the directory path ends with a separator, remove it
89 lastchar = mypath + strlen(mypath) - 1;
90 if (strchr(OSAL_DIR_SEPARATORS, *lastchar) != NULL)
93 // Terminate quickly if the path already exists
94 if (_stat(mypath, &fileinfo) == 0 && (fileinfo.st_mode & _S_IFDIR))
97 while ((currpath = strpbrk(currpath + 1, OSAL_DIR_SEPARATORS)) != NULL)
99 // if slash is right after colon, then we are looking at drive name prefix (C:\) and should
100 // just skip it, because _stat and _mkdir will both fail for "C:"
101 if (currpath > mypath && currpath[-1] == ':')
104 if (_stat(mypath, &fileinfo) != 0)
106 if (_mkdir(mypath) != 0)
109 else if (!(fileinfo.st_mode & _S_IFDIR))
113 *currpath = OSAL_DIR_SEPARATORS[0];
117 if (_mkdir(mypath) != 0)
128 const char * osal_get_shared_filepath(const char *filename, const char *firstsearch, const char *secondsearch)
130 static char retpath[_MAX_PATH];
133 /* if caller gave us any directories to search, then look there first */
134 if (firstsearch != NULL && search_dir_file(retpath, firstsearch, filename) == 0)
136 if (secondsearch != NULL && search_dir_file(retpath, secondsearch, filename) == 0)
139 /* otherwise check our standard paths */
140 if (search_dir_file(retpath, osal_get_user_configpath(), filename) == 0)
142 for (i = 0; i < datasearchdirs; i++)
144 if (search_dir_file(retpath, datasearchpath[i], filename) == 0)
148 /* we couldn't find the file */
152 const char * osal_get_user_configpath(void)
154 static char chHomePath[MAX_PATH];
157 struct _stat fileinfo;
159 // Get item ID list for the path of user's personal directory
160 HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl);
161 // get the path in a char string
162 SHGetPathFromIDList(pidl, chHomePath);
163 // do a bunch of crap just to free some memory
164 hr = SHGetMalloc(&pMalloc);
165 pMalloc->lpVtbl->Free(pMalloc, pidl);
166 pMalloc->lpVtbl->Release(pMalloc);
168 // tack on 'mupen64plus'
169 if (chHomePath[strlen(chHomePath)-1] != '\\')
170 strcat(chHomePath, "\\");
171 strcat(chHomePath, "Mupen64Plus");
173 // if this directory doesn't exist, then make it
174 if (_stat(chHomePath, &fileinfo) == 0)
176 strcat(chHomePath, "\\");
181 osal_mkdirp(chHomePath, 0);
182 if (_stat(chHomePath, &fileinfo) == 0)
184 strcat(chHomePath, "\\");
189 /* otherwise we are in trouble */
190 DebugMessage(M64MSG_ERROR, "Failed to open configuration directory '%s'.", chHomePath);
194 const char * osal_get_user_datapath(void)
196 // in windows, these are all the same
197 return osal_get_user_configpath();
200 const char * osal_get_user_cachepath(void)
202 // in windows, these are all the same
203 return osal_get_user_configpath();