source: trunk/src/msvcrt/dir.c@ 21411

Last change on this file since 21411 was 21398, checked in by dmik, 15 years ago

Build minivcrt.lib (accessible through minivcrt.h) that aims at providing MSVCRT-specific functions such as the wide character version of _getcwd() and similar to other runtimes.

File size: 19.7 KB
Line 
1/*
2 * msvcrt.dll 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 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23#ifdef __WIN32OS2__
24#include <emxheader.h>
25#include <stdlib.h>
26#include <string.h>
27#include <ctype.h>
28#include <winbase.h>
29#else
30#include "config.h"
31#endif
32
33#ifndef __MINIVCRT__
34
35#include "wine/port.h"
36
37#include <time.h>
38#include "winternl.h"
39#include "wine/unicode.h"
40#include "msvcrt.h"
41#include "msvcrt/errno.h"
42
43#include "wine/unicode.h"
44#include "msvcrt/direct.h"
45#include "msvcrt/dos.h"
46#include "msvcrt/io.h"
47#include "msvcrt/stdlib.h"
48#include "msvcrt/string.h"
49
50#include "wine/debug.h"
51
52WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
53
54#else /* !__MINIVCRT__ */
55
56#include "minivcrt.h"
57#include "minivcrt_internal.h"
58
59#include "winternl.h"
60#include "wine/unicode.h"
61
62#include <errno.h>
63#include <stdlib.h>
64
65#endif /* !__MINIVCRT__ */
66
67#ifndef __MINIVCRT__
68
69/* INTERNAL: Translate finddata_t to PWIN32_FIND_DATAA */
70static void msvcrt_fttofd(LPWIN32_FIND_DATAA fd, struct _finddata_t* ft)
71{
72 DWORD dw;
73
74 if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
75 ft->attrib = 0;
76 else
77 ft->attrib = fd->dwFileAttributes;
78
79 RtlTimeToSecondsSince1970( (LARGE_INTEGER *)&fd->ftCreationTime, &dw );
80 ft->time_create = dw;
81 RtlTimeToSecondsSince1970( (LARGE_INTEGER *)&fd->ftLastAccessTime, &dw );
82 ft->time_access = dw;
83 RtlTimeToSecondsSince1970( (LARGE_INTEGER *)&fd->ftLastWriteTime, &dw );
84 ft->time_write = dw;
85 ft->size = fd->nFileSizeLow;
86 strcpy(ft->name, fd->cFileName);
87}
88
89#endif /* !__MINIVCRT__ */
90
91/* INTERNAL: Translate wfinddata_t to PWIN32_FIND_DATAA */
92static void msvcrt_wfttofd(LPWIN32_FIND_DATAW fd, struct _wfinddata_t* ft)
93{
94 DWORD dw;
95
96 if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
97 ft->attrib = 0;
98 else
99 ft->attrib = fd->dwFileAttributes;
100
101 RtlTimeToSecondsSince1970( (LARGE_INTEGER *)&fd->ftCreationTime, &dw );
102 ft->time_create = dw;
103 RtlTimeToSecondsSince1970( (LARGE_INTEGER *)&fd->ftLastAccessTime, &dw );
104 ft->time_access = dw;
105 RtlTimeToSecondsSince1970( (LARGE_INTEGER *)&fd->ftLastWriteTime, &dw );
106 ft->time_write = dw;
107 ft->size = fd->nFileSizeLow;
108 strcpyW(ft->name, fd->cFileName);
109}
110
111#ifndef __MINIVCRT__
112
113/*********************************************************************
114 * _chdir (MSVCRT.@)
115 */
116int MSVCRT__chdir(const char * newdir)
117{
118 if (!SetCurrentDirectoryA(newdir))
119 {
120 MSVCRT__set_errno(newdir?GetLastError():0);
121 return -1;
122 }
123 return 0;
124}
125
126#endif /* !__MINIVCRT__ */
127
128/*********************************************************************
129 * _wchdir (MSVCRT.@)
130 */
131int _wchdir(const MSVCRT_wchar_t * newdir)
132{
133 if (!SetCurrentDirectoryW(newdir))
134 {
135 MSVCRT__set_errno(newdir?GetLastError():0);
136 return -1;
137 }
138 return 0;
139}
140
141#ifndef __MINIVCRT__
142
143/*********************************************************************
144 * _chdrive (MSVCRT.@)
145 */
146int MSVCRT__chdrive(int newdrive)
147{
148 char buffer[3] = "A:";
149 buffer[0] += newdrive - 1;
150 if (!SetCurrentDirectoryA( buffer ))
151 {
152 MSVCRT__set_errno(GetLastError());
153 if (newdrive <= 0)
154 *MSVCRT__errno() = MSVCRT_EACCES;
155 return -1;
156 }
157 return 0;
158}
159
160/*********************************************************************
161 * _findclose (MSVCRT.@)
162 */
163int _findclose(long hand)
164{
165 TRACE(":handle %ld\n",hand);
166 if (!FindClose((HANDLE)hand))
167 {
168 MSVCRT__set_errno(GetLastError());
169 return -1;
170 }
171 return 0;
172}
173
174/*********************************************************************
175 * _findfirst (MSVCRT.@)
176 */
177long _findfirst(const char * fspec, struct _finddata_t* ft)
178{
179 WIN32_FIND_DATAA find_data;
180 HANDLE hfind;
181
182 hfind = FindFirstFileA(fspec, &find_data);
183 if (hfind == INVALID_HANDLE_VALUE)
184 {
185 MSVCRT__set_errno(GetLastError());
186 return -1;
187 }
188 msvcrt_fttofd(&find_data,ft);
189 TRACE(":got handle %p\n",hfind);
190 return (long)hfind;
191}
192
193#endif /* !__MINIVCRT__ */
194
195/*********************************************************************
196 * _wfindfirst (MSVCRT.@)
197 */
198long _wfindfirst(const MSVCRT_wchar_t * fspec, struct _wfinddata_t* ft)
199{
200 WIN32_FIND_DATAW find_data;
201 HANDLE hfind;
202
203 hfind = FindFirstFileW(fspec, &find_data);
204 if (hfind == INVALID_HANDLE_VALUE)
205 {
206 MSVCRT__set_errno(GetLastError());
207 return -1;
208 }
209 msvcrt_wfttofd(&find_data,ft);
210 TRACE(":got handle %p\n",hfind);
211 return (long)hfind;
212}
213
214#ifndef __MINIVCRT__
215
216/*********************************************************************
217 * _findnext (MSVCRT.@)
218 */
219int _findnext(long hand, struct _finddata_t * ft)
220{
221 WIN32_FIND_DATAA find_data;
222
223 if (!FindNextFileA((HANDLE)hand, &find_data))
224 {
225 *MSVCRT__errno() = MSVCRT(ENOENT);
226 return -1;
227 }
228
229 msvcrt_fttofd(&find_data,ft);
230 return 0;
231}
232
233#endif /* !__MINIVCRT__ */
234
235/*********************************************************************
236 * _wfindnext (MSVCRT.@)
237 */
238int _wfindnext(long hand, struct _wfinddata_t * ft)
239{
240 WIN32_FIND_DATAW find_data;
241
242 if (!FindNextFileW((HANDLE)hand, &find_data))
243 {
244 *MSVCRT__errno() = MSVCRT(ENOENT);
245 return -1;
246 }
247
248 msvcrt_wfttofd(&find_data,ft);
249 return 0;
250}
251
252#ifndef __MINIVCRT__
253
254/*********************************************************************
255 * _getcwd (MSVCRT.@)
256 */
257char* MSVCRT__getcwd(char * buf, int size)
258{
259 char dir[MAX_PATH];
260 int dir_len = GetCurrentDirectoryA(MAX_PATH,dir);
261
262 if (dir_len < 1)
263 return NULL; /* FIXME: Real return value untested */
264
265 if (!buf)
266 {
267 if (size < 0)
268 return MSVCRT__strdup(dir);
269 return msvcrt_strndup(dir,size);
270 }
271 if (dir_len >= size)
272 {
273 *MSVCRT__errno() = MSVCRT_ERANGE;
274 return NULL; /* buf too small */
275 }
276 strcpy(buf,dir);
277 return buf;
278}
279
280#endif /* !__MINIVCRT__ */
281
282/*********************************************************************
283 * _wgetcwd (MSVCRT.@)
284 */
285MSVCRT_wchar_t* _wgetcwd(MSVCRT_wchar_t * buf, int size)
286{
287 MSVCRT_wchar_t dir[MAX_PATH];
288 int dir_len = GetCurrentDirectoryW(MAX_PATH,dir);
289
290 if (dir_len < 1)
291 return NULL; /* FIXME: Real return value untested */
292
293 if (!buf)
294 {
295 if (size < 0)
296 return _wcsdup(dir);
297 return msvcrt_wstrndup(dir,size);
298 }
299 if (dir_len >= size)
300 {
301 *MSVCRT__errno() = MSVCRT(ERANGE);
302 return NULL; /* buf too small */
303 }
304 strcpyW(buf,dir);
305 return buf;
306}
307
308#ifndef __MINIVCRT__
309
310/*********************************************************************
311 * _getdrive (MSVCRT.@)
312 */
313int MSVCRT__getdrive(void)
314{
315 char buffer[MAX_PATH];
316 if (!GetCurrentDirectoryA( sizeof(buffer), buffer )) return 0;
317 if (buffer[1] != ':') return 0;
318 return toupper(buffer[0]) - 'A' + 1;
319}
320
321/*********************************************************************
322 * _getdcwd (MSVCRT.@)
323 */
324char* MSVCRT__getdcwd(int drive, char * buf, int size)
325{
326 static char* dummy;
327
328 TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
329
330 if (!drive || drive == MSVCRT__getdrive())
331 return MSVCRT__getcwd(buf,size); /* current */
332 else
333 {
334 char dir[MAX_PATH];
335 char drivespec[4] = {'A', ':', '\\', 0};
336 int dir_len;
337
338 drivespec[0] += drive - 1;
339 if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
340 {
341 *MSVCRT__errno() = MSVCRT_EACCES;
342 return NULL;
343 }
344
345 dir_len = GetFullPathNameA(drivespec,MAX_PATH,dir,&dummy);
346 if (dir_len >= size || dir_len < 1)
347 {
348 *MSVCRT__errno() = MSVCRT_ERANGE;
349 return NULL; /* buf too small */
350 }
351
352 TRACE(":returning '%s'\n", dir);
353 if (!buf)
354 return MSVCRT__strdup(dir); /* allocate */
355
356 strcpy(buf,dir);
357 }
358 return buf;
359}
360
361#endif /* !__MINIVCRT__ */
362
363/*********************************************************************
364 * _wgetdcwd (MSVCRT.@)
365 */
366MSVCRT_wchar_t* _wgetdcwd(int drive, MSVCRT_wchar_t * buf, int size)
367{
368 static MSVCRT_wchar_t* dummy;
369
370 TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
371
372 if (!drive || drive == MSVCRT__getdrive())
373 return _wgetcwd(buf,size); /* current */
374 else
375 {
376 MSVCRT_wchar_t dir[MAX_PATH];
377 MSVCRT_wchar_t drivespec[4] = {'A', ':', '\\', 0};
378 int dir_len;
379
380 drivespec[0] += drive - 1;
381 if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE)
382 {
383 *MSVCRT__errno() = MSVCRT(EACCES);
384 return NULL;
385 }
386
387 dir_len = GetFullPathNameW(drivespec,MAX_PATH,dir,&dummy);
388 if (dir_len >= size || dir_len < 1)
389 {
390 *MSVCRT__errno() = MSVCRT(ERANGE);
391 return NULL; /* buf too small */
392 }
393
394 TRACE(":returning %s\n", debugstr_w(dir));
395 if (!buf)
396 return _wcsdup(dir); /* allocate */
397 strcpyW(buf,dir);
398 }
399 return buf;
400}
401
402#ifndef __MINIVCRT__
403
404/*********************************************************************
405 * _getdiskfree (MSVCRT.@)
406 */
407unsigned int _getdiskfree(unsigned int disk, struct _diskfree_t* d)
408{
409 char drivespec[4] = {'@', ':', '\\', 0};
410 DWORD ret[4];
411 unsigned int err;
412
413 if (disk > 26)
414 return ERROR_INVALID_PARAMETER; /* MSVCRT doesn't set errno here */
415
416 drivespec[0] += disk; /* make a drive letter */
417
418 if (GetDiskFreeSpaceA(disk==0?NULL:drivespec,ret,ret+1,ret+2,ret+3))
419 {
420 d->sectors_per_cluster = (unsigned)ret[0];
421 d->bytes_per_sector = (unsigned)ret[1];
422 d->avail_clusters = (unsigned)ret[2];
423 d->total_clusters = (unsigned)ret[3];
424 return 0;
425 }
426 err = GetLastError();
427 MSVCRT__set_errno(err);
428 return err;
429}
430
431/*********************************************************************
432 * _mkdir (MSVCRT.@)
433 */
434int MSVCRT__mkdir(const char * newdir)
435{
436 if (CreateDirectoryA(newdir,NULL))
437 return 0;
438 MSVCRT__set_errno(GetLastError());
439 return -1;
440}
441
442#endif /* !__MINIVCRT__ */
443
444/*********************************************************************
445 * _wmkdir (MSVCRT.@)
446 */
447int _wmkdir(const MSVCRT_wchar_t* newdir)
448{
449 if (CreateDirectoryW(newdir,NULL))
450 return 0;
451 MSVCRT__set_errno(GetLastError());
452 return -1;
453}
454
455#ifndef __MINIVCRT__
456
457/*********************************************************************
458 * _rmdir (MSVCRT.@)
459 */
460int MSVCRT__rmdir(const char * dir)
461{
462 if (RemoveDirectoryA(dir))
463 return 0;
464 MSVCRT__set_errno(GetLastError());
465 return -1;
466}
467
468#endif /* !__MINIVCRT__ */
469
470/*********************************************************************
471 * _wrmdir (MSVCRT.@)
472 */
473int _wrmdir(const MSVCRT_wchar_t * dir)
474{
475 if (RemoveDirectoryW(dir))
476 return 0;
477 MSVCRT__set_errno(GetLastError());
478 return -1;
479}
480
481/*********************************************************************
482 * _wsplitpath (MSVCRT.@)
483 */
484void _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT_wchar_t *dir,
485 MSVCRT_wchar_t *fname, MSVCRT_wchar_t *ext )
486{
487 /* Modified PD code from 'snippets' collection. */
488 MSVCRT_wchar_t ch, *ptr, *p;
489 MSVCRT_wchar_t pathbuff[MAX_PATH],*path=pathbuff;
490
491 TRACE("MSVCRT: _wsplitpath %s\n",debugstr_w(path));
492 /* FIXME: Should be an strncpyW or something */
493 strcpyW(pathbuff, inpath);
494
495 /* convert slashes to backslashes for searching */
496 for (ptr = (MSVCRT_wchar_t*)path; *ptr; ++ptr)
497 if (*ptr == '/')
498 *ptr = '\\';
499
500 /* look for drive spec */
501 if ((ptr = strchrW(path, ':')) != 0)
502 {
503 ++ptr;
504 if (drv)
505 {
506 strncpyW(drv, path, ptr - path);
507 drv[ptr - path] = 0;
508 }
509 path = ptr;
510 }
511 else if (drv)
512 *drv = 0;
513
514 /* find rightmost backslash or leftmost colon */
515 if ((ptr = strrchrW(path, '\\')) == NULL)
516 ptr = (strchrW(path, ':'));
517
518 if (!ptr)
519 {
520 ptr = (MSVCRT_wchar_t *)path; /* no path */
521 if (dir)
522 *dir = 0;
523 }
524 else
525 {
526 ++ptr; /* skip the delimiter */
527 if (dir)
528 {
529 ch = *ptr;
530 *ptr = 0;
531 strcpyW(dir, path);
532 *ptr = ch;
533 }
534 }
535
536 if ((p = strrchrW(ptr, '.')) == NULL)
537 {
538 if (fname)
539 strcpyW(fname, ptr);
540 if (ext)
541 *ext = 0;
542 }
543 else
544 {
545 *p = 0;
546 if (fname)
547 strcpyW(fname, ptr);
548 *p = '.';
549 if (ext)
550 strcpyW(ext, p);
551 }
552
553 /* Fix pathological case - Win returns ':' as part of the
554 * directory when no drive letter is given.
555 */
556 if (drv && drv[0] == ':')
557 {
558 *drv = 0;
559 if (dir)
560 {
561 pathbuff[0] = ':';
562 pathbuff[1] = 0;
563 strcatW(pathbuff,dir);
564 strcpyW(dir, pathbuff);
565 }
566 }
567}
568
569#ifndef __MINIVCRT__
570
571/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
572static void msvcrt_fln_fix(char *path)
573{
574 int dir_flag = 0, root_flag = 0;
575 char *r, *p, *q, *s;
576
577 /* Skip drive */
578 if (NULL == (r = strrchr(path, ':')))
579 r = path;
580 else
581 ++r;
582
583 /* Ignore leading slashes */
584 while ('\\' == *r)
585 if ('\\' == r[1])
586 strcpy(r, &r[1]);
587 else
588 {
589 root_flag = 1;
590 ++r;
591 }
592
593 p = r; /* Change "\\" to "\" */
594 while (NULL != (p = strchr(p, '\\')))
595 if ('\\' == p[1])
596 strcpy(p, &p[1]);
597 else
598 ++p;
599
600 while ('.' == *r) /* Scrunch leading ".\" */
601 {
602 if ('.' == r[1])
603 {
604 /* Ignore leading ".." */
605 for (p = (r += 2); *p && (*p != '\\'); ++p)
606 ;
607 }
608 else
609 {
610 for (p = r + 1 ;*p && (*p != '\\'); ++p)
611 ;
612 }
613 strcpy(r, p + ((*p) ? 1 : 0));
614 }
615
616 while ('\\' == path[strlen(path)-1]) /* Strip last '\\' */
617 {
618 dir_flag = 1;
619 path[strlen(path)-1] = '\0';
620 }
621
622 s = r;
623
624 /* Look for "\." in path */
625
626 while (NULL != (p = strstr(s, "\\.")))
627 {
628 if ('.' == p[2])
629 {
630 /* Execute this section if ".." found */
631 q = p - 1;
632 while (q > r) /* Backup one level */
633 {
634 if (*q == '\\')
635 break;
636 --q;
637 }
638 if (q > r)
639 {
640 strcpy(q, p + 3);
641 s = q;
642 }
643 else if ('.' != *q)
644 {
645 strcpy(q + ((*q == '\\') ? 1 : 0),
646 p + 3 + ((*(p + 3)) ? 1 : 0));
647 s = q;
648 }
649 else s = ++p;
650 }
651 else
652 {
653 /* Execute this section if "." found */
654 q = p + 2;
655 for ( ;*q && (*q != '\\'); ++q)
656 ;
657 strcpy (p, q);
658 }
659 }
660
661 if (root_flag) /* Embedded ".." could have bubbled up to root */
662 {
663 for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
664 ;
665 if (r != p)
666 strcpy(r, p);
667 }
668
669 if (dir_flag)
670 strcat(path, "\\");
671}
672
673/*********************************************************************
674 * _fullpath (MSVCRT.@)
675 */
676char *MSVCRT__fullpath(char * absPath, const char* relPath, unsigned int size)
677{
678 char drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
679 char res[MAX_PATH];
680 size_t len;
681
682 res[0] = '\0';
683
684 if (!relPath || !*relPath)
685 return MSVCRT__getcwd(absPath, size);
686
687 if (size < 4)
688 {
689 *MSVCRT__errno() = MSVCRT_ERANGE;
690 return NULL;
691 }
692
693 TRACE("MSVCRT: _fullpath '%s'\n",relPath);
694
695 _splitpath(relPath, drive, dir, file, ext);
696
697 /* Get Directory and drive into 'res' */
698 if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
699 {
700 /* Relative or no directory given */
701 _getdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 : 0, res, MAX_PATH);
702 strcat(res,"\\");
703 if (dir[0])
704 strcat(res,dir);
705 if (drive[0])
706 res[0] = drive[0]; /* If given a drive, preserve the letter case */
707 }
708 else
709 {
710 strcpy(res,drive);
711 strcat(res,dir);
712 }
713
714 strcat(res,"\\");
715 strcat(res, file);
716 strcat(res, ext);
717 msvcrt_fln_fix(res);
718
719 len = strlen(res);
720 if (len >= MAX_PATH || len >= (size_t)size)
721 return NULL; /* FIXME: errno? */
722
723 if (!absPath)
724 return MSVCRT__strdup(res);
725 strcpy(absPath,res);
726 return absPath;
727}
728
729/*********************************************************************
730 * _makepath (MSVCRT.@)
731 */
732VOID MSVCRT__makepath(char * path, const char * drive,
733 const char *directory, const char * filename,
734 const char * extension )
735{
736 char ch;
737 TRACE("got %s %s %s %s\n", drive, directory,
738 filename, extension);
739
740 if ( !path )
741 return;
742
743 path[0] = 0;
744 if (drive && drive[0])
745 {
746 path[0] = drive[0];
747 path[1] = ':';
748 path[2] = 0;
749 }
750 if (directory && directory[0])
751 {
752 strcat(path, directory);
753 ch = path[strlen(path)-1];
754 if (ch != '/' && ch != '\\')
755 strcat(path,"\\");
756 }
757 if (filename && filename[0])
758 {
759 strcat(path, filename);
760 if (extension && extension[0])
761 {
762 if ( extension[0] != '.' )
763 strcat(path,".");
764 strcat(path,extension);
765 }
766 }
767
768 TRACE("returning %s\n",path);
769}
770
771#endif /* !__MINIVCRT__ */
772
773/*********************************************************************
774 * _wmakepath (MSVCRT.@)
775 */
776VOID _wmakepath(MSVCRT_wchar_t *path, const MSVCRT_wchar_t *drive, const MSVCRT_wchar_t *directory,
777 const MSVCRT_wchar_t *filename, const MSVCRT_wchar_t *extension)
778{
779 MSVCRT_wchar_t ch;
780 TRACE("%s %s %s %s\n", debugstr_w(drive), debugstr_w(directory),
781 debugstr_w(filename), debugstr_w(extension));
782
783 if ( !path )
784 return;
785
786 path[0] = 0;
787 if (drive && drive[0])
788 {
789 path[0] = drive[0];
790 path[1] = ':';
791 path[2] = 0;
792 }
793 if (directory && directory[0])
794 {
795 strcatW(path, directory);
796 ch = path[strlenW(path) - 1];
797 if (ch != '/' && ch != '\\')
798 {
799 static const MSVCRT_wchar_t backslashW[] = {'\\',0};
800 strcatW(path, backslashW);
801 }
802 }
803 if (filename && filename[0])
804 {
805 strcatW(path, filename);
806 if (extension && extension[0])
807 {
808 if ( extension[0] != '.' )
809 {
810 static const MSVCRT_wchar_t dotW[] = {'.',0};
811 strcatW(path, dotW);
812 }
813 strcatW(path, extension);
814 }
815 }
816
817 TRACE("returning %s\n", debugstr_w(path));
818}
819
820#ifndef __MINIVCRT__
821
822/*********************************************************************
823 * _searchenv (MSVCRT.@)
824 */
825void MSVCRT__searchenv(const char* file, const char* env, char *buf)
826{
827 char*envVal, *penv;
828 char curPath[MAX_PATH];
829
830 *buf = '\0';
831
832 /* Try CWD first */
833 if (GetFileAttributesA( file ) != 0xFFFFFFFF)
834 {
835 GetFullPathNameA( file, MAX_PATH, buf, NULL );
836 /* Sigh. This error is *always* set, regardless of success */
837 MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
838 return;
839 }
840
841 /* Search given environment variable */
842 envVal = MSVCRT_getenv(env);
843 if (!envVal)
844 {
845 MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
846 return;
847 }
848
849 penv = envVal;
850 TRACE(":searching for %s in paths %s\n", file, envVal);
851
852 do
853 {
854 char *end = penv;
855
856 while(*end && *end != ';') end++; /* Find end of next path */
857 if (penv == end || !*penv)
858 {
859 MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
860 return;
861 }
862 strncpy(curPath, penv, end - penv);
863 if (curPath[end - penv] != '/' || curPath[end - penv] != '\\')
864 {
865 curPath[end - penv] = '\\';
866 curPath[end - penv + 1] = '\0';
867 }
868 else
869 curPath[end - penv] = '\0';
870
871 strcat(curPath, file);
872 TRACE("Checking for file %s\n", curPath);
873 if (GetFileAttributesA( curPath ) != 0xFFFFFFFF)
874 {
875 strcpy(buf, curPath);
876 MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
877 return; /* Found */
878 }
879 penv = *end ? end + 1 : end;
880 } while(1);
881}
882
883#endif /* !__MINIVCRT__ */
884
885MSVCRT_wchar_t* _wfullpath(MSVCRT_wchar_t* absPath,const MSVCRT_wchar_t* relPath,MSVCRT(size_t) size)
886{
887 MSVCRT_wchar_t ch;
888 char asciiabsPath[280], asciirelPath[280];
889
890 TRACE("MSVCRT: _wfullpath %s %d\n", debugstr_w(relPath),size);
891
892 WideCharToMultiByte(CP_ACP, 0, relPath, -1, (LPSTR)asciirelPath, 280, NULL, NULL);
893
894 MSVCRT__fullpath(asciiabsPath, asciirelPath, size);
895
896 MultiByteToWideChar(CP_ACP, 0, asciiabsPath, -1, absPath, size);
897
898 return absPath;
899}
Note: See TracBrowser for help on using the repository browser.