Release 960928
[wine/multimedia.git] / files / directory.c
blob5d12ef2890b675d8aca79651a3d14fe24d1a0cb8
1 /*
2 * DOS directories functions
4 * Copyright 1995 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
11 #include "windows.h"
12 #include "dos_fs.h"
13 #include "drive.h"
14 #include "file.h"
15 #include "msdos.h"
16 #include "options.h"
17 #include "xmalloc.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 #define MAX_PATH_ELEMENTS 20
23 static char *DIR_WindowsDosDir;
24 static char *DIR_WindowsUnixDir;
25 static char *DIR_SystemDosDir;
26 static char *DIR_SystemUnixDir;
27 static char *DIR_TempDosDir;
28 static char *DIR_TempUnixDir;
30 static char *DIR_DosPath[MAX_PATH_ELEMENTS]; /* Path in DOS format */
31 static char *DIR_UnixPath[MAX_PATH_ELEMENTS]; /* Path in Unix format */
32 static int DIR_PathElements = 0;
34 /***********************************************************************
35 * DIR_GetPath
37 * Get a path name from the wine.ini file and make sure it is valid.
39 static int DIR_GetPath( const char *keyname, const char *defval,
40 char **dos_path, char **unix_path )
42 char path[MAX_PATHNAME_LEN];
43 const char *dos_name ,*unix_name;
44 BYTE attr;
46 PROFILE_GetWineIniString( "wine", keyname, defval, path, sizeof(path) );
47 if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) ||
48 !FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) ||
49 !(attr & FA_DIRECTORY))
51 fprintf(stderr, "Invalid path '%s' for %s directory\n", path, keyname);
52 return 0;
54 if (!(dos_name = DOSFS_GetDosTrueName( unix_name, TRUE )))
56 fprintf( stderr, "Could not get DOS name for %s directory '%s'\n",
57 keyname, unix_name );
58 return 0;
60 *unix_path = xstrdup( unix_name );
61 *dos_path = xstrdup( dos_name );
62 return 1;
66 /***********************************************************************
67 * DIR_ParseWindowsPath
69 void DIR_ParseWindowsPath( char *path )
71 char *p;
72 const char *dos_name ,*unix_name;
73 BYTE attr;
74 int i;
76 for ( ; path && *path; path = p)
78 p = strchr( path, ';' );
79 if (p) while (*p == ';') *p++ = '\0';
81 if (DIR_PathElements >= MAX_PATH_ELEMENTS)
83 fprintf( stderr, "Warning: path has more than %d elements.\n",
84 MAX_PATH_ELEMENTS );
85 break;
87 if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) ||
88 !FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) ||
89 !(attr & FA_DIRECTORY))
91 fprintf(stderr,"Warning: invalid dir '%s' in path, deleting it.\n",
92 path );
93 continue;
95 if (!(dos_name = DOSFS_GetDosTrueName( unix_name, TRUE )))
97 fprintf( stderr, "Warning: could not get DOS name for '%s' in path, deleting it.\n",
98 unix_name );
99 continue;
101 DIR_UnixPath[DIR_PathElements] = xstrdup( unix_name );
102 DIR_DosPath[DIR_PathElements] = xstrdup( dos_name );
103 DIR_PathElements++;
106 if (debugging_dosfs)
107 for (i = 0; i < DIR_PathElements; i++)
109 dprintf_dosfs( stddeb, "Path[%d]: %s = %s\n",
110 i, DIR_DosPath[i], DIR_UnixPath[i] );
115 /***********************************************************************
116 * DIR_Init
118 int DIR_Init(void)
120 char path[MAX_PATHNAME_LEN], *env_p;
121 int drive;
122 const char *cwd;
124 if (!getcwd( path, MAX_PATHNAME_LEN ))
126 perror( "Could not get current directory" );
127 return 0;
129 cwd = path;
130 if ((drive = DRIVE_FindDriveRoot( &cwd )) == -1)
132 fprintf( stderr, "Warning: could not find DOS drive for cwd %s; starting in windows directory.\n",
133 cwd );
135 else
137 cwd = DOSFS_GetDosTrueName( path, TRUE );
138 DRIVE_SetCurrentDrive( drive );
139 DRIVE_Chdir( drive, cwd + 2 );
142 if (!(DIR_GetPath( "windows", "c:\\windows",
143 &DIR_WindowsDosDir, &DIR_WindowsUnixDir ))) return 0;
144 if (!(DIR_GetPath( "system", "c:\\windows\\system",
145 &DIR_SystemDosDir, &DIR_SystemUnixDir ))) return 0;
146 if (!(DIR_GetPath( "temp", "c:\\windows",
147 &DIR_TempDosDir, &DIR_TempUnixDir ))) return 0;
148 if (-1==access(DIR_TempUnixDir,W_OK)) {
149 if (errno==EACCES)
150 fprintf(stderr,"Warning: The Temporary Directory (as specified in wine.conf) is NOT writeable. Please check your configuration.\n");
151 else
152 fprintf(stderr,"Warning: Access to Temporary Directory failed (%s).\n",strerror(errno));
155 if (drive == -1)
157 drive = DIR_WindowsDosDir[0] - 'A';
158 DRIVE_SetCurrentDrive( drive );
159 DRIVE_Chdir( drive, DIR_WindowsDosDir + 2 );
162 PROFILE_GetWineIniString("wine", "path", "c:\\windows;c:\\windows\\system",
163 path, sizeof(path) );
164 DIR_ParseWindowsPath( path );
166 dprintf_dosfs( stddeb, "WindowsDir = %s\nSystemDir = %s\n",
167 DIR_WindowsDosDir, DIR_SystemDosDir );
168 dprintf_dosfs( stddeb, "TempDir = %s\nCwd = %c:\\%s\n",
169 DIR_TempDosDir, 'A' + drive, DRIVE_GetDosCwd( drive ) );
171 /* Put the temp and Windows directories into the environment */
173 env_p = (char *)xmalloc( strlen(DIR_TempDosDir) + 6 );
174 strcpy( env_p, "TEMP=" );
175 strcpy( env_p + 5, DIR_TempDosDir );
176 putenv( env_p );
177 env_p = (char *)xmalloc( strlen(DIR_WindowsDosDir) + 8 );
178 strcpy( env_p, "windir=" );
179 strcpy( env_p + 7, DIR_WindowsDosDir );
180 putenv( env_p );
182 return 1;
186 /***********************************************************************
187 * GetTempPath32A (KERNEL32.292)
189 UINT32 GetTempPath32A( UINT32 count, LPSTR path )
191 if (path) lstrcpyn32A( path, DIR_TempDosDir, count );
192 return strlen( DIR_TempDosDir );
196 /***********************************************************************
197 * GetTempPath32W (KERNEL32.293)
199 UINT32 GetTempPath32W( UINT32 count, LPWSTR path )
201 if (path) lstrcpynAtoW( path, DIR_TempDosDir, count );
202 return strlen( DIR_TempDosDir );
206 /***********************************************************************
207 * DIR_GetTempUnixDir
209 UINT32 DIR_GetTempUnixDir( LPSTR path, UINT32 count )
211 if (path) lstrcpyn32A( path, DIR_TempUnixDir, count );
212 return strlen( DIR_TempUnixDir );
216 /***********************************************************************
217 * DIR_GetWindowsUnixDir
219 UINT32 DIR_GetWindowsUnixDir( LPSTR path, UINT32 count )
221 if (path) lstrcpyn32A( path, DIR_WindowsUnixDir, count );
222 return strlen( DIR_WindowsUnixDir );
226 /***********************************************************************
227 * DIR_GetSystemUnixDir
229 UINT32 DIR_GetSystemUnixDir( LPSTR path, UINT32 count )
231 if (path) lstrcpyn32A( path, DIR_SystemUnixDir, count );
232 return strlen( DIR_SystemUnixDir );
236 /***********************************************************************
237 * DIR_GetDosPath
239 UINT32 DIR_GetDosPath( INT32 element, LPSTR path, UINT32 count )
241 if ((element < 0) || (element >= DIR_PathElements)) return 0;
242 if (path) lstrcpyn32A( path, DIR_DosPath[element], count );
243 return strlen( DIR_DosPath[element] );
247 /***********************************************************************
248 * GetTempDrive (KERNEL.92)
250 BYTE GetTempDrive( BYTE ignored )
252 /* FIXME: apparently Windows does something with the ignored byte */
253 return DIR_TempDosDir[0];
257 UINT32 WIN16_GetTempDrive( BYTE ignored )
259 /* A closer look at krnl386.exe shows what the SDK doesn't mention:
261 * returns:
262 * AL: driveletter
263 * AH: ':' - yes, some kernel code even does stosw with
264 * the returned AX.
265 * DX: 1 for success
267 return MAKELONG( GetTempDrive(ignored) | (':' << 8), 1 );
271 /***********************************************************************
272 * GetWindowsDirectory16 (KERNEL.134)
274 UINT16 GetWindowsDirectory16( LPSTR path, UINT16 count )
276 return (UINT16)GetWindowsDirectory32A( path, count );
280 /***********************************************************************
281 * GetWindowsDirectory32A (KERNEL32.311)
283 UINT32 GetWindowsDirectory32A( LPSTR path, UINT32 count )
285 if (path) lstrcpyn32A( path, DIR_WindowsDosDir, count );
286 return strlen( DIR_WindowsDosDir );
290 /***********************************************************************
291 * GetWindowsDirectory32W (KERNEL32.312)
293 UINT32 GetWindowsDirectory32W( LPWSTR path, UINT32 count )
295 if (path) lstrcpynAtoW( path, DIR_WindowsDosDir, count );
296 return strlen( DIR_WindowsDosDir );
300 /***********************************************************************
301 * GetSystemDirectory16 (KERNEL.135)
303 UINT16 GetSystemDirectory16( LPSTR path, UINT16 count )
305 return (UINT16)GetSystemDirectory32A( path, count );
309 /***********************************************************************
310 * GetSystemDirectory32A (KERNEL32.282)
312 UINT32 GetSystemDirectory32A( LPSTR path, UINT32 count )
314 if (path) lstrcpyn32A( path, DIR_SystemDosDir, count );
315 return strlen( DIR_SystemDosDir );
319 /***********************************************************************
320 * GetSystemDirectory32W (KERNEL32.283)
322 UINT32 GetSystemDirectory32W( LPWSTR path, UINT32 count )
324 if (path) lstrcpynAtoW( path, DIR_SystemDosDir, count );
325 return strlen( DIR_SystemDosDir );