Added support in winebuild for resolving function imports (-sym option).
[wine/multimedia.git] / dlls / crtdll / dir.c
blob5122cb490b9e20b61b90dcaf8bb2fb5871cd124b
1 /*
2 * CRTDLL drive/directory functions
3 *
4 * Copyright 1996,1998 Marcus Meissner
5 * Copyright 1996 Jukka Iivonen
6 * Copyright 1997,2000 Uwe Bonnes
7 * Copyright 2000 Jon Griffiths
10 * Implementation Notes:
11 * MT Safe.
14 #include "crtdll.h"
15 #include <errno.h>
17 #include "drive.h"
18 #include <time.h>
19 #include "file.h"
21 DEFAULT_DEBUG_CHANNEL(crtdll);
23 /* INTERNAL: Translate find_t to PWIN32_FIND_DATAA */
24 static void __CRTDLL__fttofd(LPWIN32_FIND_DATAA fd, find_t* ft);
25 static void __CRTDLL__fttofd(LPWIN32_FIND_DATAA fd, find_t* ft)
27 static DWORD dummy;
29 /* Tested with crtdll.dll Version 2.50.4170 (NT) from win98 SE:
30 * attrib 0x80 (FILE_ATTRIBUTE_NORMAL)is returned as 0.
32 if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
33 ft->attrib = 0;
34 else
35 ft->attrib = fd->dwFileAttributes;
37 ft->time_create = DOSFS_FileTimeToUnixTime(&fd->ftCreationTime,&dummy);
38 ft->time_access = DOSFS_FileTimeToUnixTime(&fd->ftLastAccessTime,&dummy);
39 ft->time_write = DOSFS_FileTimeToUnixTime(&fd->ftLastWriteTime,&dummy);
40 ft->size = fd->nFileSizeLow;
41 strcpy(ft->name, fd->cFileName);
45 /*********************************************************************
46 * _chdir (CRTDLL.51)
48 * Change the current directory.
50 * PARAMS
51 * newdir [in] Directory to change to
53 * RETURNS
54 * Sucess: 0
56 * Failure: -1
58 INT __cdecl CRTDLL__chdir(LPCSTR newdir)
60 if (!SetCurrentDirectoryA(newdir))
62 __CRTDLL__set_errno(newdir?GetLastError():0);
63 return -1;
65 return 0;
69 /*********************************************************************
70 * _chdrive (CRTDLL.52)
72 * Change the current drive.
74 * PARAMS
75 * newdrive [in] new drive to change to, A: =1, B: =2, etc
77 * RETURNS
78 * Sucess: 0
80 * Failure: 1
82 BOOL __cdecl CRTDLL__chdrive(INT newdrive)
84 if (!DRIVE_SetCurrentDrive(newdrive-1))
86 __CRTDLL__set_errno(GetLastError());
87 if (newdrive <= 0)
88 CRTDLL_errno = EACCES;
89 return -1;
91 return 0;
95 /*********************************************************************
96 * _findclose (CRTDLL.098)
98 * Free the resources from a search handle created from _findfirst.
100 * PARAMS
101 * hand [in]: Search handle to close
103 * RETURNS
104 * Success: 0
106 * Failure: -1
108 INT __cdecl CRTDLL__findclose(DWORD hand)
110 TRACE(":handle %ld\n",hand);
111 if (!FindClose((HANDLE)hand))
113 __CRTDLL__set_errno(GetLastError());
114 return -1;
116 return 0;
120 /*********************************************************************
121 * _findfirst (CRTDLL.099)
123 * Create and return a search handle for iterating through a file and
124 * directory list.
126 * PARAMS
127 * fspec [in] File specification string for search, e.g "C:\*.BAT"
129 * ft [out] A pointer to a find_t structure to populate.
131 * RETURNS
132 * Success: A handle for the search, suitable for passing to _findnext
133 * or _findclose. Populates the members of ft with the details
134 * of the first matching file.
136 * Failure: -1.
138 DWORD __cdecl CRTDLL__findfirst(LPCSTR fspec, find_t* ft)
140 WIN32_FIND_DATAA find_data;
141 HANDLE hfind;
143 hfind = FindFirstFileA(fspec, &find_data);
144 if (hfind == INVALID_HANDLE_VALUE)
146 __CRTDLL__set_errno(GetLastError());
147 return -1;
149 __CRTDLL__fttofd(&find_data,ft);
150 TRACE(":got handle %d\n",hfind);
151 return hfind;
155 /*********************************************************************
156 * _findnext (CRTDLL.100)
158 * Return the next matching file/directory from a search hadle.
160 * PARAMS
161 * hand [in] Search handle from a pervious call to _findfirst
163 * ft [out] A pointer to a find_t structure to populate.
165 * RETURNS
166 * Success: 0. Populates the members of ft with the details
167 * of the first matching file
169 * Failure: -1
171 INT __cdecl CRTDLL__findnext(DWORD hand, find_t * ft)
173 WIN32_FIND_DATAA find_data;
175 if (!FindNextFileA(hand, &find_data))
177 SetLastError(ERROR_INVALID_DRIVE);
178 __CRTDLL__set_errno(GetLastError());
179 return -1;
182 __CRTDLL__fttofd(&find_data,ft);
183 return 0;
187 /*********************************************************************
188 * _getcwd (CRTDLL.120)
190 * Get the current directory.
192 * PARAMS
193 * buf [out] A buffer to place the current directory name in
195 * size [in] The size of buf.
197 * RETURNS
198 * Success: buf, or if buf is NULL, an allocated buffer
200 * Failure: NULL
202 CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT size)
204 char dir[_MAX_PATH];
205 int dir_len = GetCurrentDirectoryA(_MAX_PATH,dir);
207 if (dir_len < 1)
208 return NULL; /* FIXME: Real return value untested */
210 if (!buf)
212 if (size < 0)
213 return CRTDLL__strdup(dir);
214 return __CRTDLL__strndup(dir,size);
216 if (dir_len >= size)
218 CRTDLL_errno = ERANGE;
219 return NULL; /* buf too small */
221 strcpy(buf,dir);
222 return buf;
226 /*********************************************************************
227 * _getdcwd (CRTDLL.121)
229 * Get the current directory on a drive. A: =1, B: =2, etc.
230 * Passing drive 0 means the current drive.
232 CHAR* __cdecl CRTDLL__getdcwd(INT drive,LPSTR buf, INT size)
234 static CHAR* dummy;
236 if (!drive || --drive == DRIVE_GetCurrentDrive())
237 return CRTDLL__getcwd(buf,size); /* current */
238 else
240 char dir[_MAX_PATH];
241 char drivespec[4] = {'A', ':', '\\', 0};
242 int dir_len;
244 drivespec[0] += drive;
245 if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
247 CRTDLL_errno = EACCES;
248 return NULL;
251 dir_len = GetFullPathNameA(drivespec,_MAX_PATH,dir,&dummy);
252 if (dir_len >= size || dir_len < 1)
254 CRTDLL_errno = ERANGE;
255 return NULL; /* buf too small */
258 if (!buf)
259 return CRTDLL__strdup(dir); /* allocate */
261 strcpy(buf,dir);
263 return buf;
267 /*********************************************************************
268 * _getdiskfree (CRTDLL.122)
270 * Get free disk space on given drive or the current drive.
273 UINT __cdecl CRTDLL__getdiskfree(UINT disk, diskfree_t* d)
275 char drivespec[4] = {'@', ':', '\\', 0};
276 DWORD ret[4];
277 UINT err;
279 if (disk > 26)
280 return ERROR_INVALID_PARAMETER; /* CRTDLL doesn't set errno here */
282 drivespec[0] += disk; /* make a drive letter */
284 if (GetDiskFreeSpaceA(disk==0?NULL:drivespec,ret,ret+1,ret+2,ret+3))
286 d->cluster_sectors = (unsigned)ret[0];
287 d->sector_bytes = (unsigned)ret[1];
288 d->available = (unsigned)ret[2];
289 d->num_clusters = (unsigned)ret[3];
290 return 0;
292 err = GetLastError();
293 __CRTDLL__set_errno(err);
294 return err;
298 /*********************************************************************
299 * _getdrive (CRTDLL.124)
301 * Return current drive, A: =1, B: =2, etc
303 INT __cdecl CRTDLL__getdrive(VOID)
305 return DRIVE_GetCurrentDrive() + 1;
309 /*********************************************************************
310 * _mkdir (CRTDLL.234)
312 * Create a directory.
314 INT __cdecl CRTDLL__mkdir(LPCSTR newdir)
316 if (CreateDirectoryA(newdir,NULL))
317 return 0;
319 __CRTDLL__set_errno(GetLastError());
320 return -1;
323 /*********************************************************************
324 * _rmdir (CRTDLL.255)
326 * Delete a directory
329 INT __cdecl CRTDLL__rmdir(LPSTR dir)
331 if (RemoveDirectoryA(dir))
332 return 0;
334 __CRTDLL__set_errno(GetLastError());
335 return -1;