Fix for deadlock when using private colormap.
[wine] / dlls / crtdll / crtdll_main.c
index 99efa78..10c1e1c 100644 (file)
 /*
- * The C RunTime DLL
- * 
- * Implements C run-time functionality as known from UNIX.
+ * Old C RunTime DLL - All functionality is provided by msvcrt.
  *
- * Copyright 1996,1998 Marcus Meissner
- * Copyright 1996 Jukka Iivonen
- * Copyright 1997 Uwe Bonnes
- */
-
-/*
-Unresolved issues Uwe Bonnes 970904:
-- Handling of Binary/Text Files is crude. If in doubt, use fromdos or recode
-- Arguments in crtdll.spec for functions with double argument
-- system-call calls another wine process, but without debugging arguments
-              and uses the first wine executable in the path
-- tested with ftp://ftp.remcomp.com/pub/remcomp/lcc-win32.zip, a C-Compiler
-               for Win32, based on lcc, from Jacob Navia
-AJ 990101:
-- needs a proper stdio emulation based on Win32 file handles
-- should set CRTDLL errno from GetLastError() in every function
-*/
-
-/* NOTE: This file also implements the wcs* functions. They _ARE_ in 
- * the newer Linux libcs, but use 4 byte wide characters, so are unusable,
- * since we need 2 byte wide characters. - Marcus Meissner, 981031
+ * Copyright 2000 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "config.h"
 
-#include <errno.h>
-#include <stdlib.h>
 #include <stdarg.h>
-#include <string.h>
 #include <sys/stat.h>
-#include <sys/times.h>
-#include <unistd.h>
-#include <time.h>
-#include <ctype.h>
-#include <math.h>
-#include <fcntl.h>
-#include <setjmp.h>
-#include "winbase.h"
-#include "winuser.h"
-#include "winerror.h"
-#include "ntddk.h"
-#include "debugtools.h"
-#include "module.h"
-#include "heap.h"
-#include "crtdll.h"
-#include "drive.h"
-#include "file.h"
-#include "options.h"
-#include "winnls.h"
-
-DEFAULT_DEBUG_CHANNEL(crtdll)
-
-/* windows.h RAND_MAX is smaller than normal RAND_MAX */
-#define CRTDLL_RAND_MAX         0x7fff 
-
-static DOS_FULL_NAME CRTDLL_tmpname;
-
-UINT CRTDLL_argc_dll;         /* CRTDLL.23 */
-LPSTR *CRTDLL_argv_dll;         /* CRTDLL.24 */
-LPSTR  CRTDLL_acmdln_dll;       /* CRTDLL.38 */
-UINT CRTDLL_basemajor_dll;    /* CRTDLL.42 */
-UINT CRTDLL_baseminor_dll;    /* CRTDLL.43 */
-UINT CRTDLL_baseversion_dll;  /* CRTDLL.44 */
-UINT CRTDLL_commode_dll;      /* CRTDLL.59 */
-LPSTR  CRTDLL_environ_dll;      /* CRTDLL.75 */
-UINT CRTDLL_fmode_dll;        /* CRTDLL.104 */
-UINT CRTDLL_osmajor_dll;      /* CRTDLL.241 */
-UINT CRTDLL_osminor_dll;      /* CRTDLL.242 */
-UINT CRTDLL_osmode_dll;       /* CRTDLL.243 */
-UINT CRTDLL_osver_dll;        /* CRTDLL.244 */
-UINT CRTDLL_osversion_dll;    /* CRTDLL.245 */
-UINT CRTDLL_winmajor_dll;     /* CRTDLL.329 */
-UINT CRTDLL_winminor_dll;     /* CRTDLL.330 */
-UINT CRTDLL_winver_dll;       /* CRTDLL.331 */
-
-/* FIXME: structure layout is obviously not correct */
-typedef struct
-{
-    HANDLE handle;
-    int      pad[7];
-} CRTDLL_FILE;
-
-CRTDLL_FILE CRTDLL_iob[3];
-
-static CRTDLL_FILE * const CRTDLL_stdin  = &CRTDLL_iob[0];
-static CRTDLL_FILE * const CRTDLL_stdout = &CRTDLL_iob[1];
-static CRTDLL_FILE * const CRTDLL_stderr = &CRTDLL_iob[2];
-
-typedef VOID (*new_handler_type)(VOID);
-
-static new_handler_type new_handler;
-
-#if defined(__GNUC__) && defined(__i386__)
-#define USING_REAL_FPU
-#define DO_FPU(x,y) __asm__ __volatile__( x " %0;fwait" : "=m" (y) : )
-#define POP_FPU(x) DO_FPU("fstpl",x)
-#endif
-
-CRTDLL_FILE * __cdecl CRTDLL__fdopen(INT handle, LPCSTR mode);
-
-/*********************************************************************
- *                  CRTDLL_MainInit  (CRTDLL.init)
- */
-BOOL WINAPI CRTDLL_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
-       TRACE("(0x%08x,%ld,%p)\n",hinstDLL,fdwReason,lpvReserved);
-
-       if (fdwReason == DLL_PROCESS_ATTACH) {
-               CRTDLL__fdopen(0,"r");
-               CRTDLL__fdopen(1,"w");
-               CRTDLL__fdopen(2,"w");
-       }
-       return TRUE;
-}
-
-/*********************************************************************
- *                  _GetMainArgs  (CRTDLL.022)
- */
-DWORD __cdecl CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,
-                                LPSTR *environ,DWORD flag)
-{
-        char *cmdline;
-        char  **xargv;
-       int     xargc,i,afterlastspace;
-       DWORD   version;
-
-       TRACE("(%p,%p,%p,%ld).\n",
-               argc,argv,environ,flag
-       );
-       CRTDLL_acmdln_dll = cmdline = HEAP_strdupA( GetProcessHeap(), 0,
-                                                    GetCommandLineA() );
-       TRACE("got '%s'\n", cmdline);
-
-       version = GetVersion();
-       CRTDLL_osver_dll       = version >> 16;
-       CRTDLL_winminor_dll    = version & 0xFF;
-       CRTDLL_winmajor_dll    = (version>>8) & 0xFF;
-       CRTDLL_baseversion_dll = version >> 16;
-       CRTDLL_winver_dll      = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
-       CRTDLL_baseminor_dll   = (version >> 16) & 0xFF;
-       CRTDLL_basemajor_dll   = (version >> 24) & 0xFF;
-       CRTDLL_osversion_dll   = version & 0xFFFF;
-       CRTDLL_osminor_dll     = version & 0xFF;
-       CRTDLL_osmajor_dll     = (version>>8) & 0xFF;
 
-       /* missing threading init */
-
-       i=0;xargv=NULL;xargc=0;afterlastspace=0;
-       while (cmdline[i]) {
-               if (cmdline[i]==' ') {
-                       xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
-                                                   sizeof(char*)*(++xargc));
-                       cmdline[i]='\0';
-                       xargv[xargc-1] = HEAP_strdupA( GetProcessHeap(), 0,
-                                                       cmdline+afterlastspace);
-                       i++;
-                       while (cmdline[i]==' ')
-                               i++;
-                       if (cmdline[i])
-                               afterlastspace=i;
-               } else
-                       i++;
-       }
-       xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
-                                   sizeof(char*)*(++xargc));
-       cmdline[i]='\0';
-       xargv[xargc-1] = HEAP_strdupA( GetProcessHeap(), 0,
-                                       cmdline+afterlastspace);
-       CRTDLL_argc_dll = xargc;
-       *argc           = xargc;
-       CRTDLL_argv_dll = xargv;
-       *argv           = xargv;
-
-       TRACE("found %d arguments\n",
-               CRTDLL_argc_dll);
-       CRTDLL_environ_dll = *environ = GetEnvironmentStringsA();
-       return 0;
-}
-
-
-typedef void (*_INITTERMFUN)();
+#include "windef.h"
+#include "winbase.h"
 
-/* fixme: move to header */
-struct find_t 
-{   unsigned   attrib;
-    time_t     time_create;    /* -1 when not avaiable */
-    time_t     time_access;    /* -1 when not avaiable */
-    time_t     time_write;
-    unsigned long      size;   /* fixme: 64 bit ??*/
-    char       name[260];
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crtdll);
+
+/* from msvcrt */
+extern void __getmainargs( int *argc, char ***argv, char ***envp,
+                           int expand_wildcards, int *new_mode );
+
+/* The following data items are not exported from msvcrt */
+unsigned int CRTDLL__basemajor_dll;
+unsigned int CRTDLL__baseminor_dll;
+unsigned int CRTDLL__baseversion_dll;
+unsigned int CRTDLL__cpumode_dll;
+unsigned int CRTDLL__osmajor_dll;
+unsigned int CRTDLL__osminor_dll;
+unsigned int CRTDLL__osmode_dll;
+unsigned int CRTDLL__osversion_dll;
+
+/* dev_t is a short in crtdll but an unsigned int in msvcrt */
+typedef short crtdll_dev_t;
+
+struct crtdll_stat
+{
+  crtdll_dev_t   st_dev;
+  _ino_t         st_ino;
+  unsigned short st_mode;
+  short          st_nlink;
+  short          st_uid;
+  short          st_gid;
+  crtdll_dev_t   st_rdev;
+  _off_t         st_size;
+  time_t         st_atime;
+  time_t         st_mtime;
+  time_t         st_ctime;
 };
- /*********************************************************************
- *                  _findfirst    (CRTDLL.099)
- * 
- * BUGS
- *   Unimplemented
- */
-DWORD __cdecl CRTDLL__findfirst(LPCSTR fname,  struct find_t * x2)
-{
-  FIXME(":(%s,%p): stub\n",fname,x2);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/*********************************************************************
- *                  _findnext     (CRTDLL.100)
- * 
- * BUGS
- *   Unimplemented
- */
-INT __cdecl CRTDLL__findnext(DWORD hand, struct find_t * x2)
-{
-  FIXME(":(%ld,%p): stub\n",hand,x2);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/*********************************************************************
- *                  _fstat        (CRTDLL.111)
- * 
- * BUGS
- *   Unimplemented
- */
-int __cdecl CRTDLL__fstat(int file, struct stat* buf)
-{
-  FIXME(":(%d,%p): stub\n",file,buf);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/*********************************************************************
- *                  _initterm     (CRTDLL.135)
- */
-DWORD __cdecl CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
-{
-       _INITTERMFUN    *current;
-
-       TRACE("(%p,%p)\n",start,end);
-       current=start;
-       while (current<end) {
-               if (*current) (*current)();
-               current++;
-       }
-       return 0;
-}
-
-CRTDLL_FILE * __cdecl CRTDLL__fsopen(LPCSTR x, LPCSTR y, INT z) {
-       FIXME("(%s,%s,%d),stub!\n",x,y,z);
-       return NULL;
-}
-/*********************************************************************
- *                  _fdopen     (CRTDLL.91)
- */
-CRTDLL_FILE * __cdecl CRTDLL__fdopen(INT handle, LPCSTR mode)
-{
-    CRTDLL_FILE *file;
-
-    switch (handle) 
-    {
-    case 0:
-        file = CRTDLL_stdin;
-        if (!file->handle) file->handle = GetStdHandle( STD_INPUT_HANDLE );
-        break;
-    case 1:
-        file = CRTDLL_stdout;
-        if (!file->handle) file->handle = GetStdHandle( STD_OUTPUT_HANDLE );
-        break;
-    case 2:
-        file=CRTDLL_stderr;
-        if (!file->handle) file->handle = GetStdHandle( STD_ERROR_HANDLE );
-        break;
-    default:
-        file = HeapAlloc( GetProcessHeap(), 0, sizeof(*file) );
-        file->handle = handle;
-        break;
-    }
-  TRACE("open handle %d mode %s  got file %p\n",
-              handle, mode, file);
-  return file;
-}
 
-
-/*******************************************************************
- *         _global_unwind2  (CRTDLL.129)
- */
-void __cdecl CRTDLL__global_unwind2( PEXCEPTION_FRAME frame )
+/* convert struct _stat from crtdll format to msvcrt format */
+static void convert_struct_stat( struct crtdll_stat *dst, const struct _stat *src )
 {
-    RtlUnwind( frame, 0, NULL, 0 );
+    dst->st_dev   = src->st_dev;
+    dst->st_ino   = src->st_ino;
+    dst->st_mode  = src->st_mode;
+    dst->st_nlink = src->st_nlink;
+    dst->st_uid   = src->st_uid;
+    dst->st_gid   = src->st_gid;
+    dst->st_rdev  = src->st_rdev;
+    dst->st_size  = src->st_size;
+    dst->st_atime = src->st_atime;
+    dst->st_mtime = src->st_mtime;
+    dst->st_ctime = src->st_ctime;
 }
 
-/*******************************************************************
- *         _local_unwind2  (CRTDLL.173)
- */
-void __cdecl CRTDLL__local_unwind2( PEXCEPTION_FRAME endframe, DWORD nr )
-{
-    TRACE("(%p,%ld)\n",endframe,nr);
-}
-/*********************************************************************
- *                  _read     (CRTDLL.256)
- * 
- * BUGS
- *   Unimplemented
- */
-INT __cdecl CRTDLL__read(INT fd, LPVOID buf, UINT count)
-{
-  FIXME(":(%d,%p,%d): stub\n",fd,buf,count);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
 
 /*********************************************************************
- *                  fopen     (CRTDLL.372)
+ *                  DllMain  (CRTDLL.init)
  */
-CRTDLL_FILE * __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
 {
-  CRTDLL_FILE *file = NULL;
-  HFILE handle;
-#if 0
-  DOS_FULL_NAME full_name;
-  
-  if (!DOSFS_GetFullName( path, FALSE, &full_name )) {
-    WARN("file %s bad name\n",path);
-   return 0;
-  }
-  
-  file=fopen(full_name.long_name ,mode);
-#endif
-  DWORD access = 0, creation = 0;
-
-  if ((strchr(mode,'r')&&strchr(mode,'a'))||
-      (strchr(mode,'r')&&strchr(mode,'w'))||
-      (strchr(mode,'w')&&strchr(mode,'a')))
-    return NULL;
-       
-  if (mode[0] == 'r')
-  {
-      access = GENERIC_READ;
-      creation = OPEN_EXISTING;
-      if (mode[1] == '+') access |= GENERIC_WRITE;
-  }
-  else if (mode[0] == 'w')
-  {
-      access = GENERIC_WRITE;
-      creation = CREATE_ALWAYS;
-      if (mode[1] == '+') access |= GENERIC_READ;
-  }
-  else if (mode[0] == 'a')
-  {
-      /* FIXME: there is no O_APPEND in CreateFile, should emulate it */
-      access = GENERIC_WRITE;
-      creation = OPEN_ALWAYS;
-      if (mode[1] == '+') access |= GENERIC_READ;
-  }
-  /* FIXME: should handle text/binary mode */
+  TRACE("(%p,%ld,%p)\n",hinstDLL,fdwReason,lpvReserved);
 
-  if ((handle = CreateFileA( path, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
-                               NULL, creation, FILE_ATTRIBUTE_NORMAL,
-                               -1 )) != INVALID_HANDLE_VALUE)
+  if (fdwReason == DLL_PROCESS_ATTACH)
   {
-      file = HeapAlloc( GetProcessHeap(), 0, sizeof(*file) );
-      file->handle = handle;
-  }
-  TRACE("file %s mode %s got handle %d file %p\n",
-                path,mode,handle,file);
-  return file;
-}
-
-/*********************************************************************
- *                  fread     (CRTDLL.377)
- */
-DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT size, INT nmemb, CRTDLL_FILE *file)
-{
-#if 0
-  int i=0;
-  void *temp=ptr;
-
-  /* If we would honour CR/LF <-> LF translation, we could do it like this.
-     We should keep track of all files opened, and probably files with \
-     known binary extensions must be unchanged */
-  while ( (i < (nmemb*size)) && (ret==1)) {
-    ret=fread(temp,1,1,file);
-    TRACE("got %c 0x%02x ret %d\n",
-                (isalpha(*(unsigned char*)temp))? *(unsigned char*)temp:
-                ' ',*(unsigned char*)temp, ret);
-    if (*(unsigned char*)temp != 0xd) { /* skip CR */
-      temp++;
-      i++;
-    }
-    else
-      TRACE("skipping ^M\n");
+    DWORD version = GetVersion();
+
+    DisableThreadLibraryCalls(hinstDLL);
+
+    CRTDLL__basemajor_dll   = (version >> 24) & 0xFF;
+    CRTDLL__baseminor_dll   = (version >> 16) & 0xFF;
+    CRTDLL__baseversion_dll = (version >> 16);
+    CRTDLL__cpumode_dll     = 1; /* FIXME */
+    CRTDLL__osmajor_dll     = (version>>8) & 0xFF;
+    CRTDLL__osminor_dll     = (version & 0xFF);
+    CRTDLL__osmode_dll      = 1; /* FIXME */
+    CRTDLL__osversion_dll   = (version & 0xFFFF);
   }
-  TRACE("0x%08x items of size %d from file %p to %p\n",
-              nmemb,size,file,ptr,);
-  if(i!=nmemb)
-    WARN(" failed!\n");
-
-  return i;
-#else
-  DWORD ret;
-
-  TRACE("0x%08x items of size %d from file %p to %p\n",
-              nmemb,size,file,ptr);
-  if (!ReadFile( file->handle, ptr, size * nmemb, &ret, NULL ))
-      WARN(" failed!\n");
-
-  return ret / size;
-#endif
-}
-/*********************************************************************
- *                  freopen    (CRTDLL.379)
- * 
- * BUGS
- *   Unimplemented
- */
-DWORD __cdecl CRTDLL_freopen(LPCSTR path, LPCSTR mode, LPVOID stream)
-{
-  FIXME(":(%s,%s,%p): stub\n", path, mode, stream);
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-}
-
-/*********************************************************************
- *                  fscanf     (CRTDLL.381)
- */
-INT __cdecl CRTDLL_fscanf( CRTDLL_FILE *stream, LPSTR format, ... )
-{
-#if 0
-    va_list valist;
-    INT res;
-
-    va_start( valist, format );
-#ifdef HAVE_VFSCANF
-    res = vfscanf( xlat_file_ptr(stream), format, valist );
-#endif
-    va_end( valist );
-    return res;
-#endif
-    FIXME("broken\n");
-    return 0;
-}
-
-/*********************************************************************
- *                  fseek     (CRTDLL.382)
- */
-LONG __cdecl CRTDLL_fseek( CRTDLL_FILE *file, LONG offset, INT whence)
-{
-  TRACE("file %p to 0x%08lx pos %s\n",
-        file,offset,(whence==SEEK_SET)?"SEEK_SET":
-        (whence==SEEK_CUR)?"SEEK_CUR":
-        (whence==SEEK_END)?"SEEK_END":"UNKNOWN");
-  if (SetFilePointer( file->handle, offset, NULL, whence ) != 0xffffffff)
-      return 0;
-  WARN(" failed!\n");
-  return -1;
-}
-  
-/*********************************************************************
- *                  fsetpos     (CRTDLL.383)
- */
-INT __cdecl CRTDLL_fsetpos( CRTDLL_FILE *file, INT *pos )
-{
-    TRACE("file %p pos %d\n", file, *pos );
-    return CRTDLL_fseek(file, *pos, SEEK_SET);
-}
-
-/*********************************************************************
- *                  ftell     (CRTDLL.384)
- */
-LONG __cdecl CRTDLL_ftell( CRTDLL_FILE *file )
-{
-    return SetFilePointer( file->handle, 0, NULL, SEEK_CUR );
-}
-  
-/*********************************************************************
- *                  fwrite     (CRTDLL.386)
- */
-DWORD __cdecl CRTDLL_fwrite( LPVOID ptr, INT size, INT nmemb, CRTDLL_FILE *file )
-{
-    DWORD ret;
-
-    TRACE("0x%08x items of size %d to file %p(%d) from %p\n",
-          nmemb,size,file,file-(CRTDLL_FILE*)CRTDLL_iob,ptr);
-       
-    
-    if (!WriteFile( file->handle, ptr, size * nmemb, &ret, NULL ))
-        WARN(" failed!\n");
-    return ret / size;
-}
-
-/*********************************************************************
- *                  setbuf     (CRTDLL.452)
- */
-INT __cdecl CRTDLL_setbuf(CRTDLL_FILE *file, LPSTR buf)
-{
-  TRACE("(file %p buf %p)\n", file, buf);
-  /* this doesn't work:"void value not ignored as it ought to be" 
-  return setbuf(file,buf); 
-  */
-  /* FIXME: no buffering for now */
-  return 0;
-}
-
-/*********************************************************************
- *                  _open_osfhandle         (CRTDLL.240)
- */
-HFILE __cdecl CRTDLL__open_osfhandle(LONG osfhandle, INT flags)
-{
-HFILE handle;
-       switch (osfhandle) {
-       case STD_INPUT_HANDLE :
-       case 0 :
-         handle=0;
-         break;
-       case STD_OUTPUT_HANDLE:
-       case 1:
-         handle=1;
-         break;
-       case STD_ERROR_HANDLE:
-       case 2:
-         handle=2;
-         break;
-       default:
-         return (-1);
-       }
-       TRACE("(handle %08lx,flags %d) return %d\n",
-                    osfhandle,flags,handle);
-       return handle;
-       
-}
-
-/*********************************************************************
- *                  srand         (CRTDLL.460)
- */
-void __cdecl CRTDLL_srand(DWORD seed)
-{
-       /* FIXME: should of course be thread? process? local */
-       srand(seed);
-}
-
-/*********************************************************************
- *                  vfprintf       (CRTDLL.373)
- */
-INT __cdecl CRTDLL_vfprintf( CRTDLL_FILE *file, LPSTR format, va_list args )
-{
-    char buffer[2048];  /* FIXME... */
-
-    vsprintf( buffer, format, args );
-    return CRTDLL_fwrite( buffer, 1, strlen(buffer), file );
-}
-
-/*********************************************************************
- *                  fprintf       (CRTDLL.373)
- */
-INT __cdecl CRTDLL_fprintf( CRTDLL_FILE *file, LPSTR format, ... )
-{
-    va_list valist;
-    INT res;
-
-    va_start( valist, format );
-    res = CRTDLL_vfprintf( file, format, valist );
-    va_end( valist );
-    return res;
-}
-
-/*********************************************************************
- *                  time          (CRTDLL.488)
- */
-time_t __cdecl CRTDLL_time(time_t *timeptr)
-{
-       time_t  curtime = time(NULL);
-
-       if (timeptr)
-               *timeptr = curtime;
-       return curtime;
-}
-
-/*********************************************************************
- *                            (CRTDLL.350)
- */
-clock_t __cdecl CRTDLL_clock(void)
-{
-       struct tms alltimes;
-       clock_t res;
-
-       times(&alltimes);
-       res = alltimes.tms_utime + alltimes.tms_stime+
-               alltimes.tms_cutime + alltimes.tms_cstime;
-       /* Fixme: We need some symbolic representation
-          for (Hostsystem_)CLOCKS_PER_SEC 
-          and (Emulated_system_)CLOCKS_PER_SEC
-          10 holds only for Windows/Linux_i86)
-          */
-       return 10*res;
-}
-
-/*********************************************************************
- *                  _isatty       (CRTDLL.137)
- */
-BOOL __cdecl CRTDLL__isatty(DWORD x)
-{
-       TRACE("(%ld)\n",x);
-       return TRUE;
-}
-
-/*********************************************************************
- *                  _write        (CRTDLL.332)
- */
-INT __cdecl CRTDLL__write(INT fd,LPCVOID buf,UINT count)
-{
-        INT len=0;
-
-       if (fd == -1)
-         len = -1;
-       else if (fd<=2)
-         len = (UINT)write(fd,buf,(LONG)count);
-       else
-         len = _lwrite(fd,buf,count);
-       TRACE("%d/%d byte to dfh %d from %p,\n",
-                      len,count,fd,buf);
-       return len;
-}
-
-
-/*********************************************************************
- *                  _cexit          (CRTDLL.49)
- *
- *  FIXME: What the heck is the difference between 
- *  FIXME           _c_exit         (CRTDLL.47)
- *  FIXME           _cexit          (CRTDLL.49)
- *  FIXME           _exit           (CRTDLL.87)
- *  FIXME           exit            (CRTDLL.359)
- *
- * atexit-processing comes to mind -- MW.
- *
- */
-void __cdecl CRTDLL__cexit(INT ret)
-{
-        TRACE("(%d)\n",ret);
-       ExitProcess(ret);
-}
-
-
-/*********************************************************************
- *                  exit          (CRTDLL.359)
- */
-void __cdecl CRTDLL_exit(DWORD ret)
-{
-        TRACE("(%ld)\n",ret);
-       ExitProcess(ret);
-}
-
-
-/*********************************************************************
- *                  _abnormal_termination          (CRTDLL.36)
- */
-INT __cdecl CRTDLL__abnormal_termination(void)
-{
-        TRACE("(void)\n");
-       return 0;
-}
-
-
-/*********************************************************************
- *                  _access          (CRTDLL.37)
- */
-INT __cdecl CRTDLL__access(LPCSTR filename, INT mode)
-{
-    DWORD attr = GetFileAttributesA(filename);
-
-    if (attr == -1)
-    {
-        if (GetLastError() == ERROR_INVALID_ACCESS)
-            errno = EACCES;
-        else
-            errno = ENOENT;
-        return -1;
-    }
-
-    if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & W_OK))
-    {
-        errno = EACCES;
-        return -1;
-    }
-    else
-        return 0;
-}
-
-
-/*********************************************************************
- *                  fflush        (CRTDLL.365)
- */
-INT __cdecl CRTDLL_fflush( CRTDLL_FILE *file )
-{
-    return FlushFileBuffers( file->handle ) ? 0 : -1;
-}
-
-
-/*********************************************************************
- *                  rand          (CRTDLL.446)
- */
-INT __cdecl CRTDLL_rand()
-{
-    return (rand() & CRTDLL_RAND_MAX); 
-}
-
-
-/*********************************************************************
- *                  putchar       (CRTDLL.442)
- */
-void __cdecl CRTDLL_putchar( INT x )
-{
-    putchar(x);
+  return TRUE;
 }
 
 
 /*********************************************************************
- *                  fputc       (CRTDLL.374)
+ *                  __GetMainArgs  (CRTDLL.@)
  */
-INT __cdecl CRTDLL_fputc( INT c, CRTDLL_FILE *file )
+void __GetMainArgs( int *argc, char ***argv, char ***envp, int expand_wildcards )
 {
-    char ch = (char)c;
-    DWORD res;
-    TRACE("%c to file %p\n",c,file);
-    if (!WriteFile( file->handle, &ch, 1, &res, NULL )) return -1;
-    return c;
+    int new_mode = 0;
+    __getmainargs( argc, argv, envp, expand_wildcards, &new_mode );
 }
 
 
 /*********************************************************************
- *                  fputs       (CRTDLL.375)
+ *             _fstat (CRTDLL.@)
  */
-INT __cdecl CRTDLL_fputs( LPCSTR s, CRTDLL_FILE *file )
+int CRTDLL__fstat(int fd, struct crtdll_stat* buf)
 {
-    DWORD res;
-    TRACE("%s to file %p\n",s,file);
-    if (!WriteFile( file->handle, s, strlen(s), &res, NULL )) return -1;
-    return res;
-}
+    extern int _fstat(int,struct _stat*);
+    struct _stat st;
+    int ret;
 
-
-/*********************************************************************
- *                  puts       (CRTDLL.443)
- */
-INT __cdecl CRTDLL_puts(LPCSTR s)
-{
-    TRACE("%s \n",s);
-    return puts(s);
+    if (!(ret = _fstat( fd, &st ))) convert_struct_stat( buf, &st );
+    return ret;
 }
 
 
 /*********************************************************************
- *                  putc       (CRTDLL.441)
- */
-INT __cdecl CRTDLL_putc( INT c, CRTDLL_FILE *file )
-{
-    return CRTDLL_fputc( c, file );
-}
-
-/*********************************************************************
- *                  fgetc       (CRTDLL.366)
+ *             _stat (CRTDLL.@)
  */
-INT __cdecl CRTDLL_fgetc( CRTDLL_FILE *file )
+int CRTDLL__stat(const char* path, struct crtdll_stat * buf)
 {
-    DWORD res;
-    char ch;
-    if (!ReadFile( file->handle, &ch, 1, &res, NULL )) return -1;
-    if (res != 1) return -1;
-    return ch;
-}
-
+    extern int _stat(const char*,struct _stat*);
+    struct _stat st;
+    int ret;
 
-/*********************************************************************
- *                  getc       (CRTDLL.388)
- */
-INT __cdecl CRTDLL_getc( CRTDLL_FILE *file )
-{
-    return CRTDLL_fgetc( file );
+    if (!(ret = _stat( path, &st ))) convert_struct_stat( buf, &st );
+    return ret;
 }
 
 
 /*********************************************************************
- *                  fgets       (CRTDLL.368)
+ *             _strdec (CRTDLL.@)
  */
-CHAR* __cdecl CRTDLL_fgets( LPSTR s, INT size, CRTDLL_FILE *file )
+char *_strdec(const char *str1, const char *str2)
 {
-    int    cc;
-    LPSTR  buf_start = s;
-
-    /* BAD, for the whole WINE process blocks... just done this way to test
-     * windows95's ftp.exe.
-     */
-
-    for(cc = CRTDLL_fgetc(file); cc != EOF && cc != '\n'; cc = CRTDLL_fgetc(file))
-       if (cc != '\r')
-        {
-            if (--size <= 0) break;
-            *s++ = (char)cc;
-        }
-
-    *s = '\0';
-
-    TRACE("got '%s'\n", buf_start);
-    return buf_start;
+    return (char *)(str2 - 1);
 }
 
 
 /*********************************************************************
- *                  gets          (CRTDLL.391)
+ *             _strinc (CRTDLL.@)
  */
-LPSTR __cdecl CRTDLL_gets(LPSTR buf)
+char *_strinc(const char *str)
 {
-    int    cc;
-    LPSTR  buf_start = buf;
-
-    /* BAD, for the whole WINE process blocks... just done this way to test
-     * windows95's ftp.exe.
-     */
-
-    for(cc = fgetc(stdin); cc != EOF && cc != '\n'; cc = fgetc(stdin))
-       if(cc != '\r') *buf++ = (char)cc;
-
-    *buf = '\0';
-
-    TRACE("got '%s'\n", buf_start);
-    return buf_start;
+    return (char *)(str + 1);
 }
 
 
 /*********************************************************************
- *                  _rotl          (CRTDLL.259)
- */
-UINT __cdecl CRTDLL__rotl(UINT x,INT shift)
-{
-   unsigned int ret = (x >> shift)|( x >>((sizeof(x))-shift));
-
-   TRACE("got 0x%08x rot %d ret 0x%08x\n",
-                 x,shift,ret);
-   return ret;
-    
-}
-/*********************************************************************
- *                  _lrotl          (CRTDLL.176)
+ *             _strncnt (CRTDLL.@)
  */
-DWORD __cdecl CRTDLL__lrotl(DWORD x,INT shift)
+size_t _strncnt(const char *str, size_t maxlen)
 {
-   unsigned long ret = (x >> shift)|( x >>((sizeof(x))-shift));
-
-   TRACE("got 0x%08lx rot %d ret 0x%08lx\n",
-                 x,shift,ret);
-   return ret;
-    
+    size_t len = strlen(str);
+    return (len > maxlen) ? maxlen : len;
 }
 
 
 /*********************************************************************
- *                  _mbsicmp      (CRTDLL.204)
+ *             _strnextc (CRTDLL.@)
  */
-int __cdecl CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
+unsigned int _strnextc(const char *str)
 {
-    do {
-       if (!*x)
-           return !!*y;
-       if (!*y)
-           return !!*x;
-       /* FIXME: MBCS handling... */
-       if (*x!=*y)
-           return 1;
-        x++;
-        y++;
-    } while (1);
+    return (unsigned int)str[0];
 }
 
 
 /*********************************************************************
- *                  vsprintf      (CRTDLL.500)
+ *             _strninc (CRTDLL.@)
  */
-INT __cdecl CRTDLL_vsprintf( LPSTR buffer, LPCSTR spec, va_list args )
+char *_strninc(const char *str, size_t len)
 {
-    return wvsprintfA( buffer, spec, args );
+    return (char *)(str + len);
 }
 
-/*********************************************************************
- *                  vswprintf      (CRTDLL.501)
- */
-INT __cdecl CRTDLL_vswprintf( LPWSTR buffer, LPCWSTR spec, va_list args )
-{
-    return wvsprintfW( buffer, spec, args );
-}
-
-/*********************************************************************
- *                  _strcmpi   (CRTDLL.282) (CRTDLL.287)
- */
-INT __cdecl CRTDLL__strcmpi( LPCSTR s1, LPCSTR s2 )
-{
-    return lstrcmpiA( s1, s2 );
-}
-
-
-/*********************************************************************
- *                  _strnicmp   (CRTDLL.293)
- */
-INT __cdecl CRTDLL__strnicmp( LPCSTR s1, LPCSTR s2, INT n )
-{
-    return lstrncmpiA( s1, s2, n );
-}
-
-
-/*********************************************************************
- *                  _strlwr      (CRTDLL.293)
- *
- * convert a string in place to lowercase 
- */
-LPSTR __cdecl CRTDLL__strlwr(LPSTR x)
-{
-  unsigned char *y =x;
-  
-  TRACE("CRTDLL_strlwr got %s\n", x);
-  while (*y) {
-    if ((*y > 0x40) && (*y< 0x5b))
-      *y = *y + 0x20;
-    y++;
-  }
-  TRACE("   returned %s\n", x);
-                
-  return x;
-}
-
-/*********************************************************************
- *                  system       (CRTDLL.485)
- */
-INT __cdecl CRTDLL_system(LPSTR x)
-{
-#define SYSBUF_LENGTH 1500
-  char buffer[SYSBUF_LENGTH];
-  unsigned char *y = x;
-  unsigned char *bp;
-  int i;
-
-  sprintf( buffer, "%s \"", Options.argv0 );
-  bp = buffer + strlen(buffer);
-  i = strlen(buffer) + strlen(x) +2;
-
-  /* Calculate needed buffer size to prevent overflow.  */
-  while (*y) {
-    if (*y =='\\') i++;
-    y++;
-  }
-  /* If buffer too short, exit.  */
-  if (i > SYSBUF_LENGTH) {
-    TRACE("_system buffer to small\n");
-    return 127;
-  }
-  
-  y =x;
-
-  while (*y) {
-    *bp = *y;
-    bp++; y++;
-    if (*(y-1) =='\\') *bp++ = '\\';
-  }
-  /* Remove spaces from end of string.  */
-  while (*(y-1) == ' ') {
-    bp--;y--;
-  }
-  *bp++ = '"';
-  *bp = 0;
-  TRACE("_system got '%s', executing '%s'\n",x,buffer);
-
-  return system(buffer);
-}
-
-/*********************************************************************
- *                  _strupr       (CRTDLL.300)
- */
-LPSTR __cdecl CRTDLL__strupr(LPSTR x)
-{
-       LPSTR   y=x;
-
-       while (*y) {
-               *y=toupper(*y);
-               y++;
-       }
-       return x;
-}
-
-/*********************************************************************
- *                  longjmp        (CRTDLL.426)
- */
-VOID __cdecl CRTDLL_longjmp(jmp_buf env, int val)
-{
-    FIXME("CRTDLL_longjmp semistup, expect crash\n");
-    longjmp(env, val);
-}
-
-/*********************************************************************
- *                  malloc        (CRTDLL.427)
- */
-VOID* __cdecl CRTDLL_malloc(DWORD size)
-{
-    return HeapAlloc(GetProcessHeap(),0,size);
-}
-
-/*********************************************************************
- *                  new           (CRTDLL.001)
- */
-VOID* __cdecl CRTDLL_new(DWORD size)
-{
-    VOID* result;
-    if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
-       (*new_handler)();
-    return result;
-}
-
-/*********************************************************************
- *                  set_new_handler(CRTDLL.003)
- */
-new_handler_type __cdecl CRTDLL_set_new_handler(new_handler_type func)
-{
-    new_handler_type old_handler = new_handler;
-    new_handler = func;
-    return old_handler;
-}
-
-/*********************************************************************
- *                  calloc        (CRTDLL.350)
- */
-VOID* __cdecl CRTDLL_calloc(DWORD size, DWORD count)
-{
-    return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
-}
-
-/*********************************************************************
- *                  realloc        (CRTDLL.447)
- */
-VOID* __cdecl CRTDLL_realloc( VOID *ptr, DWORD size )
-{
-    return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
-}
-
-/*********************************************************************
- *                  free          (CRTDLL.427)
- */
-VOID __cdecl CRTDLL_free(LPVOID ptr)
-{
-    HeapFree(GetProcessHeap(),0,ptr);
-}
-
-/*********************************************************************
- *                  delete       (CRTDLL.002)
- */
-VOID __cdecl CRTDLL_delete(VOID* ptr)
-{
-    HeapFree(GetProcessHeap(),0,ptr);
-}
-
-/*********************************************************************
- *                  _strdup          (CRTDLL.285)
- */
-LPSTR __cdecl CRTDLL__strdup(LPCSTR ptr)
-{
-    return HEAP_strdupA(GetProcessHeap(),0,ptr);
-}
-
-/*********************************************************************
- *                  fclose           (CRTDLL.362)
- */
-INT __cdecl CRTDLL_fclose( CRTDLL_FILE *file )
-{
-    TRACE("%p\n", file );
-    if (!CloseHandle( file->handle )) return -1;
-    HeapFree( GetProcessHeap(), 0, file );
-    return 0;
-}
-
-/*********************************************************************
- *                  _unlink           (CRTDLL.315)
- */
-INT __cdecl CRTDLL__unlink(LPCSTR pathname)
-{
-    int ret=0;
-    DOS_FULL_NAME full_name;
-
-    if (!DOSFS_GetFullName( pathname, FALSE, &full_name )) {
-      WARN("CRTDLL_unlink file %s bad name\n",pathname);
-      return EOF;
-    }
-  
-    ret=unlink(full_name.long_name);
-    TRACE("(%s unix %s)\n",
-                  pathname,full_name.long_name);
-    if(ret)
-      WARN(" Failed!\n");
-
-    return ret;
-}
-
-/*********************************************************************
- *                  rename           (CRTDLL.449)
- */
-INT __cdecl CRTDLL_rename(LPCSTR oldpath,LPCSTR newpath)
-{
-    BOOL ok = MoveFileExA( oldpath, newpath, MOVEFILE_REPLACE_EXISTING );
-    return ok ? 0 : -1;
-}
-
-
-/*********************************************************************
- *                  _stat          (CRTDLL.280)
- */
-
-struct win_stat
-{
-    UINT16 win_st_dev;
-    UINT16 win_st_ino;
-    UINT16 win_st_mode;
-    INT16  win_st_nlink;
-    INT16  win_st_uid;
-    INT16  win_st_gid;
-    UINT win_st_rdev;
-    INT  win_st_size;
-    INT  win_st_atime;
-    INT  win_st_mtime;
-    INT  win_st_ctime;
-};
-
-int __cdecl CRTDLL__stat(const char * filename, struct win_stat * buf)
-{
-    int ret=0;
-    DOS_FULL_NAME full_name;
-    struct stat mystat;
-
-    if (!DOSFS_GetFullName( filename, TRUE, &full_name ))
-    {
-      WARN("CRTDLL__stat filename %s bad name\n",filename);
-      return -1;
-    }
-    ret=stat(full_name.long_name,&mystat);
-    TRACE("CRTDLL__stat %s\n", filename);
-    if(ret) 
-      WARN(" Failed!\n");
-
-    /* FIXME: should check what Windows returns */
-
-    buf->win_st_dev   = mystat.st_dev;
-    buf->win_st_ino   = mystat.st_ino;
-    buf->win_st_mode  = mystat.st_mode;
-    buf->win_st_nlink = mystat.st_nlink;
-    buf->win_st_uid   = mystat.st_uid;
-    buf->win_st_gid   = mystat.st_gid;
-    buf->win_st_rdev  = mystat.st_rdev;
-    buf->win_st_size  = mystat.st_size;
-    buf->win_st_atime = mystat.st_atime;
-    buf->win_st_mtime = mystat.st_mtime;
-    buf->win_st_ctime = mystat.st_ctime;
-    return ret;
-}
-
-/*********************************************************************
- *                  _open           (CRTDLL.239)
- */
-HFILE __cdecl CRTDLL__open(LPCSTR path,INT flags)
-{
-    DWORD access = 0, creation = 0;
-    HFILE ret;
-    
-    /* FIXME:
-       the flags in lcc's header differ from the ones in Linux, e.g.
-       Linux: define O_APPEND         02000   (= 0x400)
-       lcc:  define _O_APPEND       0x0008  
-       so here a scheme to translate them
-       Probably lcc is wrong here, but at least a hack to get is going
-       */
-    switch(flags & 3)
-    {
-    case O_RDONLY: access |= GENERIC_READ; break;
-    case O_WRONLY: access |= GENERIC_WRITE; break;
-    case O_RDWR:   access |= GENERIC_WRITE | GENERIC_READ; break;
-    }
-
-    if (flags & 0x0100) /* O_CREAT */
-    {
-        if (flags & 0x0400) /* O_EXCL */
-            creation = CREATE_NEW;
-        else if (flags & 0x0200) /* O_TRUNC */
-            creation = CREATE_ALWAYS;
-        else
-            creation = OPEN_ALWAYS;
-    }
-    else  /* no O_CREAT */
-    {
-        if (flags & 0x0200) /* O_TRUNC */
-            creation = TRUNCATE_EXISTING;
-        else
-            creation = OPEN_EXISTING;
-    }
-    if (flags & 0x0008) /* O_APPEND */
-        FIXME("O_APPEND not supported\n" );
-    if (flags & 0xf0f4) 
-      TRACE("CRTDLL_open file unsupported flags 0x%04x\n",flags);
-    /* End Fixme */
-
-    ret = CreateFileA( path, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
-                         NULL, creation, FILE_ATTRIBUTE_NORMAL, -1 );
-    TRACE("CRTDLL_open file %s mode 0x%04x got handle %d\n", path,flags,ret);
-    return ret;
-}
-
-/*********************************************************************
- *                  _close           (CRTDLL.57)
- */
-INT __cdecl CRTDLL__close(HFILE fd)
-{
-    int ret=_lclose(fd);
-
-    TRACE("(%d)\n",fd);
-    if(ret)
-      WARN(" Failed!\n");
-
-    return ret;
-}
-
-/*********************************************************************
- *                  feof           (CRTDLL.363)
- */
-INT __cdecl CRTDLL_feof( CRTDLL_FILE *file )
-{
-    FIXME("stub\n" );
-    return 0;
-}
-
-/*********************************************************************
- *                  setlocale           (CRTDLL.453)
- */
-LPSTR __cdecl CRTDLL_setlocale(INT category,LPCSTR locale)
-{
-       LPSTR categorystr;
-
-       switch (category) {
-       case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
-       case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
-       case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
-       case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
-       case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
-       case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
-       default: categorystr = "UNKNOWN?";break;
-       }
-       FIXME("(%s,%s),stub!\n",categorystr,locale);
-       return "C";
-}
-
-/*********************************************************************
- *                  _setmode           (CRTDLL.265)
- * FIXME: At present we ignore the request to translate CR/LF to LF.
- *
- * We allways translate when we read with fgets, we never do with fread
- *
- */
-INT __cdecl CRTDLL__setmode( INT fh,INT mode)
-{
-       /* FIXME */
-#define O_TEXT     0x4000
-#define O_BINARY   0x8000
-
-       FIXME("on fhandle %d mode %s, STUB.\n",
-                     fh,(mode=O_TEXT)?"O_TEXT":
-                     (mode=O_BINARY)?"O_BINARY":"UNKNOWN");
-       return -1;
-}
-
-/*********************************************************************
- *                  _fpreset           (CRTDLL.107)
- */
-VOID __cdecl CRTDLL__fpreset(void)
-{
-       FIXME(" STUB.\n");
-}
-
-/*********************************************************************
- *                  atexit           (CRTDLL.345)
- */
-INT __cdecl CRTDLL_atexit(LPVOID x)
-{
-       FIXME("(%p), STUB.\n",x);
-       return 0; /* successful */
-}
-
-/*********************************************************************
- *                  _isctype           (CRTDLL.138)
- */
-BOOL __cdecl CRTDLL__isctype(CHAR x,CHAR type)
-{
-       if ((type & CRTDLL_SPACE) && isspace(x))
-               return TRUE;
-       if ((type & CRTDLL_PUNCT) && ispunct(x))
-               return TRUE;
-       if ((type & CRTDLL_LOWER) && islower(x))
-               return TRUE;
-       if ((type & CRTDLL_UPPER) && isupper(x))
-               return TRUE;
-       if ((type & CRTDLL_ALPHA) && isalpha(x))
-               return TRUE;
-       if ((type & CRTDLL_DIGIT) && isdigit(x))
-               return TRUE;
-       if ((type & CRTDLL_CONTROL) && iscntrl(x))
-               return TRUE;
-       /* check CRTDLL_LEADBYTE */
-       return FALSE;
-}
-
-/*********************************************************************
- *                  _chdrive           (CRTDLL.52)
- *
- *  newdir      [I] drive to change to, A=1
- *
- */
-BOOL __cdecl CRTDLL__chdrive(INT newdrive)
-{
-       /* FIXME: generates errnos */
-       return DRIVE_SetCurrentDrive(newdrive-1);
-}
-
-/*********************************************************************
- *                  _chdir           (CRTDLL.51)
- */
-INT __cdecl CRTDLL__chdir(LPCSTR newdir)
-{
-       if (!SetCurrentDirectoryA(newdir))
-               return 1;
-       return 0;
-}
-
-/*********************************************************************
- *                  _fullpath           (CRTDLL.114)
- */
-LPSTR __cdecl CRTDLL__fullpath(LPSTR buf, LPCSTR name, INT size)
-{
-  DOS_FULL_NAME full_name;
-
-  if (!buf)
-  {
-      size = 256;
-      if(!(buf = CRTDLL_malloc(size))) return NULL;
-  }
-  if (!DOSFS_GetFullName( name, FALSE, &full_name )) return NULL;
-  lstrcpynA(buf,full_name.short_name,size);
-  TRACE("CRTDLL_fullpath got %s\n",buf);
-  return buf;
-}
-
-/*********************************************************************
- *                  _splitpath           (CRTDLL.279)
- */
-VOID __cdecl CRTDLL__splitpath(LPCSTR path, LPSTR drive, LPSTR directory, LPSTR filename, LPSTR extension )
-{
-  /* drive includes :
-     directory includes leading and trailing (forward and backward slashes)
-     filename without dot and slashes
-     extension with leading dot
-     */
-  char * drivechar,*dirchar,*namechar;
-
-  TRACE("CRTDLL__splitpath got %s\n",path);
-
-  drivechar  = strchr(path,':');
-  dirchar    = strrchr(path,'/');
-  namechar   = strrchr(path,'\\');
-  dirchar = MAX(dirchar,namechar);
-  if (dirchar)
-    namechar   = strrchr(dirchar,'.');
-  else
-    namechar   = strrchr(path,'.');
-  
-  
-  if (drive) 
-    {
-      *drive = 0x00;
-      if (drivechar) 
-       {
-         strncat(drive,path,drivechar-path+1);
-         path = drivechar+1;
-       }
-    }
-  if (directory) 
-    {
-      *directory = 0x00;
-      if (dirchar)
-       {
-         strncat(directory,path,dirchar-path+1);
-         path = dirchar+1;
-       }
-    }
-  if (filename)
-    {
-      *filename = 0x00;
-      if (namechar)
-       {
-         strncat(filename,path,namechar-path);
-         if (extension) 
-           {
-             *extension = 0x00;
-             strcat(extension,namechar);
-           }
-       }
-    }
-
-  TRACE("CRTDLL__splitpath found %s %s %s %s\n",drive,directory,filename,extension);
-  
-}
-
-
-/*********************************************************************
- *                  _makepath           (CRTDLL.182)
- */
-
-VOID __cdecl CRTDLL__makepath(LPSTR path, LPCSTR drive, 
-                             LPCSTR directory, LPCSTR filename, 
-                             LPCSTR extension )
-{
-       char ch;
-       TRACE("CRTDLL__makepath got %s %s %s %s\n", drive, directory, 
-             filename, extension);
-
-       if ( !path )
-               return;
-
-       path[0] = 0;
-       if ( drive ) 
-               if ( drive[0] ) {
-                       sprintf(path, "%c:", drive[0]);
-               }
-       if ( directory ) 
-               if ( directory[0] ) {
-                       strcat(path, directory);
-                       ch = path[strlen(path)-1];
-                       if (ch != '/' && ch != '\\')
-                               strcat(path,"\\");
-               }
-       if ( filename ) 
-               if ( filename[0] ) {
-                       strcat(path, filename);
-                       if ( extension ) {
-                               if ( extension[0] ) {
-                                       if ( extension[0] != '.' ) {
-                                               strcat(path,".");
-                                       } 
-                                       strcat(path,extension);
-                               }
-                       }
-               }
-       
-       TRACE("CRTDLL__makepath returns %s\n",path);  
-}
-
-/*********************************************************************
- *                  _getcwd           (CRTDLL.120)
- */
-CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT size)
-{
-  char test[1];
-  int len;
-
-  len = size;
-  if (!buf) {
-    if (size < 0) /* allocate as big as nescessary */
-      len =GetCurrentDirectoryA(1,test) + 1;
-    if(!(buf = CRTDLL_malloc(len)))
-    {
-       /* set error to OutOfRange */
-       return( NULL );
-    }
-  }
-  size = len;
-  if(!(len =GetCurrentDirectoryA(len,buf)))
-    {
-      return NULL;
-    }
-  if (len > size)
-    {
-      /* set error to ERANGE */
-      TRACE("CRTDLL_getcwd buffer to small\n");
-      return NULL;
-    }
-  return buf;
-
-}
-
-/*********************************************************************
- *                  _getdcwd           (CRTDLL.121)
- */
-CHAR* __cdecl CRTDLL__getdcwd(INT drive,LPSTR buf, INT size)
-{
-  char test[1];
-  int len;
-
-  FIXME("(\"%c:\",%s,%d)\n",drive+'A',buf,size);
-  len = size;
-  if (!buf) {
-    if (size < 0) /* allocate as big as nescessary */
-      len =GetCurrentDirectoryA(1,test) + 1;
-    if(!(buf = CRTDLL_malloc(len)))
-    {
-       /* set error to OutOfRange */
-       return( NULL );
-    }
-  }
-  size = len;
-  if(!(len =GetCurrentDirectoryA(len,buf)))
-    {
-      return NULL;
-    }
-  if (len > size)
-    {
-      /* set error to ERANGE */
-      TRACE("buffer to small\n");
-      return NULL;
-    }
-  return buf;
-
-}
-
-/*********************************************************************
- *                  _getdrive           (CRTDLL.124)
- *
- *  Return current drive, 1 for A, 2 for B
- */
-INT __cdecl CRTDLL__getdrive(VOID)
-{
-    return DRIVE_GetCurrentDrive() + 1;
-}
-
-/*********************************************************************
- *                  _mkdir           (CRTDLL.234)
- */
-INT __cdecl CRTDLL__mkdir(LPCSTR newdir)
-{
-       if (!CreateDirectoryA(newdir,NULL))
-               return -1;
-       return 0;
-}
-
-/*********************************************************************
- *                  remove           (CRTDLL.448)
- */
-INT __cdecl CRTDLL_remove(LPCSTR file)
-{
-       if (!DeleteFileA(file))
-               return -1;
-       return 0;
-}
-
-/*********************************************************************
- *                  _errno           (CRTDLL.52)
- * Yes, this is a function.
- */
-LPINT __cdecl CRTDLL__errno()
-{
-       static  int crtdllerrno;
-       
-       /* FIXME: we should set the error at the failing function call time */
-       crtdllerrno = LastErrorToErrno(GetLastError());
-       return &crtdllerrno;
-}
-
-/*********************************************************************
- *                  _tempnam           (CRTDLL.305)
- * 
- */
-LPSTR __cdecl CRTDLL__tempnam(LPCSTR dir, LPCSTR prefix)
-{
-
-     char *ret;
-     DOS_FULL_NAME tempname;
-     
-     if ((ret = tempnam(dir,prefix))==NULL) {
-       WARN("Unable to get unique filename\n");
-       return NULL;
-     }
-     if (!DOSFS_GetFullName(ret,FALSE,&tempname))
-     {
-       TRACE("Wrong path?\n");
-       return NULL;
-     }
-     free(ret);
-     if ((ret = CRTDLL_malloc(strlen(tempname.short_name)+1)) == NULL) {
-        WARN("CRTDL_malloc for shortname failed\n");
-        return NULL;
-     }
-     if ((ret = strcpy(ret,tempname.short_name)) == NULL) { 
-       WARN("Malloc for shortname failed\n");
-       return NULL;
-     }
-     
-     TRACE("dir %s prefix %s got %s\n",
-                   dir,prefix,ret);
-     return ret;
-
-}
-/*********************************************************************
- *                  tmpnam           (CRTDLL.490)
- *
- * lcclnk from lcc-win32 relies on a terminating dot in the name returned
- * 
- */
-LPSTR __cdecl CRTDLL_tmpnam(LPSTR s)
-{
-     char *ret;
-
-     if ((ret =tmpnam(s))== NULL) {
-       WARN("Unable to get unique filename\n");
-       return NULL;
-     }
-     if (!DOSFS_GetFullName(ret,FALSE,&CRTDLL_tmpname))
-     {
-       TRACE("Wrong path?\n");
-       return NULL;
-     }
-     strcat(CRTDLL_tmpname.short_name,".");
-     TRACE("for buf %p got %s\n",
-                   s,CRTDLL_tmpname.short_name);
-     TRACE("long got %s\n",
-                   CRTDLL_tmpname.long_name);
-     if ( s != NULL) 
-       return strcpy(s,CRTDLL_tmpname.short_name);
-     else 
-       return CRTDLL_tmpname.short_name;
-
-}
-
-/*********************************************************************
- *                  _itoa           (CRTDLL.165)
- */
-LPSTR  __cdecl CRTDLL__itoa(INT x,LPSTR buf,INT buflen)
-{
-    wsnprintfA(buf,buflen,"%d",x);
-    return buf;
-}
-
-/*********************************************************************
- *                  _ltoa           (CRTDLL.180)
- */
-LPSTR  __cdecl CRTDLL__ltoa(long x,LPSTR buf,INT radix)
-{
-    switch(radix) {
-        case  2: FIXME("binary format not implemented !\n");
-                 break;
-        case  8: wsnprintfA(buf,0x80,"%o",x);
-                 break;
-        case 10: wsnprintfA(buf,0x80,"%d",x);
-                 break;
-        case 16: wsnprintfA(buf,0x80,"%x",x);
-                 break;
-        default: FIXME("radix %d not implemented !\n", radix);
-    }
-    return buf;
-}
-
-/*********************************************************************
- *                  _ultoa           (CRTDLL.311)
- */
-LPSTR  __cdecl CRTDLL__ultoa(long x,LPSTR buf,INT radix)
-{
-    switch(radix) {
-        case  2: FIXME("binary format not implemented !\n");
-                 break;
-        case  8: wsnprintfA(buf,0x80,"%lo",x);
-                 break;
-        case 10: wsnprintfA(buf,0x80,"%ld",x);
-                 break;
-        case 16: wsnprintfA(buf,0x80,"%lx",x);
-                 break;
-        default: FIXME("radix %d not implemented !\n", radix);
-    }
-    return buf;
-}
-
-typedef VOID (*sig_handler_type)(VOID);
-
-/*********************************************************************
- *                  signal           (CRTDLL.455)
- */
-VOID __cdecl CRTDLL_signal(int sig, sig_handler_type ptr)
-{
-    FIXME("(%d %p):stub.\n", sig, ptr);
-}
-
-/*********************************************************************
- *                  _ftol            (CRTDLL.113)
- */
-#ifdef USING_REAL_FPU
-LONG __cdecl CRTDLL__ftol(void) {
-       /* don't just do DO_FPU("fistp",retval), because the rounding
-        * mode must also be set to "round towards zero"... */
-       double fl;
-       POP_FPU(fl);
-       return (LONG)fl;
-}
-#else
-LONG __cdecl CRTDLL__ftol(double fl) {
-       FIXME("should be register function\n");
-       return (LONG)fl;
-}
-#endif
-
-/*********************************************************************
- *                  _CIpow           (CRTDLL.14)
- */
-#ifdef USING_REAL_FPU
-LONG __cdecl CRTDLL__CIpow(void) {
-       double x,y;
-       POP_FPU(y);
-       POP_FPU(x);
-       return pow(x,y);
-}
-#else
-LONG __cdecl CRTDLL__CIpow(double x,double y) {
-       FIXME("should be register function\n");
-       return pow(x,y);
-}
-#endif
-
-/*********************************************************************
- *                  _sleep           (CRTDLL.267)
- */
-VOID __cdecl CRTDLL__sleep(unsigned long timeout) 
-{
-  TRACE("CRTDLL__sleep for %ld milliseconds\n",timeout);
-  Sleep((timeout)?timeout:1);
-}
-
-/*********************************************************************
- *                  getenv           (CRTDLL.437)
- */
-LPSTR __cdecl CRTDLL_getenv(const char *name) 
-{
-     LPSTR environ = GetEnvironmentStringsA();
-     LPSTR pp,pos = NULL;
-     unsigned int length;
-  
-     for (pp = environ; (*pp); pp = pp + strlen(pp) +1)
-       {
-        pos =strchr(pp,'=');
-        if (pos)
-          length = pos -pp;
-        else
-          length = strlen(pp);
-        if (!strncmp(pp,name,length)) break;
-       }
-     if ((pp)&& (pos)) 
-       {
-        pp = pos+1;
-        TRACE("got %s\n",pp);
-       }
-     FreeEnvironmentStringsA( environ );
-     return pp;
-}
-
-/*********************************************************************
- *                  _mbsrchr           (CRTDLL.223)
- */
-LPSTR __cdecl CRTDLL__mbsrchr(LPSTR s,CHAR x) {
-       /* FIXME: handle multibyte strings */
-       return strrchr(s,x);
-}
-
-/*********************************************************************
- *                  _memicmp           (CRTDLL.233)(NTDLL.868)
- * A stringcompare, without \0 check
- * RETURNS
- *     -1:if first string is alphabetically before second string
- *     1:if second ''    ''      ''          ''   first   ''
- *      0:if both are equal.
- */
-INT __cdecl CRTDLL__memicmp(
-       LPCSTR s1,      /* [in] first string */
-       LPCSTR s2,      /* [in] second string */
-       DWORD len       /* [in] length to compare */
-) { 
-       int     i;
-
-       for (i=0;i<len;i++) {
-               if (tolower(s1[i])<tolower(s2[i]))
-                       return -1;
-               if (tolower(s1[i])>tolower(s2[i]))
-                       return  1;
-       }
-       return 0;
-}
-/*********************************************************************
- *                  __dllonexit           (CRTDLL.25)
- */
-VOID __cdecl CRTDLL__dllonexit ()
-{      
-       FIXME("stub\n");
-}
-
-/*********************************************************************
- *                  wcstol           (CRTDLL.520)
- * Like strtol, but for wide character strings.
- */
-INT __cdecl CRTDLL_wcstol(LPWSTR s,LPWSTR *end,INT base) {
-       LPSTR   sA = HEAP_strdupWtoA(GetProcessHeap(),0,s),endA;
-       INT     ret = strtol(sA,&endA,base);
-
-       HeapFree(GetProcessHeap(),0,sA);
-       if (end) *end = s+(endA-sA); /* pointer magic checked. */
-       return ret;
-}
-/*********************************************************************
- *                  strdate           (CRTDLL.283)
- */
-LPSTR __cdecl CRTDLL__strdate (LPSTR date)
-{      FIXME("%p stub\n", date);
-       return 0;
-}
-
-/*********************************************************************
- *                  strtime           (CRTDLL.299)
- */
-LPSTR __cdecl CRTDLL__strtime (LPSTR date)
-{      FIXME("%p stub\n", date);
-       return 0;
-}
 
 /*********************************************************************
- *                  _except_handler2  (CRTDLL.78)
+ *             _strspnp (CRTDLL.@)
  */
-INT __cdecl CRTDLL__except_handler2 (
-       PEXCEPTION_RECORD rec,
-       PEXCEPTION_FRAME frame,
-       PCONTEXT context,
-       PEXCEPTION_FRAME  *dispatcher)
+char *_strspnp( const char *str1, const char *str2)
 {
-       FIXME ("exception %lx flags=%lx at %p handler=%p %p %p stub\n",
-       rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
-       frame->Handler, context, dispatcher);
-       return ExceptionContinueSearch;
+    str1 += strspn( str1, str2 );
+    return *str1 ? (char*)str1 : NULL;
 }