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

Last change on this file since 8266 was 7521, checked in by bird, 24 years ago

include ctype.h to get the toupper() proto.

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