source: trunk/src/crtdll/dir.c@ 4671

Last change on this file since 4671 was 4671, checked in by phaller, 25 years ago

.

File size: 7.7 KB
Line 
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
8 *
9 *
10 * Implementation Notes:
11 * MT Safe.
12 */
13
14#include "crtdll.h"
15#include <errno.h>
16
17#include "ntddk.h"
18#include <time.h>
19
20#include <string.h>
21
22DEFAULT_DEBUG_CHANNEL(crtdll);
23
24/* INTERNAL: Translate find_t to PWIN32_FIND_DATAA */
25static void __CRTDLL__fttofd(LPWIN32_FIND_DATAA fd, find_t* ft);
26static void __CRTDLL__fttofd(LPWIN32_FIND_DATAA fd, find_t* ft)
27{
28 DWORD dw;
29
30 /* Tested with crtdll.dll Version 2.50.4170 (NT) from win98 SE:
31 * attrib 0x80 (FILE_ATTRIBUTE_NORMAL)is returned as 0.
32 */
33 if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
34 ft->attrib = 0;
35 else
36 ft->attrib = fd->dwFileAttributes;
37
38 RtlTimeToSecondsSince1970( &fd->ftCreationTime, &dw );
39 ft->time_create = dw;
40 RtlTimeToSecondsSince1970( &fd->ftLastAccessTime, &dw );
41 ft->time_access = dw;
42 RtlTimeToSecondsSince1970( &fd->ftLastWriteTime, &dw );
43 ft->time_write = dw;
44 ft->size = fd->nFileSizeLow;
45 strcpy(ft->name, fd->cFileName);
46}
47
48
49/*********************************************************************
50 * _chdir (CRTDLL.51)
51 *
52 * Change the current directory.
53 *
54 * PARAMS
55 * newdir [in] Directory to change to
56 *
57 * RETURNS
58 * Sucess: 0
59 *
60 * Failure: -1
61 */
62INT __cdecl CRTDLL__chdir(LPCSTR newdir)
63{
64 if (!SetCurrentDirectoryA(newdir))
65 {
66 __CRTDLL__set_errno(newdir?GetLastError():0);
67 return -1;
68 }
69 return 0;
70}
71
72
73/*********************************************************************
74 * _chdrive (CRTDLL.52)
75 *
76 * Change the current drive.
77 *
78 * PARAMS
79 * newdrive [in] new drive to change to, A: =1, B: =2, etc
80 *
81 * RETURNS
82 * Sucess: 0
83 *
84 * Failure: 1
85 */
86BOOL __cdecl CRTDLL__chdrive(INT newdrive)
87{
88 char buffer[3] = "A:";
89 buffer[0] += newdrive - 1;
90 if (!SetCurrentDirectoryA( buffer ))
91 {
92 __CRTDLL__set_errno(GetLastError());
93 if (newdrive <= 0)
94 CRTDLL_errno = EACCES;
95 return -1;
96 }
97 return 0;
98}
99
100
101/*********************************************************************
102 * _findclose (CRTDLL.098)
103 *
104 * Free the resources from a search handle created from _findfirst.
105 *
106 * PARAMS
107 * hand [in]: Search handle to close
108 *
109 * RETURNS
110 * Success: 0
111 *
112 * Failure: -1
113 */
114INT __cdecl CRTDLL__findclose(DWORD hand)
115{
116 TRACE(":handle %ld\n",hand);
117 if (!FindClose((HANDLE)hand))
118 {
119 __CRTDLL__set_errno(GetLastError());
120 return -1;
121 }
122 return 0;
123}
124
125
126 /*********************************************************************
127 * _findfirst (CRTDLL.099)
128 *
129 * Create and return a search handle for iterating through a file and
130 * directory list.
131 *
132 * PARAMS
133 * fspec [in] File specification string for search, e.g "C:\*.BAT"
134 *
135 * ft [out] A pointer to a find_t structure to populate.
136 *
137 * RETURNS
138 * Success: A handle for the search, suitable for passing to _findnext
139 * or _findclose. Populates the members of ft with the details
140 * of the first matching file.
141 *
142 * Failure: -1.
143 */
144DWORD __cdecl CRTDLL__findfirst(LPCSTR fspec, find_t* ft)
145{
146 WIN32_FIND_DATAA find_data;
147 HANDLE hfind;
148
149 hfind = FindFirstFileA(fspec, &find_data);
150 if (hfind == INVALID_HANDLE_VALUE)
151 {
152 __CRTDLL__set_errno(GetLastError());
153 return -1;
154 }
155 __CRTDLL__fttofd(&find_data,ft);
156 TRACE(":got handle %d\n",hfind);
157 return hfind;
158}
159
160
161/*********************************************************************
162 * _findnext (CRTDLL.100)
163 *
164 * Return the next matching file/directory from a search hadle.
165 *
166 * PARAMS
167 * hand [in] Search handle from a pervious call to _findfirst
168 *
169 * ft [out] A pointer to a find_t structure to populate.
170 *
171 * RETURNS
172 * Success: 0. Populates the members of ft with the details
173 * of the first matching file
174 *
175 * Failure: -1
176 */
177INT __cdecl CRTDLL__findnext(DWORD hand, find_t * ft)
178{
179 WIN32_FIND_DATAA find_data;
180
181 if (!FindNextFileA(hand, &find_data))
182 {
183 SetLastError(ERROR_INVALID_DRIVE);
184 __CRTDLL__set_errno(GetLastError());
185 return -1;
186 }
187
188 __CRTDLL__fttofd(&find_data,ft);
189 return 0;
190}
191
192
193/*********************************************************************
194 * _getcwd (CRTDLL.120)
195 *
196 * Get the current directory.
197 *
198 * PARAMS
199 * buf [out] A buffer to place the current directory name in
200 *
201 * size [in] The size of buf.
202 *
203 * RETURNS
204 * Success: buf, or if buf is NULL, an allocated buffer
205 *
206 * Failure: NULL
207 */
208CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT size)
209{
210 // return (_getcwd(buf, size));
211
212 char dir[_MAX_PATH];
213 int dir_len = GetCurrentDirectoryA(_MAX_PATH,dir);
214
215 if (dir_len < 1)
216 return NULL; /* FIXME: Real return value untested */
217
218 if (!buf)
219 {
220 if (size < 0)
221 return CRTDLL__strdup(dir);
222 return __CRTDLL__strndup(dir,size);
223 }
224 if (dir_len >= size)
225 {
226 CRTDLL_errno = ERANGE;
227 return NULL; /* buf too small */
228 }
229 strcpy(buf,dir);
230 return buf;
231}
232
233
234/*********************************************************************
235 * _getdcwd (CRTDLL.121)
236 *
237 * Get the current directory on a drive. A: =1, B: =2, etc.
238 * Passing drive 0 means the current drive.
239 */
240CHAR* __cdecl CRTDLL__getdcwd(INT drive,LPSTR buf, INT size)
241{
242 // return (_getdcwd(drive, buffer, maxlen));
243
244 static CHAR* dummy;
245
246 if (!drive || drive == CRTDLL__getdrive())
247 return CRTDLL__getcwd(buf,size); /* current */
248 else
249 {
250 char dir[_MAX_PATH];
251 char drivespec[4] = {'A', ':', '\\', 0};
252 int dir_len;
253
254 drivespec[0] += drive - 1;
255 if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
256 {
257 CRTDLL_errno = EACCES;
258 return NULL;
259 }
260
261 dir_len = GetFullPathNameA(drivespec,_MAX_PATH,dir,&dummy);
262 if (dir_len >= size || dir_len < 1)
263 {
264 CRTDLL_errno = ERANGE;
265 return NULL; /* buf too small */
266 }
267
268 if (!buf)
269 return CRTDLL__strdup(dir); /* allocate */
270
271 strcpy(buf,dir);
272 }
273 return buf;
274}
275
276
277/*********************************************************************
278 * _getdiskfree (CRTDLL.122)
279 *
280 * Get free disk space on given drive or the current drive.
281 *
282 */
283UINT __cdecl CRTDLL__getdiskfree(UINT disk, diskfree_t* d)
284{
285 char drivespec[4] = {'@', ':', '\\', 0};
286 DWORD ret[4];
287 UINT err;
288
289 if (disk > 26)
290 return ERROR_INVALID_PARAMETER; /* CRTDLL doesn't set errno here */
291
292 drivespec[0] += disk; /* make a drive letter */
293
294 if (GetDiskFreeSpaceA(disk==0?NULL:drivespec,ret,ret+1,ret+2,ret+3))
295 {
296 d->cluster_sectors = (unsigned)ret[0];
297 d->sector_bytes = (unsigned)ret[1];
298 d->available = (unsigned)ret[2];
299 d->num_clusters = (unsigned)ret[3];
300 return 0;
301 }
302 err = GetLastError();
303 __CRTDLL__set_errno(err);
304 return err;
305}
306
307
308/*********************************************************************
309 * _getdrive (CRTDLL.124)
310 *
311 * Return current drive, A: =1, B: =2, etc
312 */
313INT __cdecl CRTDLL__getdrive(VOID)
314{
315 // return DRIVE_GetCurrentDrive() + 1;
316
317 char buffer[MAX_PATH];
318 if (!GetCurrentDirectoryA( sizeof(buffer), buffer )) return 0;
319 if (buffer[1] != ':') return 0;
320 return toupper(buffer[0]) - 'A' + 1;
321}
322
323
324/*********************************************************************
325 * _mkdir (CRTDLL.234)
326 *
327 * Create a directory.
328 */
329INT __cdecl CRTDLL__mkdir(LPCSTR newdir)
330{
331 if (CreateDirectoryA(newdir,NULL))
332 return 0;
333
334 __CRTDLL__set_errno(GetLastError());
335 return -1;
336}
337
338/*********************************************************************
339 * _rmdir (CRTDLL.255)
340 *
341 * Delete a directory
342 *
343 */
344INT __cdecl CRTDLL__rmdir(LPSTR dir)
345{
346 if (RemoveDirectoryA(dir))
347 return 0;
348
349 __CRTDLL__set_errno(GetLastError());
350 return -1;
351}
Note: See TracBrowser for help on using the repository browser.