2 * CRTDLL drive/directory functions
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:
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
)
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
)
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 /*********************************************************************
48 * Change the current directory.
51 * newdir [in] Directory to change to
58 INT __cdecl
CRTDLL__chdir(LPCSTR newdir
)
60 if (!SetCurrentDirectoryA(newdir
))
62 __CRTDLL__set_errno(newdir
?GetLastError():0);
69 /*********************************************************************
70 * _chdrive (CRTDLL.52)
72 * Change the current drive.
75 * newdrive [in] new drive to change to, A: =1, B: =2, etc
82 BOOL __cdecl
CRTDLL__chdrive(INT newdrive
)
84 if (!DRIVE_SetCurrentDrive(newdrive
-1))
86 __CRTDLL__set_errno(GetLastError());
88 CRTDLL_errno
= EACCES
;
95 /*********************************************************************
96 * _findclose (CRTDLL.098)
98 * Free the resources from a search handle created from _findfirst.
101 * hand [in]: Search handle to close
108 INT __cdecl
CRTDLL__findclose(DWORD hand
)
110 TRACE(":handle %ld\n",hand
);
111 if (!FindClose((HANDLE
)hand
))
113 __CRTDLL__set_errno(GetLastError());
120 /*********************************************************************
121 * _findfirst (CRTDLL.099)
123 * Create and return a search handle for iterating through a file and
127 * fspec [in] File specification string for search, e.g "C:\*.BAT"
129 * ft [out] A pointer to a find_t structure to populate.
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.
138 DWORD __cdecl
CRTDLL__findfirst(LPCSTR fspec
, find_t
* ft
)
140 WIN32_FIND_DATAA find_data
;
143 hfind
= FindFirstFileA(fspec
, &find_data
);
144 if (hfind
== INVALID_HANDLE_VALUE
)
146 __CRTDLL__set_errno(GetLastError());
149 __CRTDLL__fttofd(&find_data
,ft
);
150 TRACE(":got handle %d\n",hfind
);
155 /*********************************************************************
156 * _findnext (CRTDLL.100)
158 * Return the next matching file/directory from a search hadle.
161 * hand [in] Search handle from a pervious call to _findfirst
163 * ft [out] A pointer to a find_t structure to populate.
166 * Success: 0. Populates the members of ft with the details
167 * of the first matching file
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());
182 __CRTDLL__fttofd(&find_data
,ft
);
187 /*********************************************************************
188 * _getcwd (CRTDLL.120)
190 * Get the current directory.
193 * buf [out] A buffer to place the current directory name in
195 * size [in] The size of buf.
198 * Success: buf, or if buf is NULL, an allocated buffer
202 CHAR
* __cdecl
CRTDLL__getcwd(LPSTR buf
, INT size
)
205 int dir_len
= GetCurrentDirectoryA(_MAX_PATH
,dir
);
208 return NULL
; /* FIXME: Real return value untested */
213 return CRTDLL__strdup(dir
);
214 return __CRTDLL__strndup(dir
,size
);
218 CRTDLL_errno
= ERANGE
;
219 return NULL
; /* buf too small */
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
)
236 if (!drive
|| --drive
== DRIVE_GetCurrentDrive())
237 return CRTDLL__getcwd(buf
,size
); /* current */
241 char drivespec
[4] = {'A', ':', '\\', 0};
244 drivespec
[0] += drive
;
245 if (GetDriveTypeA(drivespec
) < DRIVE_REMOVABLE
)
247 CRTDLL_errno
= EACCES
;
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 */
259 return CRTDLL__strdup(dir
); /* allocate */
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};
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];
292 err
= GetLastError();
293 __CRTDLL__set_errno(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
))
319 __CRTDLL__set_errno(GetLastError());
323 /*********************************************************************
324 * _rmdir (CRTDLL.255)
329 INT __cdecl
CRTDLL__rmdir(LPSTR dir
)
331 if (RemoveDirectoryA(dir
))
334 __CRTDLL__set_errno(GetLastError());