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

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

.

File size: 8.3 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 dprintf(("CRTDLL: _chdir(%s)\n",
65 newdir));
66
67 if (!SetCurrentDirectoryA(newdir))
68 {
69 __CRTDLL__set_errno(newdir?GetLastError():0);
70 return -1;
71 }
72 return 0;
73}
74
75
76/*********************************************************************
77 * _chdrive (CRTDLL.52)
78 *
79 * Change the current drive.
80 *
81 * PARAMS
82 * newdrive [in] new drive to change to, A: =1, B: =2, etc
83 *
84 * RETURNS
85 * Sucess: 0
86 *
87 * Failure: 1
88 */
89BOOL CDECL CRTDLL__chdrive(INT newdrive)
90{
91 char buffer[3] = "A:";
92 buffer[0] += newdrive - 1;
93
94 dprintf(("CRTDLL: _chdrive(%s)\n",
95 buffer));
96
97 if (!SetCurrentDirectoryA( buffer ))
98 {
99 __CRTDLL__set_errno(GetLastError());
100 if (newdrive <= 0)
101 CRTDLL_errno = EACCES;
102 return -1;
103 }
104 return 0;
105}
106
107
108/*********************************************************************
109 * _findclose (CRTDLL.098)
110 *
111 * Free the resources from a search handle created from _findfirst.
112 *
113 * PARAMS
114 * hand [in]: Search handle to close
115 *
116 * RETURNS
117 * Success: 0
118 *
119 * Failure: -1
120 */
121INT CDECL CRTDLL__findclose(DWORD hand)
122{
123 dprintf(("CRTDLL: _findclose(%08xh)\n",
124 hand));
125
126 if (!FindClose((HANDLE)hand))
127 {
128 __CRTDLL__set_errno(GetLastError());
129 return -1;
130 }
131 return 0;
132}
133
134
135 /*********************************************************************
136 * _findfirst (CRTDLL.099)
137 *
138 * Create and return a search handle for iterating through a file and
139 * directory list.
140 *
141 * PARAMS
142 * fspec [in] File specification string for search, e.g "C:\*.BAT"
143 *
144 * ft [out] A pointer to a find_t structure to populate.
145 *
146 * RETURNS
147 * Success: A handle for the search, suitable for passing to _findnext
148 * or _findclose. Populates the members of ft with the details
149 * of the first matching file.
150 *
151 * Failure: -1.
152 */
153DWORD CDECL CRTDLL__findfirst(LPCSTR fspec, find_t* ft)
154{
155 WIN32_FIND_DATAA find_data;
156 HANDLE hfind;
157
158 dprintf(("CRTDLL: _findfirst(%s)\n",
159 fspec));
160
161 hfind = FindFirstFileA(fspec, &find_data);
162 if (hfind == INVALID_HANDLE_VALUE)
163 {
164 __CRTDLL__set_errno(GetLastError());
165 return -1;
166 }
167 __CRTDLL__fttofd(&find_data,ft);
168 TRACE(":got handle %d\n",hfind);
169 return hfind;
170}
171
172
173/*********************************************************************
174 * _findnext (CRTDLL.100)
175 *
176 * Return the next matching file/directory from a search hadle.
177 *
178 * PARAMS
179 * hand [in] Search handle from a pervious call to _findfirst
180 *
181 * ft [out] A pointer to a find_t structure to populate.
182 *
183 * RETURNS
184 * Success: 0. Populates the members of ft with the details
185 * of the first matching file
186 *
187 * Failure: -1
188 */
189INT CDECL CRTDLL__findnext(DWORD hand, find_t * ft)
190{
191 WIN32_FIND_DATAA find_data;
192
193 dprintf(("CRTDLL: _findnext(%08xh)\n",
194 hand));
195
196 if (!FindNextFileA(hand, &find_data))
197 {
198 SetLastError(ERROR_INVALID_DRIVE);
199 __CRTDLL__set_errno(GetLastError());
200 return -1;
201 }
202
203 __CRTDLL__fttofd(&find_data,ft);
204 return 0;
205}
206
207
208/*********************************************************************
209 * _getcwd (CRTDLL.120)
210 *
211 * Get the current directory.
212 *
213 * PARAMS
214 * buf [out] A buffer to place the current directory name in
215 *
216 * size [in] The size of buf.
217 *
218 * RETURNS
219 * Success: buf, or if buf is NULL, an allocated buffer
220 *
221 * Failure: NULL
222 */
223CHAR* CDECL CRTDLL__getcwd(LPSTR buf, INT size)
224{
225 // return (_getcwd(buf, size));
226
227 char dir[_MAX_PATH];
228 int dir_len = GetCurrentDirectoryA(_MAX_PATH,dir);
229
230 dprintf(("CRTDLL: _getcwd()\n"));
231
232 if (dir_len < 1)
233 return NULL; /* FIXME: Real return value untested */
234
235 if (!buf)
236 {
237 if (size < 0)
238 return CRTDLL__strdup(dir);
239 return __CRTDLL__strndup(dir,size);
240 }
241 if (dir_len >= size)
242 {
243 CRTDLL_errno = ERANGE;
244 return NULL; /* buf too small */
245 }
246 strcpy(buf,dir);
247 return buf;
248}
249
250
251/*********************************************************************
252 * _getdcwd (CRTDLL.121)
253 *
254 * Get the current directory on a drive. A: =1, B: =2, etc.
255 * Passing drive 0 means the current drive.
256 */
257CHAR* CDECL CRTDLL__getdcwd(INT drive,LPSTR buf, INT size)
258{
259 // return (_getdcwd(drive, buffer, maxlen));
260
261 static CHAR* dummy;
262
263 dprintf(("CRTDLL: _getdcwd()\n"));
264
265 if (!drive || drive == CRTDLL__getdrive())
266 return CRTDLL__getcwd(buf,size); /* current */
267 else
268 {
269 char dir[_MAX_PATH];
270 char drivespec[4] = {'A', ':', '\\', 0};
271 int dir_len;
272
273 drivespec[0] += drive - 1;
274 if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
275 {
276 CRTDLL_errno = EACCES;
277 return NULL;
278 }
279
280 dir_len = GetFullPathNameA(drivespec,_MAX_PATH,dir,&dummy);
281 if (dir_len >= size || dir_len < 1)
282 {
283 CRTDLL_errno = ERANGE;
284 return NULL; /* buf too small */
285 }
286
287 if (!buf)
288 return CRTDLL__strdup(dir); /* allocate */
289
290 strcpy(buf,dir);
291 }
292 return buf;
293}
294
295
296/*********************************************************************
297 * _getdiskfree (CRTDLL.122)
298 *
299 * Get free disk space on given drive or the current drive.
300 *
301 */
302UINT CDECL CRTDLL__getdiskfree(UINT disk, diskfree_t* d)
303{
304 char drivespec[4] = {'@', ':', '\\', 0};
305 DWORD ret[4];
306 UINT err;
307
308 dprintf(("CRTDLL: _getdiskfree(%08xh)\n", disk));
309
310 if (disk > 26)
311 return ERROR_INVALID_PARAMETER; /* CRTDLL doesn't set errno here */
312
313 drivespec[0] += disk; /* make a drive letter */
314
315 if (GetDiskFreeSpaceA(disk==0?NULL:drivespec,ret,ret+1,ret+2,ret+3))
316 {
317 d->cluster_sectors = (unsigned)ret[0];
318 d->sector_bytes = (unsigned)ret[1];
319 d->available = (unsigned)ret[2];
320 d->num_clusters = (unsigned)ret[3];
321 return 0;
322 }
323 err = GetLastError();
324 __CRTDLL__set_errno(err);
325 return err;
326}
327
328
329/*********************************************************************
330 * _getdrive (CRTDLL.124)
331 *
332 * Return current drive, A: =1, B: =2, etc
333 */
334INT CDECL CRTDLL__getdrive(VOID)
335{
336 // return DRIVE_GetCurrentDrive() + 1;
337
338 char buffer[MAX_PATH];
339
340 dprintf(("CRTDLL: _getdrive()\n"));
341
342 if (!GetCurrentDirectoryA( sizeof(buffer), buffer ))
343 return 0;
344 if (buffer[1] != ':')
345 return 0;
346 return toupper(buffer[0]) - 'A' + 1;
347}
348
349
350/*********************************************************************
351 * _mkdir (CRTDLL.234)
352 *
353 * Create a directory.
354 */
355INT CDECL CRTDLL__mkdir(LPCSTR newdir)
356{
357 dprintf(("CRTDLL: _mkdir(%s)\n",
358 newdir));
359
360 if (CreateDirectoryA(newdir,NULL))
361 return 0;
362
363 __CRTDLL__set_errno(GetLastError());
364 return -1;
365}
366
367/*********************************************************************
368 * _rmdir (CRTDLL.255)
369 *
370 * Delete a directory
371 *
372 */
373INT CDECL CRTDLL__rmdir(LPSTR dir)
374{
375 dprintf(("CRTDLL: _rmdir(%s)\n",
376 dir));
377
378 if (RemoveDirectoryA(dir))
379 return 0;
380
381 __CRTDLL__set_errno(GetLastError());
382 return -1;
383}
Note: See TracBrowser for help on using the repository browser.