blob: 07049f6a64896ecf6ae5a55b7d31423b1521769d [file] [log] [blame]
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +00001/*
2 * DOS directories functions
3 *
4 * Copyright 1995 Alexandre Julliard
5 */
6
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10
11#include "windows.h"
12#include "dos_fs.h"
13#include "drive.h"
14#include "file.h"
15#include "msdos.h"
Alexandre Julliard7e56f681996-01-31 19:02:28 +000016#include "options.h"
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000017#include "xmalloc.h"
Alexandre Julliard3051b641996-07-05 17:14:13 +000018#include "string32.h"
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000019#include "stddebug.h"
20#include "debug.h"
Alexandre Julliard3051b641996-07-05 17:14:13 +000021#include "string32.h"
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000022
23#define MAX_PATH_ELEMENTS 20
24
25static char *DIR_WindowsDosDir;
26static char *DIR_WindowsUnixDir;
27static char *DIR_SystemDosDir;
28static char *DIR_SystemUnixDir;
29static char *DIR_TempDosDir;
30static char *DIR_TempUnixDir;
31
32static char *DIR_DosPath[MAX_PATH_ELEMENTS]; /* Path in DOS format */
33static char *DIR_UnixPath[MAX_PATH_ELEMENTS]; /* Path in Unix format */
34static int DIR_PathElements = 0;
35
36/***********************************************************************
37 * DIR_GetPath
38 *
39 * Get a path name from the wine.ini file and make sure it is valid.
40 */
41static int DIR_GetPath( const char *keyname, const char *defval,
42 char **dos_path, char **unix_path )
43{
44 char path[MAX_PATHNAME_LEN];
45 const char *dos_name ,*unix_name;
46 BYTE attr;
47
Alexandre Julliard7e56f681996-01-31 19:02:28 +000048 PROFILE_GetWineIniString( "wine", keyname, defval, path, sizeof(path) );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +000049 if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) ||
50 !FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) ||
51 !(attr & FA_DIRECTORY))
52 {
53 fprintf(stderr, "Invalid path '%s' for %s directory\n", path, keyname);
54 return 0;
55 }
56 if (!(dos_name = DOSFS_GetDosTrueName( unix_name, TRUE )))
57 {
58 fprintf( stderr, "Could not get DOS name for %s directory '%s'\n",
59 keyname, unix_name );
60 return 0;
61 }
62 *unix_path = xstrdup( unix_name );
63 *dos_path = xstrdup( dos_name );
64 return 1;
65}
66
67
68/***********************************************************************
69 * DIR_ParseWindowsPath
70 */
71void DIR_ParseWindowsPath( char *path )
72{
73 char *p;
74 const char *dos_name ,*unix_name;
75 BYTE attr;
76 int i;
77
78 for ( ; path && *path; path = p)
79 {
80 p = strchr( path, ';' );
81 if (p) while (*p == ';') *p++ = '\0';
82
83 if (DIR_PathElements >= MAX_PATH_ELEMENTS)
84 {
85 fprintf( stderr, "Warning: path has more than %d elements.\n",
86 MAX_PATH_ELEMENTS );
87 break;
88 }
89 if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) ||
90 !FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) ||
91 !(attr & FA_DIRECTORY))
92 {
93 fprintf(stderr,"Warning: invalid dir '%s' in path, deleting it.\n",
94 path );
95 continue;
96 }
97 if (!(dos_name = DOSFS_GetDosTrueName( unix_name, TRUE )))
98 {
99 fprintf( stderr, "Warning: could not get DOS name for '%s' in path, deleting it.\n",
100 unix_name );
101 continue;
102 }
103 DIR_UnixPath[DIR_PathElements] = xstrdup( unix_name );
104 DIR_DosPath[DIR_PathElements] = xstrdup( dos_name );
105 DIR_PathElements++;
106 }
107
108 if (debugging_dosfs)
109 for (i = 0; i < DIR_PathElements; i++)
110 {
111 dprintf_dosfs( stddeb, "Path[%d]: %s = %s\n",
112 i, DIR_DosPath[i], DIR_UnixPath[i] );
113 }
114}
115
116
117/***********************************************************************
118 * DIR_Init
119 */
120int DIR_Init(void)
121{
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000122 char path[MAX_PATHNAME_LEN], *env_p;
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000123 int drive;
124 const char *cwd;
125
126 if (!getcwd( path, MAX_PATHNAME_LEN ))
127 {
128 perror( "Could not get current directory" );
129 return 0;
130 }
131 cwd = path;
132 if ((drive = DRIVE_FindDriveRoot( &cwd )) == -1)
133 {
134 fprintf( stderr, "Warning: could not find DOS drive for cwd %s; starting in windows directory.\n",
135 cwd );
136 }
137 else
138 {
139 cwd = DOSFS_GetDosTrueName( path, TRUE );
140 DRIVE_SetCurrentDrive( drive );
141 DRIVE_Chdir( drive, cwd + 2 );
142 }
143
144 if (!(DIR_GetPath( "windows", "c:\\windows",
145 &DIR_WindowsDosDir, &DIR_WindowsUnixDir ))) return 0;
146 if (!(DIR_GetPath( "system", "c:\\windows\\system",
147 &DIR_SystemDosDir, &DIR_SystemUnixDir ))) return 0;
148 if (!(DIR_GetPath( "temp", "c:\\windows",
149 &DIR_TempDosDir, &DIR_TempUnixDir ))) return 0;
Alexandre Julliard8bbf8181996-09-13 16:50:47 +0000150 if (-1==access(DIR_TempUnixDir,W_OK)) {
151 if (errno==EACCES)
152 fprintf(stderr,"Warning: The Temporary Directory (as specified in wine.conf) is NOT writeable. Please check your configuration.\n");
153 else
154 fprintf(stderr,"Warning: Access to Temporary Directory failed (%s).\n",strerror(errno));
155 }
156
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000157 if (drive == -1)
158 {
159 drive = DIR_WindowsDosDir[0] - 'A';
160 DRIVE_SetCurrentDrive( drive );
161 DRIVE_Chdir( drive, DIR_WindowsDosDir + 2 );
162 }
163
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000164 PROFILE_GetWineIniString("wine", "path", "c:\\windows;c:\\windows\\system",
165 path, sizeof(path) );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000166 DIR_ParseWindowsPath( path );
167
168 dprintf_dosfs( stddeb, "WindowsDir = %s\nSystemDir = %s\n",
169 DIR_WindowsDosDir, DIR_SystemDosDir );
170 dprintf_dosfs( stddeb, "TempDir = %s\nCwd = %c:\\%s\n",
171 DIR_TempDosDir, 'A' + drive, DRIVE_GetDosCwd( drive ) );
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000172
173 /* Put the temp and Windows directories into the environment */
174
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000175 env_p = (char *)xmalloc( strlen(DIR_TempDosDir) + 6 );
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000176 strcpy( env_p, "TEMP=" );
177 strcpy( env_p + 5, DIR_TempDosDir );
178 putenv( env_p );
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000179 env_p = (char *)xmalloc( strlen(DIR_WindowsDosDir) + 8 );
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000180 strcpy( env_p, "windir=" );
181 strcpy( env_p + 7, DIR_WindowsDosDir );
182 putenv( env_p );
183
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000184 return 1;
185}
186
187
188/***********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +0000189 * GetTempPath32A (KERNEL32.292)
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000190 */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000191UINT32 GetTempPath32A( UINT32 count, LPSTR path )
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000192{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000193 if (path) lstrcpyn32A( path, DIR_TempDosDir, count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000194 return strlen( DIR_TempDosDir );
195}
196
197
198/***********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +0000199 * GetTempPath32W (KERNEL32.293)
200 */
201UINT32 GetTempPath32W( UINT32 count, LPWSTR path )
202{
203 LPSTR tmp = (char*)xmalloc(count);
204 UINT32 len = GetTempPath32A( count, tmp );
205 if (path) STRING32_AnsiToUni( path, tmp );
206 free(tmp);
207 return len;
208}
209
210
211/***********************************************************************
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000212 * DIR_GetTempUnixDir
213 */
214UINT DIR_GetTempUnixDir( LPSTR path, UINT count )
215{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000216 if (path) lstrcpyn32A( path, DIR_TempUnixDir, count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000217 return strlen( DIR_TempUnixDir );
218}
219
220
221/***********************************************************************
222 * DIR_GetWindowsUnixDir
223 */
224UINT DIR_GetWindowsUnixDir( LPSTR path, UINT count )
225{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000226 if (path) lstrcpyn32A( path, DIR_WindowsUnixDir, count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000227 return strlen( DIR_WindowsUnixDir );
228}
229
230
231/***********************************************************************
232 * DIR_GetSystemUnixDir
233 */
234UINT DIR_GetSystemUnixDir( LPSTR path, UINT count )
235{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000236 if (path) lstrcpyn32A( path, DIR_SystemUnixDir, count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000237 return strlen( DIR_SystemUnixDir );
238}
239
240
241/***********************************************************************
242 * DIR_GetDosPath
243 */
244UINT DIR_GetDosPath( int element, LPSTR path, UINT count )
245{
246 if ((element < 0) || (element >= DIR_PathElements)) return 0;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000247 if (path) lstrcpyn32A( path, DIR_DosPath[element], count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000248 return strlen( DIR_DosPath[element] );
249}
250
251
252/***********************************************************************
253 * GetTempDrive (KERNEL.92)
254 */
255BYTE GetTempDrive( BYTE ignored )
256{
Alexandre Julliardca22b331996-07-12 19:02:39 +0000257 /* FIXME: apparently Windows does something with the ignored byte */
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000258 return DIR_TempDosDir[0];
259}
260
261
Alexandre Julliardca22b331996-07-12 19:02:39 +0000262UINT32 WIN16_GetTempDrive( BYTE ignored )
263{
264 /* A closer look at krnl386.exe shows what the SDK doesn't mention:
265 *
266 * returns:
267 * AL: driveletter
268 * AH: ':' - yes, some kernel code even does stosw with
269 * the returned AX.
270 * DX: 1 for success
271 */
272 return MAKELONG( GetTempDrive(ignored) | (':' << 8), 1 );
273}
274
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000275/***********************************************************************
276 * GetWindowsDirectory (KERNEL.134)
277 */
278UINT GetWindowsDirectory( LPSTR path, UINT count )
279{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000280 if (path) lstrcpyn32A( path, DIR_WindowsDosDir, count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000281 return strlen( DIR_WindowsDosDir );
282}
283
284
285/***********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +0000286 * GetSystemDirectory16 (KERNEL.135)
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000287 */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000288UINT16 GetSystemDirectory16( LPSTR path, UINT16 count )
289{
290 return (UINT16)GetSystemDirectory32A( path, count );
291}
292
293
294/***********************************************************************
295 * GetSystemDirectory32A (KERNEL32.282)
296 */
297UINT32 GetSystemDirectory32A( LPSTR path, UINT32 count )
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000298{
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000299 if (path) lstrcpyn32A( path, DIR_SystemDosDir, count );
Alexandre Julliard4f8c37b1996-01-14 18:12:01 +0000300 return strlen( DIR_SystemDosDir );
301}
Alexandre Julliard3051b641996-07-05 17:14:13 +0000302
303
304/***********************************************************************
305 * GetSystemDirectory32W (KERNEL32.283)
306 */
307UINT32 GetSystemDirectory32W( LPWSTR path, UINT32 count )
308{
309 if (path)
310 {
311 LPWSTR tmp = STRING32_DupAnsiToUni( DIR_SystemDosDir );
312 lstrcpyn32W( path, tmp, count );
313 free (tmp);
314 }
315 return strlen( DIR_SystemDosDir );
316}