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

stdio emulation.
This commit is contained in:
Alexandre Julliard 1999-01-01 16:56:22 +00:00
parent 1392658679
commit 56d236f0b0
1 changed files with 208 additions and 234 deletions

View File

@ -16,6 +16,9 @@ Unresolved issues Uwe Bonnes 970904:
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 @@ Unresolved issues Uwe Bonnes 970904:
* 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_winmajor_dll; /* CRTDLL.329 */
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 @@ DWORD __cdecl CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
/*********************************************************************
* _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 @@ INT32 __cdecl CRTDLL__read(INT32 fd, LPVOID buf, UINT32 count)
/*********************************************************************
* 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 @@ DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
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 @@ DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
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 @@ DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID vfile)
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 @@ DWORD __cdecl CRTDLL_freopen(LPCSTR path, LPCSTR mode, LPVOID stream)
/*********************************************************************
* 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 @@ INT32 __cdecl CRTDLL_fscanf( LPVOID stream, LPSTR format, ... )
#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;
}
@ -496,28 +493,31 @@ void __cdecl CRTDLL_srand(DWORD seed)
srand(seed);
}
/*********************************************************************
* 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)
*/
@ -645,16 +645,117 @@ INT32 __cdecl CRTDLL__access(LPCSTR filename, INT32 mode)
/*********************************************************************
* 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;
}
@ -680,83 +781,6 @@ LPSTR __cdecl CRTDLL_gets(LPSTR buf)
}
/*********************************************************************
* 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)
*/
@ -783,32 +807,6 @@ DWORD __cdecl CRTDLL__lrotl(DWORD x,INT32 shift)
}
/*********************************************************************
* 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)
*/
@ -1087,33 +1085,12 @@ LPWSTR __cdecl CRTDLL__wcsdup(LPCWSTR ptr)
/*********************************************************************
* 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 @@ INT32 __cdecl CRTDLL__close(HFILE32 fd)
/*********************************************************************
* 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;
}
/*********************************************************************