Hacked stdio functions to use Win32 file handles. Still needs a proper
stdio emulation.

diff --git a/misc/crtdll.c b/misc/crtdll.c
index c142b7e..eb3e40a 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -16,6 +16,9 @@
               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 
@@ -23,8 +26,6 @@
  * since we need 2 byte wide characters. - Marcus Meissner, 981031
  */
 
-/* FIXME: all the file handling is hopelessly broken -- AJ */
-
 #include <errno.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -70,7 +71,18 @@
 UINT32 CRTDLL_winminor_dll;     /* CRTDLL.330 */
 UINT32 CRTDLL_winver_dll;       /* CRTDLL.331 */
 
-BYTE CRTDLL_iob[32*3];  /* FIXME */
+/* FIXME: structure layout is obviously not correct */
+typedef struct
+{
+    HANDLE32 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);
 
@@ -210,40 +222,34 @@
 /*********************************************************************
  *                  _fdopen     (CRTDLL.91)
  */
-DWORD __cdecl CRTDLL__fdopen(INT32 handle, LPCSTR mode)
+CRTDLL_FILE * __cdecl CRTDLL__fdopen(INT32 handle, LPCSTR mode)
 {
-  FILE *file;
+    CRTDLL_FILE *file;
 
-  switch (handle) 
+    switch (handle) 
     {
-    case 0 : file=stdin;
-      break;
-    case 1 : file=stdout;
-      break;
-    case 2 : file=stderr;
-      break;
+    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=fdopen(handle,mode);
+        file = HeapAlloc( GetProcessHeap(), 0, sizeof(*file) );
+        file->handle = handle;
+        break;
     }
   TRACE(crtdll, "open handle %d mode %s  got file %p\n",
 	       handle, mode, file);
-  return (DWORD)file;
+  return file;
 }
 
-static FILE *xlat_file_ptr(void *ptr)
-{
-    unsigned long dif;
-    
-    /* CRT sizeof(FILE) == 32 */
-    dif = ((char *)ptr - (char *)CRTDLL_iob) / 32;
-    switch(dif)
-    {
-	case 0: return stdin;
-	case 1: return stdout;
-	case 2: return stderr;
-    }
-    return (FILE*)ptr;
-}
 
 /*******************************************************************
  *         _global_unwind2  (CRTDLL.129)
@@ -276,10 +282,10 @@
 /*********************************************************************
  *                  fopen     (CRTDLL.372)
  */
-DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
+CRTDLL_FILE * __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
 {
-  FILE *file;
-  HFILE32 dos_fildes;
+  CRTDLL_FILE *file = NULL;
+  HFILE32 handle;
 #if 0
   DOS_FULL_NAME full_name;
   
@@ -291,12 +297,11 @@
   file=fopen(full_name.long_name ,mode);
 #endif
   INT32 flagmode=0;
-  int unix_fildes=0;
 
   if ((strchr(mode,'r')&&strchr(mode,'a'))||
       (strchr(mode,'r')&&strchr(mode,'w'))||
       (strchr(mode,'w')&&strchr(mode,'a')))
-    return 0;
+    return NULL;
        
   if (strstr(mode,"r+")) flagmode=O_RDWR;
   else if (strchr(mode,'r')) flagmode = O_RDONLY;
@@ -307,22 +312,21 @@
   else if (strchr(mode,'b'))
     TRACE(crtdll, "%s in BINARY mode\n",path);
       
-  dos_fildes=FILE_Open(path, flagmode,0);
-  unix_fildes=FILE_GetUnixHandle(dos_fildes,0);
-  file = fdopen(unix_fildes,mode);
-
-  TRACE(crtdll, "file %s mode %s got ufh %d dfh %d file %p\n",
-		 path,mode,unix_fildes,dos_fildes,file);
-  return (DWORD)file;
+  if ((handle = FILE_Open(path, flagmode,0)) != INVALID_HANDLE_VALUE32)
+  {
+      file = HeapAlloc( GetProcessHeap(), 0, sizeof(*file) );
+      file->handle = handle;
+  }
+  TRACE(crtdll, "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, INT32 size, INT32 nmemb, LPVOID vfile)
+DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT32 size, INT32 nmemb, CRTDLL_FILE *file)
 {
-  size_t ret=1;
-  FILE *file=xlat_file_ptr(vfile);
 #if 0
   int i=0;
   void *temp=ptr;
@@ -349,14 +353,14 @@
 
   return i;
 #else
-    
-  ret=fread(ptr,size,nmemb,file);
+  DWORD ret;
+
   TRACE(crtdll, "0x%08x items of size %d from file %p to %p\n",
 	       nmemb,size,file,ptr);
-  if(ret!=nmemb)
-    WARN(crtdll, " failed!\n");
+  if (!ReadFile( file->handle, ptr, size * nmemb, &ret, NULL ))
+      WARN(crtdll, " failed!\n");
 
-  return ret;
+  return ret / size;
 #endif
 }
 /*********************************************************************
@@ -375,8 +379,9 @@
 /*********************************************************************
  *                  fscanf     (CRTDLL.381)
  */
-INT32 __cdecl CRTDLL_fscanf( LPVOID stream, LPSTR format, ... )
+INT32 __cdecl CRTDLL_fscanf( CRTDLL_FILE *stream, LPSTR format, ... )
 {
+#if 0
     va_list valist;
     INT32 res;
 
@@ -386,75 +391,67 @@
 #endif
     va_end( valist );
     return res;
+#endif
+    FIXME(crtdll,"broken\n");
+    return 0;
 }
 
 /*********************************************************************
  *                  fseek     (CRTDLL.382)
  */
-LONG __cdecl CRTDLL_fseek(LPVOID stream, LONG offset, INT32 whence)
+LONG __cdecl CRTDLL_fseek( CRTDLL_FILE *file, LONG offset, INT32 whence)
 {
-  long ret;
-
-  ret=fseek(xlat_file_ptr(stream),offset,whence);
   TRACE(crtdll, "file %p to 0x%08lx pos %s\n",
-	       stream,offset,(whence==SEEK_SET)?"SEEK_SET":
-	       (whence==SEEK_CUR)?"SEEK_CUR":
-	       (whence==SEEK_END)?"SEEK_END":"UNKNOWN");
-  if(ret)
-    WARN(crtdll, " failed!\n");
-
-  return ret;
+        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(crtdll, " failed!\n");
+  return -1;
 }
   
 /*********************************************************************
  *                  fsetpos     (CRTDLL.383)
  */
-INT32 __cdecl CRTDLL_fsetpos(LPVOID stream, fpos_t *pos)
+INT32 __cdecl CRTDLL_fsetpos( CRTDLL_FILE *file, INT32 *pos )
 {
-  TRACE(crtdll, "file %p\n", stream);
-  return fseek(xlat_file_ptr(stream), *pos, SEEK_SET);
+    TRACE(crtdll, "file %p pos %d\n", file, *pos );
+    return CRTDLL_fseek(file, *pos, SEEK_SET);
 }
 
 /*********************************************************************
  *                  ftell     (CRTDLL.384)
  */
-LONG __cdecl CRTDLL_ftell(LPVOID stream)
+LONG __cdecl CRTDLL_ftell( CRTDLL_FILE *file )
 {
-  long ret;
-
-  ret=ftell(xlat_file_ptr(stream));
-  TRACE(crtdll, "file %p at 0x%08lx\n",
-	       stream,ret);
-  return ret;
+    return SetFilePointer( file->handle, 0, NULL, SEEK_CUR );
 }
   
 /*********************************************************************
  *                  fwrite     (CRTDLL.386)
  */
-DWORD __cdecl CRTDLL_fwrite(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID vfile)
+DWORD __cdecl CRTDLL_fwrite( LPVOID ptr, INT32 size, INT32 nmemb, CRTDLL_FILE *file )
 {
-  size_t ret;
-  FILE *file=xlat_file_ptr(vfile);
+    DWORD ret;
 
-  ret=fwrite(ptr,size,nmemb,file);
-  TRACE(crtdll, "0x%08x items of size %d from %p to file %p\n",
-	       nmemb,size,ptr,file);
-  if(ret!=nmemb)
-    WARN(crtdll, " Failed!\n");
-
-  return ret;
+    TRACE(crtdll, "0x%08x items of size %d to file %p from %p\n",
+          nmemb,size,file,ptr);
+    if (!WriteFile( file->handle, ptr, size * nmemb, &ret, NULL ))
+        WARN(crtdll, " failed!\n");
+    return ret / size;
 }
 
 /*********************************************************************
  *                  setbuf     (CRTDLL.452)
  */
-INT32 __cdecl CRTDLL_setbuf(LPVOID file, LPSTR buf)
+INT32 __cdecl CRTDLL_setbuf(CRTDLL_FILE *file, LPSTR buf)
 {
   TRACE(crtdll, "(file %p buf %p)\n", file, buf);
   /* this doesn't work:"void value not ignored as it ought to be" 
   return setbuf(file,buf); 
   */
-  setbuf(xlat_file_ptr(file),buf);
+  /* FIXME: no buffering for now */
   return 0;
 }
 
@@ -497,28 +494,31 @@
 }
 
 /*********************************************************************
+ *                  vfprintf       (CRTDLL.373)
+ */
+INT32 __cdecl CRTDLL_vfprintf( CRTDLL_FILE *file, LPSTR format, va_list args )
+{
+    char buffer[1024];  /* FIXME... */
+
+    vsprintf( buffer, format, args );
+    return CRTDLL_fwrite( buffer, 1, strlen(buffer), file );
+}
+
+/*********************************************************************
  *                  fprintf       (CRTDLL.373)
  */
-INT32 __cdecl CRTDLL_fprintf( FILE *file, LPSTR format, ... )
+INT32 __cdecl CRTDLL_fprintf( CRTDLL_FILE *file, LPSTR format, ... )
 {
     va_list valist;
     INT32 res;
 
     va_start( valist, format );
-    res = vfprintf( xlat_file_ptr(file), format, valist );
+    res = CRTDLL_vfprintf( file, format, valist );
     va_end( valist );
     return res;
 }
 
 /*********************************************************************
- *                  vfprintf       (CRTDLL.373)
- */
-INT32 __cdecl CRTDLL_vfprintf( FILE *file, LPSTR format, va_list args )
-{
-    return vfprintf( xlat_file_ptr(file), format, args );
-}
-
-/*********************************************************************
  *                  time          (CRTDLL.488)
  */
 time_t __cdecl CRTDLL_time(time_t *timeptr)
@@ -645,16 +645,117 @@
 /*********************************************************************
  *                  fflush        (CRTDLL.365)
  */
-INT32 __cdecl CRTDLL_fflush(LPVOID stream)
+INT32 __cdecl CRTDLL_fflush( CRTDLL_FILE *file )
 {
-    int ret;
+    return FlushFileBuffers( file->handle ) ? 0 : -1;
+}
 
-    ret = fflush(xlat_file_ptr(stream));
-    TRACE(crtdll,"%p returnd %d\n",stream,ret);
-    if(ret)
-      WARN(crtdll, " Failed!\n");
 
-    return ret;
+/*********************************************************************
+ *                  rand          (CRTDLL.446)
+ */
+INT32 __cdecl CRTDLL_rand()
+{
+    return rand();
+}
+
+
+/*********************************************************************
+ *                  putchar       (CRTDLL.442)
+ */
+void __cdecl CRTDLL_putchar( INT32 x )
+{
+    putchar(x);
+}
+
+
+/*********************************************************************
+ *                  fputc       (CRTDLL.374)
+ */
+INT32 __cdecl CRTDLL_fputc( INT32 c, CRTDLL_FILE *file )
+{
+    char ch = (char)c;
+    DWORD res;
+    TRACE(crtdll, "%c to file %p\n",c,file);
+    if (!WriteFile( file->handle, &ch, 1, &res, NULL )) return -1;
+    return c;
+}
+
+
+/*********************************************************************
+ *                  fputs       (CRTDLL.375)
+ */
+INT32 __cdecl CRTDLL_fputs( LPCSTR s, CRTDLL_FILE *file )
+{
+    DWORD res;
+    TRACE(crtdll, "%s to file %p\n",s,file);
+    if (!WriteFile( file->handle, s, strlen(s), &res, NULL )) return -1;
+    return res;
+}
+
+
+/*********************************************************************
+ *                  puts       (CRTDLL.443)
+ */
+INT32 __cdecl CRTDLL_puts(LPCSTR s)
+{
+    TRACE(crtdll, "%s \n",s);
+    return puts(s);
+}
+
+
+/*********************************************************************
+ *                  putc       (CRTDLL.441)
+ */
+INT32 __cdecl CRTDLL_putc( INT32 c, CRTDLL_FILE *file )
+{
+    return CRTDLL_fputc( c, file );
+}
+
+/*********************************************************************
+ *                  fgetc       (CRTDLL.366)
+ */
+INT32 __cdecl CRTDLL_fgetc( CRTDLL_FILE *file )
+{
+    DWORD res;
+    char ch;
+    if (!ReadFile( file->handle, &ch, 1, &res, NULL )) return -1;
+    return ch;
+}
+
+
+/*********************************************************************
+ *                  getc       (CRTDLL.388)
+ */
+INT32 __cdecl CRTDLL_getc( CRTDLL_FILE *file )
+{
+    return CRTDLL_fgetc( file );
+}
+
+
+/*********************************************************************
+ *                  fgets       (CRTDLL.368)
+ */
+CHAR* __cdecl CRTDLL_fgets( LPSTR s, INT32 size, CRTDLL_FILE *file )
+{
+    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(crtdll,"got '%s'\n", buf_start);
+    return buf_start;
 }
 
 
@@ -681,83 +782,6 @@
 
 
 /*********************************************************************
- *                  rand          (CRTDLL.446)
- */
-INT32 __cdecl CRTDLL_rand()
-{
-    return rand();
-}
-
-
-/*********************************************************************
- *                  putchar       (CRTDLL.442)
- */
-void __cdecl CRTDLL_putchar( INT32 x )
-{
-    putchar(x);
-}
-
-
-/*********************************************************************
- *                  fputc       (CRTDLL.374)
- */
-INT32 __cdecl CRTDLL_fputc( INT32 c, FILE *stream )
-{
-    TRACE(crtdll, "%c to file %p\n",c,stream);
-    return fputc(c,xlat_file_ptr(stream));
-}
-
-
-/*********************************************************************
- *                  fputs       (CRTDLL.375)
- */
-INT32 __cdecl CRTDLL_fputs( LPCSTR s, FILE *stream )
-{
-    TRACE(crtdll, "%s to file %p\n",s,stream);
-    return fputs(s,xlat_file_ptr(stream));
-}
-
-
-/*********************************************************************
- *                  puts       (CRTDLL.443)
- */
-INT32 __cdecl CRTDLL_puts(LPCSTR s)
-{
-    TRACE(crtdll, "%s \n",s);
-    return puts(s);
-}
-
-
-/*********************************************************************
- *                  putc       (CRTDLL.441)
- */
-INT32 __cdecl CRTDLL_putc(INT32 c, FILE *stream)
-{
-    TRACE(crtdll, " %c to file %p\n",c,stream);
-    return fputc(c,xlat_file_ptr(stream));
-}
-/*********************************************************************
- *                  fgetc       (CRTDLL.366)
- */
-INT32 __cdecl CRTDLL_fgetc( FILE *stream )
-{
-  int ret= fgetc(xlat_file_ptr(stream));
-  TRACE(crtdll, "got %d\n",ret);
-  return ret;
-}
-
-
-/*********************************************************************
- *                  getc       (CRTDLL.388)
- */
-INT32 __cdecl CRTDLL_getc( FILE *stream )
-{
-  int ret= fgetc(xlat_file_ptr(stream));
-  TRACE(crtdll, "got %d\n",ret);
-  return ret;
-}
-
-/*********************************************************************
  *                  _rotl          (CRTDLL.259)
  */
 UINT32 __cdecl CRTDLL__rotl(UINT32 x,INT32 shift)
@@ -784,32 +808,6 @@
 
 
 /*********************************************************************
- *                  fgets       (CRTDLL.368)
- */
-CHAR* __cdecl CRTDLL_fgets(LPSTR s,INT32 size, LPVOID stream)
-{
-  char * ret;
-  char * control_M;
-  
-  ret=fgets(s, size,xlat_file_ptr(stream));
-  /*FIXME: Control with CRTDLL_setmode */
-  control_M= strrchr(s,'\r');
-  /*delete CR if we read a DOS File */
-  if (control_M)
-    {
-      *control_M='\n';
-      *(control_M+1)=0;
-    }
-  TRACE(crtdll, "got %s for %d chars from file %p\n",
-		 s,size,stream);
-  if(ret)
-    WARN(crtdll, " Failed!\n");
-
-  return ret;
-}
-
-
-/*********************************************************************
  *                  _mbsicmp      (CRTDLL.204)
  */
 int __cdecl CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
@@ -1087,33 +1085,12 @@
 /*********************************************************************
  *                  fclose           (CRTDLL.362)
  */
-INT32 __cdecl CRTDLL_fclose( FILE *stream )
+INT32 __cdecl CRTDLL_fclose( CRTDLL_FILE *file )
 {
-    int unix_handle;
-    HFILE32 dos_handle=1;
-    HFILE32 ret=EOF;
-
-    stream=xlat_file_ptr(stream);
-    unix_handle=fileno(stream);
-
-    if (unix_handle<4) ret= fclose(stream);
-    else {
-      int h;
-      while((h = FILE_GetUnixHandle(dos_handle,0)) != unix_handle)
-      {
-          close(h);
-          dos_handle++;
-      }
-      fclose(stream);
-      ret = _lclose32( dos_handle);
-    }
-    TRACE(crtdll,"(%p) ufh %d dfh %d\n",
-		   stream,unix_handle,dos_handle);
-
-    if(ret)
-      WARN(crtdll, " Failed!\n");
-
-    return ret;
+    TRACE(crtdll,"%p\n", file );
+    if (!CloseHandle( file->handle )) return -1;
+    HeapFree( GetProcessHeap(), 0, file );
+    return 0;
 }
 
 /*********************************************************************
@@ -1246,13 +1223,10 @@
 /*********************************************************************
  *                  feof           (CRTDLL.363)
  */
-INT32 __cdecl CRTDLL_feof( FILE *stream )
+INT32 __cdecl CRTDLL_feof( CRTDLL_FILE *file )
 {
-    int ret;
-    
-    ret=feof(xlat_file_ptr(stream));
-    TRACE(crtdll,"(%p) %s\n",stream,(ret)?"true":"false");
-    return ret;
+    FIXME(crtdll,"stub\n" );
+    return 0;
 }
 
 /*********************************************************************