Release 970914
[wine.git] / misc / crtdll.c
blob7ba7d07a75726d2353045c6499e5fcabd717926f
1 /*
2 * The C RunTime DLL
3 *
4 * Implements C run-time functionality as known from UNIX.
6 * Copyright 1996 Marcus Meissner
7 * Copyright 1996 Jukka Iivonen
8 * Copyright 1997 Uwe Bonnes
9 */
12 Unresolved issues Uwe Bonnes 970904:
13 - Handling of Binary/Text Files is crude. If in doubt, use fromdos or recode
14 - Arguments in crtdll.spec for functions with double argument
15 - system-call calls another wine process, but without debugging arguments
16 and uses the first wine executable in the path
17 - tested with ftp://ftp.remcomp.com/pub/remcomp/lcc-win32.zip, a C-Compiler
18 for Win32, based on lcc, from Jacob Navia
21 /* FIXME: all the file handling is hopelessly broken -- AJ */
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <ctype.h>
30 #include <math.h>
31 #include <fcntl.h>
32 #include "win.h"
33 #include "windows.h"
34 #include "stddebug.h"
35 #include "debug.h"
36 #include "module.h"
37 #include "xmalloc.h"
38 #include "heap.h"
39 #include "crtdll.h"
40 #include "drive.h"
41 #include "file.h"
43 extern int FILE_GetUnixHandle( HFILE32 );
45 static DOS_FULL_NAME CRTDLL_tmpname;
47 extern INT32 WIN32_wsprintf32W( DWORD *args );
49 UINT32 CRTDLL_argc_dll; /* CRTDLL.23 */
50 LPSTR *CRTDLL_argv_dll; /* CRTDLL.24 */
51 LPSTR CRTDLL_acmdln_dll; /* CRTDLL.38 */
52 UINT32 CRTDLL_basemajor_dll; /* CRTDLL.42 */
53 UINT32 CRTDLL_baseminor_dll; /* CRTDLL.43 */
54 UINT32 CRTDLL_baseversion_dll; /* CRTDLL.44 */
55 LPSTR CRTDLL_environ_dll; /* CRTDLL.75 */
56 UINT32 CRTDLL_osmajor_dll; /* CRTDLL.241 */
57 UINT32 CRTDLL_osminor_dll; /* CRTDLL.242 */
58 UINT32 CRTDLL_osver_dll; /* CRTDLL.244 */
59 UINT32 CRTDLL_osversion_dll; /* CRTDLL.245 */
60 UINT32 CRTDLL_winmajor_dll; /* CRTDLL.329 */
61 UINT32 CRTDLL_winminor_dll; /* CRTDLL.330 */
62 UINT32 CRTDLL_winver_dll; /* CRTDLL.331 */
64 typedef VOID (*new_handler_type)(VOID);
66 static new_handler_type new_handler;
68 /*********************************************************************
69 * _GetMainArgs (CRTDLL.022)
71 DWORD __cdecl CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,
72 LPSTR *environ,DWORD flag)
74 char *cmdline;
75 char **xargv;
76 int xargc,i,afterlastspace;
77 DWORD version;
79 dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs(%p,%p,%p,%ld).\n",
80 argc,argv,environ,flag
82 CRTDLL_acmdln_dll = cmdline = xstrdup( GetCommandLine32A() );
83 dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs got \"%s\"\n",
84 cmdline);
86 version = GetVersion32();
87 CRTDLL_osver_dll = version >> 16;
88 CRTDLL_winminor_dll = version & 0xFF;
89 CRTDLL_winmajor_dll = (version>>8) & 0xFF;
90 CRTDLL_baseversion_dll = version >> 16;
91 CRTDLL_winver_dll = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
92 CRTDLL_baseminor_dll = (version >> 16) & 0xFF;
93 CRTDLL_basemajor_dll = (version >> 24) & 0xFF;
94 CRTDLL_osversion_dll = version & 0xFFFF;
95 CRTDLL_osminor_dll = version & 0xFF;
96 CRTDLL_osmajor_dll = (version>>8) & 0xFF;
98 /* missing threading init */
100 i=0;xargv=NULL;xargc=0;afterlastspace=0;
101 while (cmdline[i]) {
102 if (cmdline[i]==' ') {
103 xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
104 cmdline[i]='\0';
105 xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
106 i++;
107 while (cmdline[i]==' ')
108 i++;
109 if (cmdline[i])
110 afterlastspace=i;
111 } else
112 i++;
114 xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
115 cmdline[i]='\0';
116 xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
117 CRTDLL_argc_dll = xargc;
118 *argc = xargc;
119 CRTDLL_argv_dll = xargv;
120 *argv = xargv;
122 dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs found %d arguments\n",
123 CRTDLL_argc_dll);
124 /* FIXME ... use real environment */
125 *environ = xmalloc(sizeof(LPSTR));
126 CRTDLL_environ_dll = *environ;
127 (*environ)[0] = NULL;
128 return 0;
132 typedef void (*_INITTERMFUN)();
134 /*********************************************************************
135 * _initterm (CRTDLL.135)
137 DWORD __cdecl CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
139 _INITTERMFUN *current;
141 dprintf_crtdll(stddeb,"_initterm(%p,%p)\n",start,end);
142 current=start;
143 while (current<end) {
144 if (*current) (*current)();
145 current++;
147 return 0;
150 /*********************************************************************
151 * _fdopen (CRTDLL.91)
153 DWORD __cdecl CRTDLL__fdopen(INT32 handle, LPCSTR mode)
155 FILE *file;
157 switch (handle)
159 case 0 : file=stdin;
160 break;
161 case 1 : file=stdout;
162 break;
163 case 2 : file=stderr;
164 break;
165 default:
166 file=fdopen(handle,mode);
168 dprintf_crtdll(stddeb,
169 "CRTDLL_fdopen open handle %d mode %s got file %p\n",
170 handle, mode, file);
171 return (DWORD)file;
174 /*********************************************************************
175 * fopen (CRTDLL.372)
177 DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
179 FILE *file;
180 HFILE32 dos_fildes;
181 #if 0
182 DOS_FULL_NAME full_name;
184 if (!DOSFS_GetFullName( path, FALSE, &full_name )) {
185 dprintf_crtdll(stddeb,"CRTDLL_fopen file %s bad name\n",path);
186 return 0;
189 file=fopen(full_name.long_name ,mode);
190 #endif
191 INT32 flagmode=0;
192 int unix_fildes=0;
194 if ((strchr(mode,'r')&&strchr(mode,'a'))||
195 (strchr(mode,'r')&&strchr(mode,'w'))||
196 (strchr(mode,'w')&&strchr(mode,'a')))
197 return 0;
199 if (strstr(mode,"r+")) flagmode=O_RDWR;
200 else if (strchr(mode,'r')) flagmode = O_RDONLY;
201 else if (strstr(mode,"w+")) flagmode= O_RDWR | O_TRUNC | O_CREAT;
202 else if (strchr(mode,'w')) flagmode = O_WRONLY | O_TRUNC | O_CREAT;
203 else if (strstr(mode,"a+")) flagmode= O_RDWR | O_CREAT | O_APPEND;
204 else if (strchr(mode,'w')) flagmode = O_RDWR | O_CREAT | O_APPEND;
205 else if (strchr(mode,'b'))
206 dprintf_crtdll(stderr,
207 "CRTDLL_fopen %s in BINARY mode\n",path);
209 dos_fildes=FILE_Open(path, flagmode);
210 unix_fildes=FILE_GetUnixHandle(dos_fildes);
211 file = fdopen(unix_fildes,mode);
213 dprintf_crtdll(stddeb,
214 "CRTDLL_fopen file %s mode %s got ufh %d dfh %d file %p\n",
215 path,mode,unix_fildes,dos_fildes,file);
216 return (DWORD)file;
219 /*********************************************************************
220 * fread (CRTDLL.377)
222 DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
224 size_t ret=1;
225 #if 0
226 int i=0;
227 void *temp=ptr;
229 /* If we would honour CR/LF <-> LF translation, we could do it like this.
230 We should keep track of all files opened, and probably files with \
231 known binary extensions must be unchanged */
232 while ( (i < (nmemb*size)) && (ret==1)) {
233 ret=fread(temp,1,1,file);
234 dprintf_crtdll(stddeb,
235 "CRTDLL_fread got %c 0x%02x ret %d\n",
236 (isalpha(*(unsigned char*)temp))? *(unsigned char*)temp:
237 ' ',*(unsigned char*)temp, ret);
238 if (*(unsigned char*)temp != 0xd) { /* skip CR */
239 temp++;
240 i++;
242 else
243 dprintf_crtdll(stddeb, "CRTDLL_fread skipping ^M\n");
245 dprintf_crtdll(stddeb,
246 "CRTDLL_fread 0x%08x items of size %d from file %p to %p%s\n",
247 nmemb,size,file,ptr,(i!=nmemb)?" failed":"");
248 return i;
249 #else
251 ret=fread(ptr,size,nmemb,file);
252 dprintf_crtdll(stddeb,
253 "CRTDLL_fread 0x%08x items of size %d from file %p to %p%s\n",
254 nmemb,size,file,ptr,(ret!=nmemb)?" failed":"");
255 return ret;
256 #endif
259 /*********************************************************************
260 * fseek (CRTDLL.382)
262 LONG __cdecl CRTDLL_fseek(LPVOID stream, LONG offset, INT32 whence)
264 long ret;
266 ret=fseek(stream,offset,whence);
267 dprintf_crtdll(stddeb,
268 "CRTDLL_fseek file %p to 0x%08lx pos %s%s\n",
269 stream,offset,(whence==SEEK_SET)?"SEEK_SET":
270 (whence==SEEK_CUR)?"SEEK_CUR":
271 (whence==SEEK_END)?"SEEK_END":"UNKNOWN",
272 (ret)?"failed":"");
273 return ret;
276 /*********************************************************************
277 * ftell (CRTDLL.384)
279 LONG __cdecl CRTDLL_ftell(LPVOID stream)
281 long ret;
283 ret=ftell(stream);
284 dprintf_crtdll(stddeb,
285 "CRTDLL_ftell file %p at 0x%08lx\n",
286 stream,ret);
287 return ret;
290 /*********************************************************************
291 * fwrite (CRTDLL.386)
293 DWORD __cdecl CRTDLL_fwrite(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
295 size_t ret;
297 ret=fwrite(ptr,size,nmemb,file);
298 dprintf_crtdll(stddeb,
299 "CRTDLL_fwrite 0x%08x items of size %d from %p to file %p%s\n",
300 nmemb,size,ptr,file,(ret!=nmemb)?" failed":"");
301 return ret;
304 /*********************************************************************
305 * setbuf (CRTDLL.452)
307 INT32 __cdecl CRTDLL_setbuf(LPVOID file, LPSTR buf)
309 dprintf_crtdll(stddeb,
310 "CRTDLL_setbuf(file %p buf %p)\n",
311 file,buf);
312 /* this doesn't work:"void value not ignored as it ought to be"
313 return setbuf(file,buf);
315 setbuf(file,buf);
316 return 0;
319 /*********************************************************************
320 * _open_osfhandle (CRTDLL.240)
322 HFILE32 __cdecl CRTDLL__open_osfhandle(LONG osfhandle, INT32 flags)
324 HFILE32 handle;
326 switch (osfhandle) {
327 case STD_INPUT_HANDLE :
328 case 0 :
329 handle=0;
330 break;
331 case STD_OUTPUT_HANDLE:
332 case 1:
333 handle=1;
334 break;
335 case STD_ERROR_HANDLE:
336 case 2:
337 handle=2;
338 break;
339 default:
340 return (-1);
342 dprintf_crtdll(stddeb,
343 "CRTDLL_open_osfhandle(handle %08lx,flags %d) return %d\n",
344 osfhandle,flags,handle);
345 return handle;
349 /*********************************************************************
350 * srand (CRTDLL.460)
352 void __cdecl CRTDLL_srand(DWORD seed)
354 /* FIXME: should of course be thread? process? local */
355 srand(seed);
358 /*********************************************************************
359 * fprintf (CRTDLL.373)
361 INT32 __cdecl CRTDLL_fprintf( FILE *file, LPSTR format, ... )
363 va_list valist;
364 INT32 res;
366 va_start( valist, format );
367 res = vfprintf( file, format, valist );
368 va_end( valist );
369 return res;
372 /*********************************************************************
373 * vfprintf (CRTDLL.373)
375 INT32 __cdecl CRTDLL_vfprintf( FILE *file, LPSTR format, va_list args )
377 return vfprintf( file, format, args );
380 /*********************************************************************
381 * time (CRTDLL.488)
383 time_t __cdecl CRTDLL_time(time_t *timeptr)
385 time_t curtime = time(NULL);
387 if (timeptr)
388 *timeptr = curtime;
389 return curtime;
392 /*********************************************************************
393 * _isatty (CRTDLL.137)
395 BOOL32 __cdecl CRTDLL__isatty(DWORD x)
397 dprintf_crtdll(stderr,"CRTDLL__isatty(%ld)\n",x);
398 return TRUE;
401 /*********************************************************************
402 * _write (CRTDLL.332)
404 INT32 __cdecl CRTDLL__write(INT32 fd,LPCVOID buf,UINT32 count)
406 INT32 len=0;
408 if (fd == -1)
409 len = -1;
410 else if (fd<=2)
411 len = (UINT32)write(fd,buf,(LONG)len);
412 else
413 len = _lwrite32(fd,buf,count);
414 dprintf_crtdll(stddeb,"CRTDLL_write %d/%d byte to dfh %d from %p,\n",
415 len,count,fd,buf);
416 return len;
420 /*********************************************************************
421 * _cexit (CRTDLL.49)
423 * FIXME: What the heck is the difference between
424 * FIXME _c_exit (CRTDLL.47)
425 * FIXME _cexit (CRTDLL.49)
426 * FIXME _exit (CRTDLL.87)
427 * FIXME exit (CRTDLL.359)
430 void __cdecl CRTDLL__cexit(INT32 ret)
432 dprintf_crtdll(stddeb,"CRTDLL__cexit(%d)\n",ret);
433 ExitProcess(ret);
437 /*********************************************************************
438 * exit (CRTDLL.359)
440 void __cdecl CRTDLL_exit(DWORD ret)
442 dprintf_crtdll(stddeb,"CRTDLL_exit(%ld)\n",ret);
443 ExitProcess(ret);
447 /*********************************************************************
448 * fflush (CRTDLL.365)
450 INT32 __cdecl CRTDLL_fflush(LPVOID stream)
452 int ret;
454 ret = fflush(stream);
455 dprintf_crtdll(stddeb,"CRTDLL_fflush %p returnd %d %s\n",stream,ret,(ret)?"":" failed");
456 return ret;
460 /*********************************************************************
461 * gets (CRTDLL.391)
463 LPSTR __cdecl CRTDLL_gets(LPSTR buf)
465 /* BAD, for the whole WINE process blocks... just done this way to test
466 * windows95's ftp.exe.
468 return gets(buf);
472 /*********************************************************************
473 * rand (CRTDLL.446)
475 INT32 __cdecl CRTDLL_rand()
477 return rand();
481 /*********************************************************************
482 * putchar (CRTDLL.442)
484 void __cdecl CRTDLL_putchar( INT32 x )
486 putchar(x);
490 /*********************************************************************
491 * fputc (CRTDLL.374)
493 INT32 __cdecl CRTDLL_fputc( INT32 c, FILE *stream )
495 dprintf_crtdll(stddeb,
496 "CRTDLL_fputc %c to file %p\n",c,stream);
497 return fputc(c,stream);
501 /*********************************************************************
502 * fputs (CRTDLL.375)
504 INT32 __cdecl CRTDLL_fputs( LPCSTR s, FILE *stream )
506 dprintf_crtdll(stddeb,
507 "CRTDLL_fputs %s to file %p\n",s,stream);
508 return fputs(s,stream);
512 /*********************************************************************
513 * puts (CRTDLL.443)
515 INT32 __cdecl CRTDLL_puts(LPCSTR s)
517 dprintf_crtdll(stddeb,
518 "CRTDLL_fputs %s \n",s);
519 return puts(s);
523 /*********************************************************************
524 * putc (CRTDLL.441)
526 INT32 __cdecl CRTDLL_putc(INT32 c, FILE *stream)
528 dprintf_crtdll(stddeb,
529 "CRTDLL_putc %c to file %p\n",c,stream);
530 return fputc(c,stream);
532 /*********************************************************************
533 * fgetc (CRTDLL.366)
535 INT32 __cdecl CRTDLL_fgetc( FILE *stream )
537 int ret= fgetc(stream);
538 dprintf_crtdll(stddeb,
539 "CRTDLL_fgetc got %d\n",ret);
540 return ret;
544 /*********************************************************************
545 * getc (CRTDLL.388)
547 INT32 __cdecl CRTDLL_getc( FILE *stream )
549 int ret= fgetc(stream);
550 dprintf_crtdll(stddeb,
551 "CRTDLL_getc got %d\n",ret);
552 return ret;
555 /*********************************************************************
556 * _lrotl (CRTDLL.176)
558 DWORD __cdecl CRTDLL__lrotl(DWORD x,INT32 shift)
560 unsigned long ret = (x >> shift)|( x >>((sizeof(x))-shift));
562 dprintf_crtdll(stddeb,
563 "CRTDLL_lrotl got 0x%08lx rot %d ret 0x%08lx\n",
564 x,shift,ret);
565 return ret;
570 /*********************************************************************
571 * fgets (CRTDLL.368)
573 CHAR* __cdecl CRTDLL_fgets(LPSTR s,INT32 size, LPVOID stream)
575 char * ret;
576 char * control_M;
578 ret=fgets(s, size,stream);
579 /*FIXME: Control with CRTDLL_setmode */
580 control_M= strrchr(s,'\r');
581 /*delete CR if we read a DOS File */
582 if (control_M)
584 *control_M='\n';
585 *(control_M+1)=0;
587 dprintf_crtdll(stddeb,
588 "CRTDLL_fgets got %s for %d chars from file %p%s\n",
589 s,size,stream,(ret)?"":" failed");
590 return ret;
594 /*********************************************************************
595 * _mbsicmp (CRTDLL.204)
597 int __cdecl CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
599 do {
600 if (!*x)
601 return !!*y;
602 if (!*y)
603 return !!*x;
604 /* FIXME: MBCS handling... */
605 if (*x!=*y)
606 return 1;
607 x++;
608 y++;
609 } while (1);
613 /*********************************************************************
614 * _mbsinc (CRTDLL.205)
616 unsigned char * __cdecl CRTDLL__mbsinc(unsigned char *x)
618 /* FIXME: mbcs */
619 return x++;
623 /*********************************************************************
624 * vsprintf (CRTDLL.500)
626 INT32 __cdecl CRTDLL_vsprintf( LPSTR buffer, LPCSTR spec, va_list args )
628 return wvsprintf32A( buffer, spec, args );
631 /*********************************************************************
632 * vswprintf (CRTDLL.501)
634 INT32 __cdecl CRTDLL_vswprintf( LPWSTR buffer, LPCWSTR spec, va_list args )
636 return wvsprintf32W( buffer, spec, args );
639 /*********************************************************************
640 * _mbscpy (CRTDLL.200)
642 unsigned char* __cdecl CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
644 dprintf_crtdll(stddeb,"CRTDLL_mbscpy %s and %s\n",x,y);
645 return strcpy(x,y);
649 /*********************************************************************
650 * _mbscat (CRTDLL.197)
652 unsigned char* __cdecl CRTDLL__mbscat(unsigned char *x,unsigned char *y)
654 return strcat(x,y);
658 /*********************************************************************
659 * _strcmpi (CRTDLL.282) (CRTDLL.287)
661 INT32 __cdecl CRTDLL__strcmpi( LPCSTR s1, LPCSTR s2 )
663 return lstrcmpi32A( s1, s2 );
667 /*********************************************************************
668 * _strnicmp (CRTDLL.293)
670 INT32 __cdecl CRTDLL__strnicmp( LPCSTR s1, LPCSTR s2, INT32 n )
672 return lstrncmpi32A( s1, s2, n );
676 /*********************************************************************
677 * _strlwr (CRTDLL.293)
679 * convert a string in place to lowercase
681 LPSTR CRTDLL__strlwr(LPSTR x)
683 unsigned char *y =x;
685 dprintf_crtdll(stddeb,
686 "CRTDLL_strlwr got %s",x);
687 while (*y) {
688 if ((*y > 0x40) && (*y< 0x5b))
689 *y = *y + 0x20;
690 y++;
692 dprintf_crtdll(stddeb," returned %s\n",x);
694 return x;
697 /*********************************************************************
698 * system (CRTDLL.485)
700 INT32 CRTDLL_system(LPSTR x)
702 #define SYSBUF_LENGTH 1500
703 char buffer[SYSBUF_LENGTH]="wine \"";
704 unsigned char *y =x;
705 unsigned char *bp =buffer+strlen(buffer);
706 int i =strlen(buffer) + strlen(x) +2;
708 /* Calculate needed buffer size tp prevent overflow*/
709 while (*y) {
710 if (*y =='\\') i++;
711 y++;
713 /* if buffer to short, exit */
714 if (i > SYSBUF_LENGTH) {
715 dprintf_crtdll(stddeb,"_system buffer to small\n");
716 return 127;
719 y =x;
721 while (*y) {
722 *bp = *y;
723 bp++; y++;
724 if (*(y-1) =='\\') *bp++ = '\\';
726 /* remove spaces from end of string */
727 while (*(y-1) == ' ') {
728 bp--;y--;
730 *bp++ = '"';
731 *bp = 0;
732 dprintf_crtdll(stddeb,
733 "_system got \"%s\", executing \"%s\"\n",x,buffer);
735 return system(buffer);
738 /*********************************************************************
739 * _strupr (CRTDLL.300)
741 LPSTR __cdecl CRTDLL__strupr(LPSTR x)
743 LPSTR y=x;
745 while (*y) {
746 *y=toupper(*y);
747 y++;
749 return x;
752 /*********************************************************************
753 * _wcsupr (CRTDLL.328)
755 LPWSTR __cdecl CRTDLL__wcsupr(LPWSTR x)
757 LPWSTR y=x;
759 while (*y) {
760 *y=toupper(*y);
761 y++;
763 return x;
766 /*********************************************************************
767 * _wcslwr (CRTDLL.323)
769 LPWSTR __cdecl CRTDLL__wcslwr(LPWSTR x)
771 LPWSTR y=x;
773 while (*y) {
774 *y=tolower(*y);
775 y++;
777 return x;
781 /*********************************************************************
782 * malloc (CRTDLL.427)
784 VOID* __cdecl CRTDLL_malloc(DWORD size)
786 return HeapAlloc(GetProcessHeap(),0,size);
789 /*********************************************************************
790 * new (CRTDLL.001)
792 VOID* __cdecl CRTDLL_new(DWORD size)
794 VOID* result;
795 if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
796 (*new_handler)();
797 return result;
800 /*********************************************************************
801 * set_new_handler(CRTDLL.003)
803 new_handler_type __cdecl CRTDLL_set_new_handler(new_handler_type func)
805 new_handler_type old_handler = new_handler;
806 new_handler = func;
807 return old_handler;
810 /*********************************************************************
811 * calloc (CRTDLL.350)
813 VOID* __cdecl CRTDLL_calloc(DWORD size, DWORD count)
815 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
818 /*********************************************************************
819 * realloc (CRTDLL.447)
821 VOID* __cdecl CRTDLL_realloc( VOID *ptr, DWORD size )
823 return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
826 /*********************************************************************
827 * free (CRTDLL.427)
829 VOID __cdecl CRTDLL_free(LPVOID ptr)
831 HeapFree(GetProcessHeap(),0,ptr);
834 /*********************************************************************
835 * delete (CRTDLL.002)
837 VOID __cdecl CRTDLL_delete(VOID* ptr)
839 HeapFree(GetProcessHeap(),0,ptr);
842 /*********************************************************************
843 * _strdup (CRTDLL.285)
845 LPSTR __cdecl CRTDLL__strdup(LPSTR ptr)
847 return HEAP_strdupA(GetProcessHeap(),0,ptr);
851 /*********************************************************************
852 * fclose (CRTDLL.362)
854 INT32 __cdecl CRTDLL_fclose( FILE *stream )
856 int unix_handle=fileno(stream);
857 HFILE32 dos_handle=3;
858 HFILE32 ret=EOF;
860 if (unix_handle<4) ret= fclose(stream);
861 else {
862 while(FILE_GetUnixHandle(dos_handle) != unix_handle) dos_handle++;
863 fclose(stream);
864 ret = _lclose32( dos_handle);
866 dprintf_crtdll(stddeb,"CRTDLL_fclose(%p) ufh %d dfh %d%s\n",
867 stream,unix_handle,dos_handle,(ret)?" failed":"");
868 return ret;
871 /*********************************************************************
872 * _unlink (CRTDLL.315)
874 INT32 __cdecl CRTDLL__unlink(LPCSTR pathname)
876 int ret=0;
877 DOS_FULL_NAME full_name;
879 if (!DOSFS_GetFullName( pathname, FALSE, &full_name )) {
880 dprintf_crtdll(stddeb,"CRTDLL_unlink file %s bad name\n",pathname);
881 return EOF;
884 ret=unlink(full_name.long_name);
885 dprintf_crtdll(stddeb,"CRTDLL_unlink(%s unix %s)%s\n",
886 pathname,full_name.long_name, (ret)?" failed":"");
887 return ret;
890 /*********************************************************************
891 * _open (CRTDLL.239)
893 HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
895 HFILE32 ret=0;
896 int wineflags=0;
898 /* FIXME:
899 the flags in lcc's header differ from the ones in Linux, e.g.
900 Linux: define O_APPEND 02000 (= 0x400)
901 lcc: define _O_APPEND 0x0008
902 so here a scheme to translate them
903 Probably lcc is wrong here, but at least a hack to get is going
905 wineflags = (flags & 3);
906 if (flags & 0x0008 ) wineflags |= O_APPEND;
907 if (flags & 0x0100 ) wineflags |= O_CREAT;
908 if (flags & 0x0200 ) wineflags |= O_TRUNC;
909 if (flags & 0x0400 ) wineflags |= O_EXCL;
910 if (flags & 0xf0f4 )
911 dprintf_crtdll(stddeb,"CRTDLL_open file unsupported flags 0x%04x\n",flags);
912 /* End Fixme */
914 ret = FILE_Open(path,wineflags);
915 dprintf_crtdll(stddeb,"CRTDLL_open file %s mode 0x%04x (lccmode 0x%04x) got dfh %d\n",
916 path,wineflags,flags,ret);
917 return ret;
920 /*********************************************************************
921 * _close (CRTDLL.57)
923 INT32 __cdecl CRTDLL__close(HFILE32 fd)
925 int ret=_lclose32(fd);
927 dprintf_crtdll(stddeb,"CRTDLL_close(%d)%s\n",fd,(ret)?" failed":"");
928 return ret;
931 /*********************************************************************
932 * feof (CRTDLL.363)
934 INT32 __cdecl CRTDLL_feof( FILE *stream )
936 int ret;
938 ret=feof(stream);
939 dprintf_crtdll(stddeb,"CRTDLL_feof(%p) %s\n",stream,(ret)?"true":"false");
940 return ret;
943 /*********************************************************************
944 * setlocale (CRTDLL.453)
946 LPSTR __cdecl CRTDLL_setlocale(INT32 category,LPCSTR locale)
948 LPSTR categorystr;
950 switch (category) {
951 case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
952 case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
953 case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
954 case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
955 case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
956 case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
957 default: categorystr = "UNKNOWN?";break;
959 fprintf(stderr,"CRTDLL_setlocale(%s,%s),stub!\n",categorystr,locale);
960 return "C";
963 /*********************************************************************
964 * wcscat (CRTDLL.503)
966 LPWSTR __cdecl CRTDLL_wcscat( LPWSTR s1, LPCWSTR s2 )
968 return lstrcat32W( s1, s2 );
971 /*********************************************************************
972 * wcschr (CRTDLL.504)
974 LPWSTR __cdecl CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
976 LPWSTR s;
978 s=str;
979 do {
980 if (*s==xchar)
981 return s;
982 } while (*s++);
983 return NULL;
986 /*********************************************************************
987 * wcscmp (CRTDLL.505)
989 INT32 __cdecl CRTDLL_wcscmp( LPCWSTR s1, LPCWSTR s2 )
991 return lstrcmp32W( s1, s2 );
994 /*********************************************************************
995 * wcscpy (CRTDLL.507)
997 LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR s1, LPCWSTR s2 )
999 return lstrcpy32W( s1, s2 );
1002 /*********************************************************************
1003 * wcscspn (CRTDLL.508)
1005 INT32 __cdecl CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
1007 LPWSTR s,t;
1009 s=str;
1010 do {
1011 t=reject;
1012 while (*t) { if (*t==*s) break;t++;}
1013 if (*t) break;
1014 s++;
1015 } while (*s);
1016 return s-str; /* nr of wchars */
1019 /*********************************************************************
1020 * wcslen (CRTDLL.510)
1022 INT32 __cdecl CRTDLL_wcslen( LPCWSTR s )
1024 return lstrlen32W( s );
1027 /*********************************************************************
1028 * wcsncat (CRTDLL.511)
1030 LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT32 n )
1032 return lstrcatn32W( s1, s2, n );
1035 /*********************************************************************
1036 * wcsncmp (CRTDLL.512)
1038 INT32 __cdecl CRTDLL_wcsncmp( LPCWSTR s1, LPCWSTR s2, INT32 n )
1040 return lstrncmp32W( s1, s2, n );
1043 /*********************************************************************
1044 * wcsncpy (CRTDLL.513)
1046 LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT32 n )
1048 return lstrcpyn32W( s1, s2, n );
1051 /*********************************************************************
1052 * wcsspn (CRTDLL.516)
1054 INT32 __cdecl CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
1056 LPWSTR s,t;
1058 s=str;
1059 do {
1060 t=accept;
1061 while (*t) { if (*t==*s) break;t++;}
1062 if (!*t) break;
1063 s++;
1064 } while (*s);
1065 return s-str; /* nr of wchars */
1068 /*********************************************************************
1069 * towupper (CRTDLL.494)
1071 WCHAR __cdecl CRTDLL_towupper(WCHAR x)
1073 return (WCHAR)toupper((CHAR)x);
1076 /*********************************************************************
1077 * _wcsicmp (CRTDLL.321)
1079 DWORD __cdecl CRTDLL__wcsicmp( LPCWSTR s1, LPCWSTR s2 )
1081 return lstrcmpi32W( s1, s2 );
1084 /*********************************************************************
1085 * _wcsicoll (CRTDLL.322)
1087 DWORD __cdecl CRTDLL__wcsicoll(LPCWSTR a1,LPCWSTR a2)
1089 /* FIXME: handle collates */
1090 return lstrcmpi32W(a1,a2);
1093 /*********************************************************************
1094 * _wcsnicmp (CRTDLL.324)
1096 DWORD __cdecl CRTDLL__wcsnicmp( LPCWSTR s1, LPCWSTR s2, INT32 len )
1098 return lstrncmpi32W( s1, s2, len );
1101 /*********************************************************************
1102 * wcscoll (CRTDLL.506)
1104 DWORD __cdecl CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
1106 /* FIXME: handle collates */
1107 return lstrcmp32W(a1,a2);
1110 /*********************************************************************
1111 * _wcsrev (CRTDLL.326)
1113 VOID __cdecl CRTDLL__wcsrev(LPWSTR s) {
1114 LPWSTR e;
1116 e=s;
1117 while (*e)
1118 e++;
1119 while (s<e) {
1120 WCHAR a;
1122 a=*s;*s=*e;*e=a;
1123 s++;e--;
1127 /*********************************************************************
1128 * wcsstr (CRTDLL.517)
1130 LPWSTR __cdecl CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
1132 LPWSTR x,y,c;
1134 x=s;
1135 while (*x) {
1136 if (*x==*b) {
1137 y=x;c=b;
1138 while (*y && *c && *y==*c) { c++;y++; }
1139 if (!*c)
1140 return x;
1142 x++;
1144 return NULL;
1147 /*********************************************************************
1148 * wcstombs (CRTDLL.521)
1150 INT32 __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT32 len )
1152 lstrcpynWtoA( dst, src, len );
1153 return strlen(dst); /* FIXME: is this right? */
1156 /*********************************************************************
1157 * wcsrchr (CRTDLL.515)
1159 LPWSTR __cdecl CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
1161 LPWSTR s;
1163 s=str+lstrlen32W(str);
1164 do {
1165 if (*s==xchar)
1166 return s;
1167 s--;
1168 } while (s>=str);
1169 return NULL;
1172 /*********************************************************************
1173 * _setmode (CRTDLL.265)
1174 * FIXME: At present we ignore the request to translate CR/LF to LF.
1176 * We allways translate when we read with fgets, we never do with fread
1179 INT32 __cdecl CRTDLL__setmode( INT32 fh,INT32 mode)
1181 /* FIXME */
1182 #define O_TEXT 0x4000
1183 #define O_BINARY 0x8000
1185 dprintf_crtdll(stddeb,
1186 "CRTDLL._setmode on fhandle %d mode %s, STUB.\n",
1187 fh,(mode=O_TEXT)?"O_TEXT":
1188 (mode=O_BINARY)?"O_BINARY":"UNKNOWN");
1189 return -1;
1192 /*********************************************************************
1193 * atexit (CRTDLL.345)
1195 INT32 __cdecl CRTDLL_atexit(LPVOID x)
1197 /* FIXME */
1198 fprintf(stdnimp,"CRTDLL.atexit(%p), STUB.\n",x);
1199 return 0; /* successful */
1202 /*********************************************************************
1203 * mblen (CRTDLL.428)
1204 * FIXME: check multibyte support
1206 WCHAR __cdecl CRTDLL_mblen(CHAR *mb,INT32 size)
1209 int ret=1;
1211 if (!mb)
1212 ret = 0;
1213 else if ((size<1)||(!*(mb+1)))
1214 ret = -1;
1215 else if (!(*mb))
1216 ret =0;
1218 dprintf_crtdll(stderr,"CRTDLL_mlen %s for max %d bytes ret %d\n",mb,size,ret);
1220 return ret;
1223 /*********************************************************************
1224 * mbstowcs (CRTDLL.429)
1225 * FIXME: check multibyte support
1227 INT32 __cdecl CRTDLL_mbstowcs(LPWSTR wcs, LPCSTR mbs, INT32 size)
1230 /* Slightly modified lstrcpynAtoW functions from memory/strings.c
1231 * We need the numberr of characters transfered
1232 * FIXME: No multibyte support yet
1235 LPWSTR p = wcs;
1236 LPCSTR src= mbs;
1237 int ret, n=size;
1239 while ((n-- > 0) && *src) {
1240 *p++ = (WCHAR)(unsigned char)*src++;
1242 p++;
1243 ret = (p -wcs);
1245 dprintf_crtdll(stddeb,"CRTDLL_mbstowcs %s for %d chars put %d wchars\n",
1246 mbs,size,ret);
1247 return ret;
1250 /*********************************************************************
1251 * mbtowc (CRTDLL.430)
1252 * FIXME: check multibyte support
1254 WCHAR __cdecl CRTDLL_mbtowc(WCHAR* wc,CHAR* mb,INT32 size)
1256 int ret;
1258 if (!mb)
1259 ret = 0;
1260 else if (!wc)
1261 ret =-1;
1262 else
1263 if ( (ret = mblen(mb,size)) != -1 )
1265 if (ret <= sizeof(char))
1266 *wc = (WCHAR) ((unsigned char)*mb);
1267 else
1268 ret= -1;
1270 else
1271 ret = -1;
1273 dprintf_crtdll(stderr,"CRTDLL_mbtowc %s for %d chars\n",mb,size);
1275 return ret;
1278 /*********************************************************************
1279 * _isctype (CRTDLL.138)
1281 BOOL32 __cdecl CRTDLL__isctype(CHAR x,CHAR type)
1283 if ((type & CRTDLL_SPACE) && isspace(x))
1284 return TRUE;
1285 if ((type & CRTDLL_PUNCT) && ispunct(x))
1286 return TRUE;
1287 if ((type & CRTDLL_LOWER) && islower(x))
1288 return TRUE;
1289 if ((type & CRTDLL_UPPER) && isupper(x))
1290 return TRUE;
1291 if ((type & CRTDLL_ALPHA) && isalpha(x))
1292 return TRUE;
1293 if ((type & CRTDLL_DIGIT) && isdigit(x))
1294 return TRUE;
1295 if ((type & CRTDLL_CONTROL) && iscntrl(x))
1296 return TRUE;
1297 /* check CRTDLL_LEADBYTE */
1298 return FALSE;
1301 /*********************************************************************
1302 * _chdrive (CRTDLL.52)
1304 BOOL32 __cdecl CRTDLL__chdrive(INT32 newdrive)
1306 /* FIXME: generates errnos */
1307 return DRIVE_SetCurrentDrive(newdrive);
1310 /*********************************************************************
1311 * _chdir (CRTDLL.51)
1313 INT32 __cdecl CRTDLL__chdir(LPCSTR newdir)
1315 if (!SetCurrentDirectory32A(newdir))
1316 return -1;
1317 return 0;
1320 /*********************************************************************
1321 * _getcwd (CRTDLL.120)
1323 CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT32 size)
1325 DOS_FULL_NAME full_name;
1326 char *ret;
1328 dprintf_crtdll(stddeb,"CRTDLL_getcwd for buf %p size %d\n",
1329 buf,size);
1330 if (buf == NULL)
1332 dprintf_crtdll(stderr,"CRTDLL_getcwd malloc unsupported\n");
1333 printf("CRTDLL_getcwd malloc unsupported\n");
1334 return 0;
1336 ret = getcwd(buf,size);
1337 if (!DOSFS_GetFullName( buf, FALSE, &full_name ))
1339 dprintf_crtdll(stddeb,"CRTDLL_getcwd failed\n");
1340 return 0;
1342 if (strlen(full_name.short_name)>size)
1344 dprintf_crtdll(stddeb,"CRTDLL_getcwd string too long\n");
1345 return 0;
1347 ret=strcpy(buf,full_name.short_name);
1348 if (ret)
1349 dprintf_crtdll(stddeb,"CRTDLL_getcwd returned:%s\n",ret);
1350 return ret;
1353 /*********************************************************************
1354 * _mkdir (CRTDLL.234)
1356 INT32 __cdecl CRTDLL__mkdir(LPCSTR newdir)
1358 if (!CreateDirectory32A(newdir,NULL))
1359 return -1;
1360 return 0;
1363 /*********************************************************************
1364 * _errno (CRTDLL.52)
1365 * Yes, this is a function.
1367 LPINT32 __cdecl CRTDLL__errno()
1369 static int crtdllerrno;
1370 extern int LastErrorToErrno(DWORD);
1372 /* FIXME: we should set the error at the failing function call time */
1373 crtdllerrno = LastErrorToErrno(GetLastError());
1374 return &crtdllerrno;
1377 /*********************************************************************
1378 * _tempnam (CRTDLL.305)
1381 LPSTR __cdecl CRTDLL__tempnam(LPCSTR dir, LPCSTR prefix)
1384 char *ret;
1385 DOS_FULL_NAME tempname;
1387 if ((ret = tempnam(dir,prefix))==NULL) {
1388 dprintf_crtdll(stddeb,
1389 "CRTDLL_tempnam Unable to get unique filename\n");
1390 return NULL;
1392 if (!DOSFS_GetFullName(ret,FALSE,&tempname))
1394 dprintf_crtdll(stddeb,
1395 "CRTDLL_tempnam Wrong path?\n");
1396 return NULL;
1398 free(ret);
1399 if ((ret = CRTDLL_malloc(strlen(tempname.short_name)+1)) == NULL) {
1400 dprintf_crtdll(stddeb,
1401 "CRTDLL_tempnam CRTDL_malloc for shortname failed\n");
1402 return NULL;
1404 if ((ret = strcpy(ret,tempname.short_name)) == NULL) {
1405 dprintf_crtdll(stddeb,
1406 "CRTDLL_tempnam Malloc for shortname failed\n");
1407 return NULL;
1410 dprintf_crtdll(stddeb,"CRTDLL_tempnam dir %s prefix %s got %s\n",
1411 dir,prefix,ret);
1412 return ret;
1415 /*********************************************************************
1416 * tmpnam (CRTDLL.490)
1418 * lcclnk from lcc-win32 relies on a terminating dot in the name returned
1421 LPSTR __cdecl CRTDLL_tmpnam(LPSTR s)
1423 char *ret;
1425 if ((ret =tmpnam(s))== NULL) {
1426 dprintf_crtdll(stddeb,
1427 "CRTDLL_tmpnam Unable to get unique filename\n");
1428 return NULL;
1430 if (!DOSFS_GetFullName(ret,FALSE,&CRTDLL_tmpname))
1432 dprintf_crtdll(stddeb,
1433 "CRTDLL_tmpnam Wrong path?\n");
1434 return NULL;
1436 strcat(CRTDLL_tmpname.short_name,".");
1437 dprintf_crtdll(stddeb,"CRTDLL_tmpnam for buf %p got %s\n",
1438 s,CRTDLL_tmpname.short_name);
1439 dprintf_crtdll(stddeb,"CRTDLL_tmpnam long got %s\n",
1440 CRTDLL_tmpname.long_name);
1441 if ( s != NULL)
1442 return strcpy(s,CRTDLL_tmpname.short_name);
1443 else
1444 return CRTDLL_tmpname.short_name;
1448 /*********************************************************************
1449 * _itoa (CRTDLL.165)
1451 LPSTR __cdecl CRTDLL__itoa(INT32 x,LPSTR buf,INT32 buflen)
1453 wsnprintf32A(buf,buflen,"%d",x);
1454 return buf;