Commit 1db20bfd authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

- Migrate CRTDLL to MSVCRT.

- Many fixes and a load of new functions.
parent ca43a641
...@@ -45,6 +45,7 @@ Other DLLs: ...@@ -45,6 +45,7 @@ Other DLLs:
avifil32/ - COM object to play AVI files avifil32/ - COM object to play AVI files
comctl32/ - common controls comctl32/ - common controls
commdlg/ - common dialog boxes (both 16 & 32 bit) commdlg/ - common dialog boxes (both 16 & 32 bit)
crtdll/ - Old C runtime library
dplayx/ - DirectX dplayx dplayx/ - DirectX dplayx
dsound/ - DirectX dsound dsound/ - DirectX dsound
imagehlp/ - PE (Portable Executable) Image Helper lib imagehlp/ - PE (Portable Executable) Image Helper lib
...@@ -55,6 +56,7 @@ Other DLLs: ...@@ -55,6 +56,7 @@ Other DLLs:
msacm/ - audio compression manager (multimedia) (16 bit) msacm/ - audio compression manager (multimedia) (16 bit)
msacm32/ - audio compression manager (multimedia) (32 bit) msacm32/ - audio compression manager (multimedia) (32 bit)
msnet/ msnet/
msvcrt/ - C runtime library
msvideo/ - 16 bit video manager msvideo/ - 16 bit video manager
ole32/ - 32 bit OLE 2.0 librairies ole32/ - 32 bit OLE 2.0 librairies
oleaut32/ - 32 bit OLE 2.0 automation oleaut32/ - 32 bit OLE 2.0 automation
......
...@@ -129,6 +129,7 @@ DLLS = \ ...@@ -129,6 +129,7 @@ DLLS = \
msacm.drv \ msacm.drv \
msacm32 \ msacm32 \
msnet32 \ msnet32 \
msvcrt \
msvfw32 \ msvfw32 \
odbc32 \ odbc32 \
ole32 \ ole32 \
......
...@@ -7000,6 +7000,7 @@ dlls/lzexpand/Makefile ...@@ -7000,6 +7000,7 @@ dlls/lzexpand/Makefile
dlls/mpr/Makefile dlls/mpr/Makefile
dlls/msacm/Makefile dlls/msacm/Makefile
dlls/msnet32/Makefile dlls/msnet32/Makefile
dlls/msvcrt/Makefile
dlls/msvideo/Makefile dlls/msvideo/Makefile
dlls/ntdll/Makefile dlls/ntdll/Makefile
dlls/odbc32/Makefile dlls/odbc32/Makefile
...@@ -7241,6 +7242,7 @@ dlls/lzexpand/Makefile ...@@ -7241,6 +7242,7 @@ dlls/lzexpand/Makefile
dlls/mpr/Makefile dlls/mpr/Makefile
dlls/msacm/Makefile dlls/msacm/Makefile
dlls/msnet32/Makefile dlls/msnet32/Makefile
dlls/msvcrt/Makefile
dlls/msvideo/Makefile dlls/msvideo/Makefile
dlls/ntdll/Makefile dlls/ntdll/Makefile
dlls/odbc32/Makefile dlls/odbc32/Makefile
......
...@@ -1200,6 +1200,7 @@ dlls/lzexpand/Makefile ...@@ -1200,6 +1200,7 @@ dlls/lzexpand/Makefile
dlls/mpr/Makefile dlls/mpr/Makefile
dlls/msacm/Makefile dlls/msacm/Makefile
dlls/msnet32/Makefile dlls/msnet32/Makefile
dlls/msvcrt/Makefile
dlls/msvideo/Makefile dlls/msvideo/Makefile
dlls/ntdll/Makefile dlls/ntdll/Makefile
dlls/odbc32/Makefile dlls/odbc32/Makefile
......
...@@ -32,6 +32,7 @@ DLLFILES = \ ...@@ -32,6 +32,7 @@ DLLFILES = \
mpr/libmpr.@LIBEXT@ \ mpr/libmpr.@LIBEXT@ \
msacm/libmsacm32.@LIBEXT@ \ msacm/libmsacm32.@LIBEXT@ \
msnet32/libmsnet32.@LIBEXT@ \ msnet32/libmsnet32.@LIBEXT@ \
msvcrt/libmsvcrt.@LIBEXT@ \
msvideo/libmsvfw32.@LIBEXT@ \ msvideo/libmsvfw32.@LIBEXT@ \
ntdll/libntdll.@LIBEXT@ \ ntdll/libntdll.@LIBEXT@ \
odbc32/libodbc32.@LIBEXT@ \ odbc32/libodbc32.@LIBEXT@ \
...@@ -145,6 +146,7 @@ SUBDIRS = \ ...@@ -145,6 +146,7 @@ SUBDIRS = \
mpr \ mpr \
msacm \ msacm \
msnet32 \ msnet32 \
msvcrt \
msvideo \ msvideo \
ntdll \ ntdll \
odbc32 \ odbc32 \
...@@ -283,6 +285,9 @@ libmsacm32.@LIBEXT@ libmsacm.@LIBEXT@: msacm/libmsacm32.@LIBEXT@ ...@@ -283,6 +285,9 @@ libmsacm32.@LIBEXT@ libmsacm.@LIBEXT@: msacm/libmsacm32.@LIBEXT@
libmsnet32.@LIBEXT@: msnet32/libmsnet32.@LIBEXT@ libmsnet32.@LIBEXT@: msnet32/libmsnet32.@LIBEXT@
$(RM) $@ && $(LN_S) msnet32/libmsnet32.@LIBEXT@ $@ $(RM) $@ && $(LN_S) msnet32/libmsnet32.@LIBEXT@ $@
libmsvcrt.@LIBEXT@: msvcrt/libmsvcrt.@LIBEXT@
$(RM) $@ && $(LN_S) msvcrt/libmsvcrt.@LIBEXT@ $@
libmsvfw32.@LIBEXT@ libmsvideo.@LIBEXT@: msvideo/libmsvfw32.@LIBEXT@ libmsvfw32.@LIBEXT@ libmsvideo.@LIBEXT@: msvideo/libmsvfw32.@LIBEXT@
$(RM) $@ && $(LN_S) msvideo/libmsvfw32.@LIBEXT@ $@ $(RM) $@ && $(LN_S) msvideo/libmsvfw32.@LIBEXT@ $@
...@@ -418,6 +423,7 @@ lzexpand/liblz32.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@ ...@@ -418,6 +423,7 @@ lzexpand/liblz32.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@
mpr/libmpr.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@ mpr/libmpr.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@
msacm/libmsacm32.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libadvapi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ msacm/libmsacm32.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libadvapi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
msnet32/libmsnet32.@LIBEXT@: libntdll.@LIBEXT@ msnet32/libmsnet32.@LIBEXT@: libntdll.@LIBEXT@
msvcrt/libmsvcrt.@LIBEXT@: libkernel32.@LIBEXT@ libntdll.@LIBEXT@
msvideo/libmsvfw32.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ msvideo/libmsvfw32.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
odbc32/libodbc32.@LIBEXT@: libntdll.@LIBEXT@ odbc32/libodbc32.@LIBEXT@: libntdll.@LIBEXT@
ole32/libole32.@LIBEXT@: libadvapi32.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ librpcrt4.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@ ole32/libole32.@LIBEXT@: libadvapi32.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ librpcrt4.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
......
Makefile
msvcrt.spec.c
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = msvcrt
EXTRALIBS = $(LIBUNICODE)
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
console.c \
cpp.c \
ctype.c \
data.c \
dir.c \
environ.c \
errno.c \
except.c \
exit.c \
file.c \
heap.c \
locale.c \
main.c \
math.c \
mbcs.c \
misc.c \
process.c \
string.c \
thread.c \
time.c \
wcs.c
@MAKE_DLL_RULES@
### Dependencies:
/*
* msvcrt.dll console functions
*
* Copyright 2000 Jon Griffiths
*
* Note: init and free don't need MT locking since they are called at DLL
* (de)attachment time, which is syncronised for us
*/
#include "msvcrt.h"
#include "wincon.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* MT */
extern CRITICAL_SECTION MSVCRT_console_cs;
#define LOCK_CONSOLE EnterCriticalSection(&MSVCRT_console_cs)
#define UNLOCK_CONSOLE LeaveCriticalSection(&MSVCRT_console_cs)
static HANDLE MSVCRT_console_in = INVALID_HANDLE_VALUE;
static HANDLE MSVCRT_console_out= INVALID_HANDLE_VALUE;
static int __MSVCRT_console_buffer = MSVCRT_EOF;
/* INTERNAL: Initialise console handles */
void MSVCRT_init_console(void)
{
TRACE(":Opening console handles\n");
MSVCRT_console_in = GetStdHandle(STD_INPUT_HANDLE);
/* FIXME: Should be initialised with:
* CreateFileA("CONIN$", GENERIC_READ, FILE_SHARE_READ,
* NULL, OPEN_EXISTING, 0, (HANDLE)NULL);
*/
MSVCRT_console_out= CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, (HANDLE)NULL);
if ((MSVCRT_console_in == INVALID_HANDLE_VALUE) ||
(MSVCRT_console_out== INVALID_HANDLE_VALUE))
WARN(":Console handle Initialisation FAILED!\n");
}
/* INTERNAL: Free console handles */
void MSVCRT_free_console(void)
{
TRACE(":Closing console handles\n");
CloseHandle(MSVCRT_console_in);
CloseHandle(MSVCRT_console_out);
}
/*********************************************************************
* _cputs (MSVCRT.@)
*/
int __cdecl MSVCRT__cputs(const char * str)
{
DWORD count;
int retval = MSVCRT_EOF;
LOCK_CONSOLE;
if (WriteConsoleA(MSVCRT_console_out, str, strlen(str), &count, NULL)
&& count == 1)
retval = 0;
UNLOCK_CONSOLE;
return retval;
}
/*********************************************************************
* _getch (MSVCRT.@)
*/
int __cdecl MSVCRT__getch(void)
{
int retval = MSVCRT_EOF;
LOCK_CONSOLE;
if (__MSVCRT_console_buffer != MSVCRT_EOF)
{
retval = __MSVCRT_console_buffer;
__MSVCRT_console_buffer = MSVCRT_EOF;
}
else
{
INPUT_RECORD ir;
DWORD count;
DWORD mode = 0;
GetConsoleMode(MSVCRT_console_in, &mode);
if(mode)
SetConsoleMode(MSVCRT_console_in, 0);
do {
if (ReadConsoleInputA(MSVCRT_console_in, &ir, 1, &count))
{
/* Only interested in ASCII chars */
if (ir.EventType == KEY_EVENT &&
ir.Event.KeyEvent.bKeyDown &&
ir.Event.KeyEvent.uChar.AsciiChar)
{
retval = ir.Event.KeyEvent.uChar.AsciiChar;
break;
}
}
else
break;
} while(1);
if (mode)
SetConsoleMode(MSVCRT_console_in, mode);
}
UNLOCK_CONSOLE;
return retval;
}
/*********************************************************************
* _putch (MSVCRT.@)
*/
int __cdecl MSVCRT__putch(int c)
{
int retval = MSVCRT_EOF;
DWORD count;
LOCK_CONSOLE;
if (WriteConsoleA(MSVCRT_console_out, &c, 1, &count, NULL) && count == 1)
retval = c;
UNLOCK_CONSOLE;
return retval;
}
/*********************************************************************
* _getche (MSVCRT.@)
*/
int __cdecl MSVCRT__getche(void)
{
int retval;
LOCK_CONSOLE;
retval = MSVCRT__getch();
if (retval != MSVCRT_EOF)
retval = MSVCRT__putch(retval);
UNLOCK_CONSOLE;
return retval;
}
/*********************************************************************
* _cgets (MSVCRT.@)
*/
char *__cdecl MSVCRT__cgets(char *str)
{
char *buf = str + 2;
int c;
str[1] = 0; /* Length */
/* FIXME: No editing of string supported */
LOCK_CONSOLE;
do
{
if (str[1] >= str[0] || (str[1]++, c = MSVCRT__getche()) == MSVCRT_EOF || c == '\n')
break;
*buf++ = c & 0xff;
} while (1);
UNLOCK_CONSOLE;
*buf = '\0';
return str + 2;
}
/*********************************************************************
* _ungetch (MSVCRT.@)
*/
int __cdecl MSVCRT__ungetch(int c)
{
int retval = MSVCRT_EOF;
LOCK_CONSOLE;
if (c != MSVCRT_EOF && __MSVCRT_console_buffer == MSVCRT_EOF)
retval = __MSVCRT_console_buffer = c;
UNLOCK_CONSOLE;
return retval;
}
/*********************************************************************
* _cscanf (MSVCRT.@)
*/
int __cdecl MSVCRT__cscanf( const char * format, ... )
{
/* NOTE: If you extend this function, extend MSVCRT_fscanf in file.c too */
int rd = 0;
int nch;
va_list ap;
if (!*format) return 0;
WARN("\"%s\": semi-stub\n", format);
va_start(ap, format);
LOCK_CONSOLE;
nch = MSVCRT__getch();
while (*format) {
if (*format == ' ') {
/* skip whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT__getch();
}
else if (*format == '%') {
int st = 0;
format++;
switch(*format) {
case 'd': { /* read an integer */
int*val = va_arg(ap, int*);
int cur = 0;
/* skip initial whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT__getch();
/* get sign and first digit */
if (nch == '-') {
nch = MSVCRT__getch();
if (isdigit(nch))
cur = -(nch - '0');
else break;
} else {
if (isdigit(nch))
cur = nch - '0';
else break;
}
nch = MSVCRT__getch();
/* read until no more digits */
while ((nch!=MSVCRT_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = MSVCRT__getch();
}
st = 1;
*val = cur;
}
break;
case 'f': { /* read a float */
float*val = va_arg(ap, float*);
float cur = 0;
/* skip initial whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT__getch();
/* get sign and first digit */
if (nch == '-') {
nch = MSVCRT__getch();
if (isdigit(nch))
cur = -(nch - '0');
else break;
} else {
if (isdigit(nch))
cur = nch - '0';
else break;
}
/* read until no more digits */
while ((nch!=MSVCRT_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = MSVCRT__getch();
}
if (nch == '.') {
/* handle decimals */
float dec = 1;
nch = MSVCRT__getch();
while ((nch!=MSVCRT_EOF) && isdigit(nch)) {
dec /= 10;
cur += dec * (nch - '0');
nch = MSVCRT__getch();
}
}
st = 1;
*val = cur;
}
break;
case 's': { /* read a word */
char*str = va_arg(ap, char*);
char*sptr = str;
/* skip initial whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT__getch();
/* read until whitespace */
while ((nch!=MSVCRT_EOF) && !isspace(nch)) {
*sptr++ = nch; st++;
nch = MSVCRT__getch();
}
/* terminate */
*sptr = 0;
TRACE("read word: %s\n", str);
}
break;
default: FIXME("unhandled: %%%c\n", *format);
}
if (st) rd++;
else break;
}
else {
/* check for character match */
if (nch == *format)
nch = MSVCRT__getch();
else break;
}
format++;
}
if (nch != MSVCRT_EOF)
MSVCRT__ungetch(nch);
UNLOCK_CONSOLE;
va_end(ap);
TRACE("returning %d\n", rd);
return rd;
}
/*********************************************************************
* _kbhit (MSVCRT.@)
*/
int __cdecl MSVCRT__kbhit(void)
{
int retval = 0;
LOCK_CONSOLE;
if (__MSVCRT_console_buffer != MSVCRT_EOF)
retval = 1;
else
{
/* FIXME: There has to be a faster way than this in Win32.. */
INPUT_RECORD *ir = NULL;
DWORD count = 0, i;
GetNumberOfConsoleInputEvents(MSVCRT_console_in, &count);
if (count && (ir = MSVCRT_malloc(count * sizeof(INPUT_RECORD))) &&
PeekConsoleInputA(MSVCRT_console_in, ir, count, &count))
for(i = 0; i < count - 1; i++)
{
if (ir[i].EventType == KEY_EVENT &&
ir[i].Event.KeyEvent.bKeyDown &&
ir[i].Event.KeyEvent.uChar.AsciiChar)
{
retval = 1;
break;
}
}
if (ir)
MSVCRT_free(ir);
}
UNLOCK_CONSOLE;
return retval;
}
extern int snprintf(char *, int, const char *, ...);
/*********************************************************************
* _cprintf (MSVCRT.@)
*/
int __cdecl MSVCRT__cprintf( const char * format, ... )
{
char buf[2048], *mem = buf;
int written, resize = sizeof(buf), retval;
va_list valist;
va_start( valist, format );
/* There are two conventions for snprintf failing:
* Return -1 if we truncated, or
* Return the number of bytes that would have been written
* The code below handles both cases
*/
while ((written = snprintf( mem, resize, format, valist )) == -1 ||
written > resize)
{
resize = (written == -1 ? resize * 2 : written + 1);
if (mem != buf)
MSVCRT_free (mem);
if (!(mem = (char *)MSVCRT_malloc(resize)))
return MSVCRT_EOF;
va_start( valist, format );
}
va_end(valist);
LOCK_CONSOLE;
retval = MSVCRT__cputs( mem );
UNLOCK_CONSOLE;
if (mem != buf)
MSVCRT_free (mem);
return retval;
}
/*
* msvcrt.dll C++ objects
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
void __cdecl MSVCRT__purecall(void);
typedef void (__cdecl *v_table_ptr)();
static v_table_ptr exception_vtable[2];
static v_table_ptr bad_typeid_vtable[3];
static v_table_ptr __non_rtti_object_vtable[3];
static v_table_ptr bad_cast_vtable[3];
static v_table_ptr type_info_vtable[1];
typedef struct __exception
{
v_table_ptr *vtable;
const char *name;
int do_free; /* FIXME: take string copy with char* ctor? */
} exception;
typedef struct __bad_typeid
{
exception base;
} bad_typeid;
typedef struct ____non_rtti_object
{
bad_typeid base;
} __non_rtti_object;
typedef struct __bad_cast
{
exception base;
} bad_cast;
typedef struct __type_info
{
v_table_ptr *vtable;
void *data;
char name[1];
} type_info;
/******************************************************************
* ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_exception_ctor(exception * _this, const char ** name)
{
TRACE("(%p %s)\n",_this,*name);
_this->vtable = exception_vtable;
_this->name = *name;
TRACE("name = %s\n",_this->name);
_this->do_free = 0; /* FIXME */
}
/******************************************************************
* ??0exception@@QAE@ABV0@@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
if (_this != rhs)
memcpy (_this, rhs, sizeof (*_this));
TRACE("name = %s\n",_this->name);
}
/******************************************************************
* ??0exception@@QAE@XZ (MSVCRT.@)
*/
void __cdecl MSVCRT_exception_default_ctor(exception * _this)
{
TRACE("(%p)\n",_this);
_this->vtable = exception_vtable;
_this->name = "";
_this->do_free = 0; /* FIXME */
}
/******************************************************************
* ??1exception@@UAE@XZ (MSVCRT.@)
*/
void __cdecl MSVCRT_exception_dtor(exception * _this)
{
TRACE("(%p)\n",_this);
}
/******************************************************************
* ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
exception * __cdecl MSVCRT_exception_opequals(exception * _this, const exception * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
memcpy (_this, rhs, sizeof (*_this));
TRACE("name = %s\n",_this->name);
return _this;
}
/******************************************************************
* ??_Eexception@@UAEPAXI@Z (MSVCRT.@)
*/
void * __cdecl MSVCRT_exception__unknown_E(exception * _this, unsigned int arg1)
{
TRACE("(%p %d)\n",_this,arg1);
MSVCRT__purecall();
return NULL;
}
/******************************************************************
* ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
*/
void * __cdecl MSVCRT_exception__unknown_G(exception * _this, unsigned int arg1)
{
TRACE("(%p %d)\n",_this,arg1);
MSVCRT__purecall();
return NULL;
}
/******************************************************************
* ?what@exception@@UBEPBDXZ (MSVCRT.@)
*/
const char * __stdcall MSVCRT_exception_what(exception * _this)
{
TRACE("(%p) returning %s\n",_this,_this->name);
return _this->name;
}
/******************************************************************
* ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
MSVCRT_exception_copy_ctor(&_this->base,&rhs->base);
}
/******************************************************************
* ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name)
{
TRACE("(%p %s)\n",_this,name);
MSVCRT_exception_ctor(&_this->base, &name);
_this->base.vtable = bad_typeid_vtable;
}
/******************************************************************
* ??1bad_typeid@@UAE@XZ (MSVCRT.@)
*/
void __cdecl MSVCRT_bad_typeid_dtor(bad_typeid * _this)
{
TRACE("(%p)\n",_this);
MSVCRT_exception_dtor(&_this->base);
}
/******************************************************************
* ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
bad_typeid * __cdecl MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
MSVCRT_exception_copy_ctor(&_this->base,&rhs->base);
return _this;
}
/******************************************************************
* ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
*/
void __cdecl MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this,
const __non_rtti_object * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
MSVCRT_bad_typeid_copy_ctor(&_this->base,&rhs->base);
}
/******************************************************************
* ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
*/
void __cdecl MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this,
const char * name)
{
TRACE("(%p %s)\n",_this,name);
MSVCRT_bad_typeid_ctor(&_this->base,name);
_this->base.base.vtable = __non_rtti_object_vtable;
}
/******************************************************************
* ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
*/
void __cdecl MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this)
{
TRACE("(%p)\n",_this);
MSVCRT_bad_typeid_dtor(&_this->base);
}
/******************************************************************
* ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
__non_rtti_object * __cdecl MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this,
const __non_rtti_object *rhs)
{
TRACE("(%p %p)\n",_this,rhs);
memcpy (_this, rhs, sizeof (*_this));
TRACE("name = %s\n",_this->base.base.name);
return _this;
}
/******************************************************************
* ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
*/
void * __cdecl MSVCRT___non_rtti_object__unknown_E(__non_rtti_object * _this, unsigned int arg1)
{
TRACE("(%p %d)\n",_this,arg1);
MSVCRT__purecall();
return NULL;
}
/******************************************************************
* ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
*/
void * __cdecl MSVCRT___non_rtti_object__unknown_G(__non_rtti_object * _this, unsigned int arg1)
{
TRACE("(%p %d)\n",_this,arg1);
MSVCRT__purecall();
return NULL;
}
/******************************************************************
* ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name)
{
TRACE("(%p %s)\n",_this,*name);
MSVCRT_exception_ctor(&_this->base, name);
_this->base.vtable = bad_cast_vtable;
}
/******************************************************************
* ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
MSVCRT_exception_copy_ctor(&_this->base,&rhs->base);
}
/******************************************************************
* ??1bad_cast@@UAE@XZ (MSVCRT.@)
*/
void __cdecl MSVCRT_bad_cast_dtor(bad_cast * _this)
{
TRACE("(%p)\n",_this);
MSVCRT_exception_dtor(&_this->base);
}
/******************************************************************
* ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
*/
bad_cast * __cdecl MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs)
{
TRACE("(%p %p)\n",_this,rhs);
MSVCRT_exception_copy_ctor(&_this->base,&rhs->base);
return _this;
}
/******************************************************************
* ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
*/
int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs)
{
TRACE("(%p %p) returning %d\n",_this,rhs,_this->name == rhs->name);
return _this->name == rhs->name;
}
/******************************************************************
* ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
*/
int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs)
{
TRACE("(%p %p) returning %d\n",_this,rhs,_this->name == rhs->name);
return _this->name != rhs->name;
}
/******************************************************************
* ??1type_info@@UAE@XZ (MSVCRT.@)
*/
void __cdecl MSVCRT_type_info_dtor(type_info * _this)
{
TRACE("(%p)\n",_this);
if (_this->data)
MSVCRT_free(_this->data);
}
/******************************************************************
* ?name@type_info@@QBEPBDXZ (MSVCRT.@)
*/
const char * __stdcall MSVCRT_type_info_name(type_info * _this)
{
TRACE("(%p) returning %s\n",_this,_this->name);
return _this->name;
}
/******************************************************************
* ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
*/
const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this)
{
TRACE("(%p) returning %s\n",_this,_this->name);
return _this->name;
}
/* INTERNAL: Set up vtables
* FIXME:should be static, cope with versions?
*/
void MSVCRT_init_vtables(void)
{
exception_vtable[0] = MSVCRT_exception_dtor;
exception_vtable[1] = (void*)MSVCRT_exception_what;
bad_typeid_vtable[0] = MSVCRT_bad_typeid_dtor;
bad_typeid_vtable[1] = exception_vtable[1];
bad_typeid_vtable[2] = MSVCRT__purecall; /* FIXME */
__non_rtti_object_vtable[0] = MSVCRT___non_rtti_object_dtor;
__non_rtti_object_vtable[1] = bad_typeid_vtable[1];
__non_rtti_object_vtable[2] = bad_typeid_vtable[2];
bad_cast_vtable[0] = MSVCRT_bad_cast_dtor;
bad_cast_vtable[1] = exception_vtable[1];
bad_cast_vtable[2] = MSVCRT__purecall; /* FIXME */
type_info_vtable[0] = MSVCRT_type_info_dtor;
}
/*
* msvcrt.dll ctype functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* ASCII char classification table - binary compatible */
#define MSVCRT_UPPER C1_UPPER
#define MSVCRT_LOWER C1_LOWER
#define MSVCRT_DIGIT C1_DIGIT
#define MSVCRT_SPACE C1_SPACE
#define MSVCRT_PUNCT C1_PUNCT
#define MSVCRT_CONTROL C1_CNTRL
#define MSVCRT_BLANK C1_BLANK
#define MSVCRT_HEX C1_XDIGIT
#define MSVCRT_LEADBYTE 0x8000
#define MSVCRT_ALPHA (C1_ALPHA|MSVCRT_UPPER|MSVCRT_LOWER)
#define _C_ MSVCRT_CONTROL
#define _S_ MSVCRT_SPACE
#define _P_ MSVCRT_PUNCT
#define _D_ MSVCRT_DIGIT
#define _H_ MSVCRT_HEX
#define _U_ MSVCRT_UPPER
#define _L_ MSVCRT_LOWER
WORD MSVCRT__ctype [257] = {
0, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_, _S_|_C_,
_S_|_C_, _S_|_C_, _S_|_C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
_C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|MSVCRT_BLANK,
_P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_,
_P_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_,
_D_|_H_, _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _U_|_H_,
_U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_, _U_, _U_,
_U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_,
_U_, _P_, _P_, _P_, _P_, _P_, _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_,
_L_|_H_, _L_|_H_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_,
_L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_,
_C_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Internal: Current ctype table for locale */
WORD MSVCRT_current_ctype[257];
/* pctype is used by macros in the Win32 headers. It must point
* To a table of flags exactly like ctype. To allow locale
* changes to affect ctypes (i.e. isleadbyte), we use a second table
* and update its flags whenever the current locale changes.
*/
WORD* MSVCRT__pctype = MSVCRT_current_ctype + 1;
/* mbctype data */
extern int MSVCRT___mb_cur_max;
extern LCID MSVCRT_current_lc_all_lcid;
/*********************************************************************
* MSVCRT___p__pctype (MSVCRT.@)
*/
WORD** MSVCRT___p__pctype(void)
{
return &MSVCRT__pctype;
}
/*********************************************************************
* _isctype (MSVCRT.@)
*/
int __cdecl MSVCRT__isctype(int c, int type)
{
if (c >= -1 && c <= 255)
return MSVCRT__pctype[c] & type;
if (MSVCRT___mb_cur_max != 1 && c > 0)
{
/* FIXME: Is there a faster way to do this? */
WORD typeInfo;
char convert[3], *pconv = convert;
if (MSVCRT__pctype[(UINT)c >> 8] & MSVCRT_LEADBYTE)
*pconv++ = (UINT)c >> 8;
*pconv++ = c & 0xff;
*pconv = 0;
/* FIXME: Use ctype LCID, not lc_all */
if (GetStringTypeExA(MSVCRT_current_lc_all_lcid, CT_CTYPE1,
convert, convert[1] ? 2 : 1, &typeInfo))
return typeInfo & type;
}
return 0;
}
/*********************************************************************
* isalnum (MSVCRT.@)
*/
int __cdecl MSVCRT_isalnum(int c)
{
return MSVCRT__isctype( c,MSVCRT_ALPHA | MSVCRT_DIGIT );
}
/*********************************************************************
* isalpha (MSVCRT.@)
*/
int __cdecl MSVCRT_isalpha(int c)
{
return MSVCRT__isctype( c, MSVCRT_ALPHA );
}
/*********************************************************************
* iscntrl (MSVCRT.@)
*/
int __cdecl MSVCRT_iscntrl(int c)
{
return MSVCRT__isctype( c, MSVCRT_CONTROL );
}
/*********************************************************************
* isdigit (MSVCRT.@)
*/
int __cdecl MSVCRT_isdigit(int c)
{
return MSVCRT__isctype( c, MSVCRT_DIGIT );
}
/*********************************************************************
* isgraph (MSVCRT.@)
*/
int __cdecl MSVCRT_isgraph(int c)
{
return MSVCRT__isctype( c, MSVCRT_ALPHA | MSVCRT_DIGIT | MSVCRT_PUNCT );
}
/*********************************************************************
* isleadbyte (MSVCRT.@)
*/
int __cdecl MSVCRT_isleadbyte(int c)
{
return MSVCRT__isctype( c, MSVCRT_LEADBYTE );
}
/*********************************************************************
* islower (MSVCRT.@)
*/
int __cdecl MSVCRT_islower(int c)
{
return MSVCRT__isctype( c, MSVCRT_LOWER );
}
/*********************************************************************
* isprint (MSVCRT.@)
*/
int __cdecl MSVCRT_isprint(int c)
{
return MSVCRT__isctype( c, MSVCRT_ALPHA | MSVCRT_DIGIT |
MSVCRT_BLANK | MSVCRT_PUNCT );
}
/*********************************************************************
* ispunct (MSVCRT.@)
*/
int __cdecl MSVCRT_ispunct(int c)
{
return MSVCRT__isctype( c, MSVCRT_PUNCT );
}
/*********************************************************************
* isspace (MSVCRT.@)
*/
int __cdecl MSVCRT_isspace(int c)
{
return MSVCRT__isctype( c, MSVCRT_SPACE );
}
/*********************************************************************
* isupper (MSVCRT.@)
*/
int __cdecl MSVCRT_isupper(int c)
{
return MSVCRT__isctype( c, MSVCRT_UPPER );
}
/*********************************************************************
* isxdigit (MSVCRT.@)
*/
int __cdecl MSVCRT_isxdigit(int c)
{
return MSVCRT__isctype( c, MSVCRT_HEX );
}
/*********************************************************************
* __isascii (MSVCRT.@)
*/
int __cdecl MSVCRT___isascii(int c)
{
return isascii((unsigned)c);
}
/*********************************************************************
* __toascii (MSVCRT.@)
*/
int __cdecl MSVCRT___toascii(int c)
{
return (unsigned)c & 0x7f;
}
/*********************************************************************
* iswascii (MSVCRT.@)
*
*/
int __cdecl MSVCRT_iswascii(WCHAR c)
{
return ((unsigned)c < 0x80);
}
/*********************************************************************
* __iscsym (MSVCRT.@)
*/
int __cdecl MSVCRT___iscsym(int c)
{
return (c < 127 && (isalnum(c) || c == '_'));
}
/*********************************************************************
* __iscsymf (MSVCRT.@)
*/
int __cdecl MSVCRT___iscsymf(int c)
{
return (c < 127 && (isalpha(c) || c == '_'));
}
/*********************************************************************
* _toupper (MSVCRT.@)
*/
int __cdecl MSVCRT__toupper(int c)
{
return toupper(c);
}
/*********************************************************************
* _tolower (MSVCRT.@)
*/
int __cdecl MSVCRT__tolower(int c)
{
return tolower(c);
}
/*
* msvcrt.dll dll data items
*
* Copyright 2000 Jon Griffiths
*/
#include <math.h>
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
unsigned int MSVCRT___argc;
unsigned int MSVCRT_basemajor;/* FIXME: */
unsigned int MSVCRT_baseminor;/* FIXME: */
unsigned int MSVCRT_baseversion; /* FIXME: */
unsigned int MSVCRT__commode;
unsigned int MSVCRT__fmode;
unsigned int MSVCRT_osmajor;/* FIXME: */
unsigned int MSVCRT_osminor;/* FIXME: */
unsigned int MSVCRT_osmode;/* FIXME: */
unsigned int MSVCRT__osver;
unsigned int MSVCRT_osversion; /* FIXME: */
unsigned int MSVCRT__winmajor;
unsigned int MSVCRT__winminor;
unsigned int MSVCRT__winver;
unsigned int MSVCRT__sys_nerr;
unsigned int MSVCRT___setlc_active;
unsigned int MSVCRT___unguarded_readlc_active;
double MSVCRT__HUGE;
char **MSVCRT___argv;
WCHAR **MSVCRT___wargv;
char *MSVCRT__acmdln;
WCHAR *MSVCRT__wcmdln;
char *MSVCRT__environ;
WCHAR *MSVCRT__wenviron;
char **MSVCRT___initenv;
WCHAR **MSVCRT___winitenv;
int MSVCRT_timezone;
int MSVCRT_app_type;
typedef void (__cdecl *MSVCRT__INITTERMFUN)(void);
char * __cdecl MSVCRT__strdup(const char *);
/* Data access functions */
#define GET_UINT_PTR(x) unsigned int __cdecl *MSVCRT___p_##x(void) { return &MSVCRT_##x; }
GET_UINT_PTR(__argc)
GET_UINT_PTR(_commode)
GET_UINT_PTR(_fmode)
GET_UINT_PTR(_osver)
GET_UINT_PTR(_winmajor)
GET_UINT_PTR(_winminor)
GET_UINT_PTR(_winver)
char **__cdecl MSVCRT___p__acmdln(void) { return &MSVCRT__acmdln; }
WCHAR **__cdecl MSVCRT___p__wcmdln(void) { return &MSVCRT__wcmdln; }
char ***__cdecl MSVCRT___p___argv(void) { return &MSVCRT___argv; }
WCHAR ***__cdecl MSVCRT___p___wargv(void) { return &MSVCRT___wargv; }
char **__cdecl MSVCRT___p__environ(void) { return &MSVCRT__environ; }
WCHAR **__cdecl MSVCRT___p__wenviron(void) { return &MSVCRT__wenviron; }
char ***__cdecl MSVCRT___p___initenv(void) { return &MSVCRT___initenv; }
WCHAR ***__cdecl MSVCRT___p___winitenv(void) { return &MSVCRT___winitenv; }
int *__cdecl MSVCRT___p__timezone(void) { return &MSVCRT_timezone; }
/* INTERNAL: Create a wide string from an ascii string */
static WCHAR *wstrdupa(const char *str)
{
const size_t len = strlen(str) + 1 ;
WCHAR *wstr = MSVCRT_malloc(len* sizeof (WCHAR));
if (!wstr)
return NULL;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len*sizeof(char),wstr,len* sizeof (WCHAR));
return wstr;
}
/* INTERNAL: Since we can't rely on Winelib startup code calling w/getmainargs,
* we initialise data values during DLL loading. The when called by a native
* program we simply return the data we've already initialised. This also means
* you can call multiple times without leaking
*/
void MSVCRT_init_args(void)
{
char *cmdline, **xargv = NULL;
WCHAR *wcmdline, **wxargv = NULL;
int xargc,end,last_arg,afterlastspace;
DWORD version;
MSVCRT__acmdln = cmdline = MSVCRT__strdup( GetCommandLineA() );
MSVCRT__wcmdln = wcmdline = wstrdupa(cmdline);
TRACE("got '%s', wide = '%s'\n", cmdline, debugstr_w(wcmdline));
version = GetVersion();
MSVCRT__osver = version >> 16;
MSVCRT__winminor = version & 0xFF;
MSVCRT__winmajor = (version>>8) & 0xFF;
MSVCRT_baseversion = version >> 16;
MSVCRT__winver = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
MSVCRT_baseminor = (version >> 16) & 0xFF;
MSVCRT_basemajor = (version >> 24) & 0xFF;
MSVCRT_osversion = version & 0xFFFF;
MSVCRT_osminor = version & 0xFF;
MSVCRT_osmajor = (version>>8) & 0xFF;
MSVCRT__sys_nerr = 43;
MSVCRT__HUGE = HUGE_VAL;
MSVCRT___setlc_active = 0;
MSVCRT___unguarded_readlc_active = 0;
MSVCRT_timezone = 0;
/* FIXME: set app type for Winelib apps */
end = last_arg = xargc = afterlastspace = 0;
while (1)
{
if ((cmdline[end]==' ') || (cmdline[end]=='\0'))
{
if (cmdline[end]=='\0')
last_arg=1;
else
cmdline[end]='\0';
/* alloc xargc + NULL entry */
xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
sizeof(char*)*(xargc+1));
wxargv=(WCHAR**)HeapReAlloc( GetProcessHeap(), 0, wxargv,
sizeof(WCHAR*)*(xargc+1));
if (strlen(cmdline+afterlastspace))
{
xargv[xargc] = MSVCRT__strdup(cmdline+afterlastspace);
wxargv[xargc] = wstrdupa(xargv[xargc]);
xargc++;
if (!last_arg) /* need to seek to the next arg ? */
{
end++;
while (cmdline[end]==' ')
end++;
}
afterlastspace=end;
}
else
{
xargv[xargc] = NULL;
wxargv[xargc] = NULL; /* the last entry is NULL */
break;
}
}
else
end++;
}
MSVCRT___argc = xargc;
MSVCRT___argv = xargv;
MSVCRT___wargv = wxargv;
TRACE("found %d arguments\n",MSVCRT___argc);
MSVCRT__environ = GetEnvironmentStringsA();
MSVCRT___initenv = &MSVCRT__environ;
MSVCRT__wenviron = GetEnvironmentStringsW();
MSVCRT___winitenv = &MSVCRT__wenviron;
}
/* INTERNAL: free memory used by args */
void MSVCRT_free_args(void)
{
/* FIXME */
}
/*********************************************************************
* __getmainargs (MSVCRT.@)
*/
char** __cdecl MSVCRT___getmainargs(DWORD *argc,char ***argv,char **environ,DWORD flag)
{
TRACE("(%p,%p,%p,%ld).\n",argc,argv,environ,flag);
*argc = MSVCRT___argc;
*argv = MSVCRT___argv;
*environ = MSVCRT__environ;
return environ;
}
/*********************************************************************
* __wgetmainargs (MSVCRT.@)
*/
WCHAR** __cdecl MSVCRT___wgetmainargs(DWORD *argc,WCHAR ***wargv,WCHAR **wenviron,DWORD flag)
{
TRACE("(%p,%p,%p,%ld).\n",argc,wargv,wenviron,flag);
*argc = MSVCRT___argc;
*wargv = MSVCRT___wargv;
*wenviron = MSVCRT__wenviron;
return wenviron;
}
/*********************************************************************
* _initterm (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__initterm(MSVCRT__INITTERMFUN *start,MSVCRT__INITTERMFUN *end)
{
MSVCRT__INITTERMFUN*current = start;
TRACE("(%p,%p)\n",start,end);
while (current<end)
{
if (*current)
{
TRACE("Call init function %p\n",*current);
(**current)();
TRACE("returned\n");
}
current++;
}
return 0;
}
/*********************************************************************
* __set_app_type (MSVCRT.@)
*/
void __cdecl MSVCRT___set_app_type(int app_type)
{
TRACE("(%d) %s application\n", app_type, app_type == 2 ? "Gui" : "Console");
MSVCRT_app_type = app_type;
}
/*
* msvcrt.dll drive/directory functions
*
* Copyright 1996,1998 Marcus Meissner
* Copyright 1996 Jukka Iivonen
* Copyright 1997,2000 Uwe Bonnes
* Copyright 2000 Jon Griffiths
*/
#include <time.h>
#include "ntddk.h"
#include "wine/unicode.h"
#include "msvcrt.h"
#include "ms_errno.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef struct MSVCRT_finddata_t
{
unsigned attrib;
time_t time_create; /* -1 when N/A */
time_t time_access; /* -1 when N/A */
time_t time_write;
unsigned long size; /* FIXME: 64 bit ??*/
char name[MAX_PATH];
} MSVCRT_finddata_t;
typedef struct MSVCRT_wfinddata_t
{
unsigned attrib;
time_t time_create; /* -1 when N/A */
time_t time_access; /* -1 when N/A */
time_t time_write;
unsigned long size; /* FIXME: 64 bit ??*/
WCHAR name[MAX_PATH];
} MSVCRT_wfinddata_t;
typedef struct __MSVCRT_diskfree_t {
unsigned num_clusters;
unsigned available;
unsigned cluster_sectors;
unsigned sector_bytes;
} MSVCRT_diskfree_t;
/* INTERNAL: Translate finddata_t to PWIN32_FIND_DATAA */
static void MSVCRT__fttofd(LPWIN32_FIND_DATAA fd, MSVCRT_finddata_t* ft)
{
DWORD dw;
if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
ft->attrib = 0;
else
ft->attrib = fd->dwFileAttributes;
RtlTimeToSecondsSince1970( &fd->ftCreationTime, &dw );
ft->time_create = dw;
RtlTimeToSecondsSince1970( &fd->ftLastAccessTime, &dw );
ft->time_access = dw;
RtlTimeToSecondsSince1970( &fd->ftLastWriteTime, &dw );
ft->time_write = dw;
ft->size = fd->nFileSizeLow;
strcpy(ft->name, fd->cFileName);
}
/* INTERNAL: Translate wfinddata_t to PWIN32_FIND_DATAA */
static void MSVCRT__wfttofd(LPWIN32_FIND_DATAW fd, MSVCRT_wfinddata_t* ft)
{
DWORD dw;
if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL)
ft->attrib = 0;
else
ft->attrib = fd->dwFileAttributes;
RtlTimeToSecondsSince1970( &fd->ftCreationTime, &dw );
ft->time_create = dw;
RtlTimeToSecondsSince1970( &fd->ftLastAccessTime, &dw );
ft->time_access = dw;
RtlTimeToSecondsSince1970( &fd->ftLastWriteTime, &dw );
ft->time_write = dw;
ft->size = fd->nFileSizeLow;
strcpyW(ft->name, fd->cFileName);
}
char * MSVCRT__strndup(const char *, unsigned int);
LPWSTR __cdecl MSVCRT__wcsdup( LPCWSTR );
LPWSTR __cdecl MSVCRT__wstrndup( LPCWSTR , unsigned int );
char *__cdecl MSVCRT_getenv(const char *);
/*********************************************************************
* _chdir (MSVCRT.@)
*/
int __cdecl MSVCRT__chdir(const char * newdir)
{
if (!SetCurrentDirectoryA(newdir))
{
MSVCRT__set_errno(newdir?GetLastError():0);
return -1;
}
return 0;
}
/*********************************************************************
* _wchdir (MSVCRT.@)
*/
int __cdecl MSVCRT__wchdir(const WCHAR * newdir)
{
if (!SetCurrentDirectoryW(newdir))
{
MSVCRT__set_errno(newdir?GetLastError():0);
return -1;
}
return 0;
}
/*********************************************************************
* _chdrive (MSVCRT.@)
*/
int __cdecl MSVCRT__chdrive(int newdrive)
{
char buffer[3] = "A:";
buffer[0] += newdrive - 1;
if (!SetCurrentDirectoryA( buffer ))
{
MSVCRT__set_errno(GetLastError());
if (newdrive <= 0)
SET_THREAD_VAR(errno,MSVCRT_EACCES);
return -1;
}
return 0;
}
/*********************************************************************
* _findclose (MSVCRT.@)
*/
int __cdecl MSVCRT__findclose(DWORD hand)
{
TRACE(":handle %ld\n",hand);
if (!FindClose((HANDLE)hand))
{
MSVCRT__set_errno(GetLastError());
return -1;
}
return 0;
}
/*********************************************************************
* _findfirst (MSVCRT.@)
*/
DWORD __cdecl MSVCRT__findfirst(const char * fspec, MSVCRT_finddata_t* ft)
{
WIN32_FIND_DATAA find_data;
HANDLE hfind;
hfind = FindFirstFileA(fspec, &find_data);
if (hfind == INVALID_HANDLE_VALUE)
{
MSVCRT__set_errno(GetLastError());
return -1;
}
MSVCRT__fttofd(&find_data,ft);
TRACE(":got handle %d\n",hfind);
return hfind;
}
/*********************************************************************
* _wfindfirst (MSVCRT.@)
*/
DWORD __cdecl MSVCRT__wfindfirst(const WCHAR * fspec, MSVCRT_wfinddata_t* ft)
{
WIN32_FIND_DATAW find_data;
HANDLE hfind;
hfind = FindFirstFileW(fspec, &find_data);
if (hfind == INVALID_HANDLE_VALUE)
{
MSVCRT__set_errno(GetLastError());
return -1;
}
MSVCRT__wfttofd(&find_data,ft);
TRACE(":got handle %d\n",hfind);
return hfind;
}
/*********************************************************************
* _findnext (MSVCRT.@)
*/
int __cdecl MSVCRT__findnext(DWORD hand, MSVCRT_finddata_t * ft)
{
WIN32_FIND_DATAA find_data;
if (!FindNextFileA(hand, &find_data))
{
SET_THREAD_VAR(errno,MSVCRT_ENOENT);
return -1;
}
MSVCRT__fttofd(&find_data,ft);
return 0;
}
/*********************************************************************
* _wfindnext (MSVCRT.@)
*/
int __cdecl MSVCRT__wfindnext(DWORD hand, MSVCRT_wfinddata_t * ft)
{
WIN32_FIND_DATAW find_data;
if (!FindNextFileW(hand, &find_data))
{
SET_THREAD_VAR(errno,MSVCRT_ENOENT);
return -1;
}
MSVCRT__wfttofd(&find_data,ft);
return 0;
}
/*********************************************************************
* _getcwd (MSVCRT.@)
*/
char* __cdecl MSVCRT__getcwd(char * buf, int size)
{
char dir[_MAX_PATH];
int dir_len = GetCurrentDirectoryA(MAX_PATH,dir);
if (dir_len < 1)
return NULL; /* FIXME: Real return value untested */
if (!buf)
{
if (size < 0)
return MSVCRT__strdup(dir);
return MSVCRT__strndup(dir,size);
}
if (dir_len >= size)
{
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return NULL; /* buf too small */
}
strcpy(buf,dir);
return buf;
}
/*********************************************************************
* _wgetcwd (MSVCRT.@)
*/
WCHAR* __cdecl MSVCRT__wgetcwd(WCHAR * buf, int size)
{
WCHAR dir[_MAX_PATH];
int dir_len = GetCurrentDirectoryW(MAX_PATH,dir);
if (dir_len < 1)
return NULL; /* FIXME: Real return value untested */
if (!buf)
{
if (size < 0)
return MSVCRT__wcsdup(dir);
return MSVCRT__wstrndup(dir,size);
}
if (dir_len >= size)
{
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return NULL; /* buf too small */
}
strcpyW(buf,dir);
return buf;
}
/*********************************************************************
* _getdrive (MSVCRT.@)
*/
int __cdecl MSVCRT__getdrive(void)
{
char buffer[MAX_PATH];
if (!GetCurrentDirectoryA( sizeof(buffer), buffer )) return 0;
if (buffer[1] != ':') return 0;
return toupper(buffer[0]) - 'A' + 1;
}
/*********************************************************************
* _getdcwd (MSVCRT.@)
*/
char* __cdecl MSVCRT__getdcwd(int drive, char * buf, int size)
{
static char* dummy;
TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
if (!drive || drive == MSVCRT__getdrive())
return MSVCRT__getcwd(buf,size); /* current */
else
{
char dir[_MAX_PATH];
char drivespec[4] = {'A', ':', '\\', 0};
int dir_len;
drivespec[0] += drive - 1;
if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
{
SET_THREAD_VAR(errno,MSVCRT_EACCES);
return NULL;
}
dir_len = GetFullPathNameA(drivespec,_MAX_PATH,dir,&dummy);
if (dir_len >= size || dir_len < 1)
{
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return NULL; /* buf too small */
}
TRACE(":returning '%s'\n", dir);
if (!buf)
return MSVCRT__strdup(dir); /* allocate */
strcpy(buf,dir);
}
return buf;
}
/*********************************************************************
* _wgetdcwd (MSVCRT.@)
*/
WCHAR* __cdecl MSVCRT__wgetdcwd(int drive, WCHAR * buf, int size)
{
static WCHAR* dummy;
TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
if (!drive || drive == MSVCRT__getdrive())
return MSVCRT__wgetcwd(buf,size); /* current */
else
{
WCHAR dir[_MAX_PATH];
WCHAR drivespec[4] = {'A', ':', '\\', 0};
int dir_len;
drivespec[0] += drive - 1;
if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE)
{
SET_THREAD_VAR(errno,MSVCRT_EACCES);
return NULL;
}
dir_len = GetFullPathNameW(drivespec,_MAX_PATH,dir,&dummy);
if (dir_len >= size || dir_len < 1)
{
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return NULL; /* buf too small */
}
TRACE(":returning '%s'\n", debugstr_w(dir));
if (!buf)
return MSVCRT__wcsdup(dir); /* allocate */
strcpyW(buf,dir);
}
return buf;
}
/*********************************************************************
* _getdiskfree (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__getdiskfree(unsigned int disk, MSVCRT_diskfree_t* d)
{
char drivespec[4] = {'@', ':', '\\', 0};
DWORD ret[4];
unsigned int err;
if (disk > 26)
return ERROR_INVALID_PARAMETER; /* MSVCRT doesn't set errno here */
drivespec[0] += disk; /* make a drive letter */
if (GetDiskFreeSpaceA(disk==0?NULL:drivespec,ret,ret+1,ret+2,ret+3))
{
d->cluster_sectors = (unsigned)ret[0];
d->sector_bytes = (unsigned)ret[1];
d->available = (unsigned)ret[2];
d->num_clusters = (unsigned)ret[3];
return 0;
}
err = GetLastError();
MSVCRT__set_errno(err);
return err;
}
/*********************************************************************
* _mkdir (MSVCRT.@)
*/
int __cdecl MSVCRT__mkdir(const char * newdir)
{
if (CreateDirectoryA(newdir,NULL))
return 0;
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* _wmkdir (MSVCRT.@)
*/
int __cdecl MSVCRT__wmkdir(const WCHAR* newdir)
{
if (CreateDirectoryW(newdir,NULL))
return 0;
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* _rmdir (MSVCRT.@)
*/
int __cdecl MSVCRT__rmdir(const char * dir)
{
if (RemoveDirectoryA(dir))
return 0;
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* _wrmdir (MSVCRT.@)
*/
int __cdecl MSVCRT__wrmdir(const WCHAR * dir)
{
if (RemoveDirectoryW(dir))
return 0;
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* _splitpath (MSVCRT.@)
*/
void __cdecl MSVCRT__splitpath(const char* inpath, char * drv, char * dir,
char* fname, char * ext )
{
/* Modified PD code from 'snippets' collection. */
char ch, *ptr, *p;
char pathbuff[MAX_PATH],*path=pathbuff;
TRACE(":splitting path '%s'\n",path);
strcpy(pathbuff, inpath);
/* convert slashes to backslashes for searching */
for (ptr = (char*)path; *ptr; ++ptr)
if ('/' == *ptr)
*ptr = '\\';
/* look for drive spec */
if ('\0' != (ptr = strchr(path, ':')))
{
++ptr;
if (drv)
{
strncpy(drv, path, ptr - path);
drv[ptr - path] = '\0';
}
path = ptr;
}
else if (drv)
*drv = '\0';
/* find rightmost backslash or leftmost colon */
if (NULL == (ptr = strrchr(path, '\\')))
ptr = (strchr(path, ':'));
if (!ptr)
{
ptr = (char *)path; /* no path */
if (dir)
*dir = '\0';
}
else
{
++ptr; /* skip the delimiter */
if (dir)
{
ch = *ptr;
*ptr = '\0';
strcpy(dir, path);
*ptr = ch;
}
}
if (NULL == (p = strrchr(ptr, '.')))
{
if (fname)
strcpy(fname, ptr);
if (ext)
*ext = '\0';
}
else
{
*p = '\0';
if (fname)
strcpy(fname, ptr);
*p = '.';
if (ext)
strcpy(ext, p);
}
/* Fix pathological case - Win returns ':' as part of the
* directory when no drive letter is given.
*/
if (drv && drv[0] == ':')
{
*drv = '\0';
if (dir)
{
pathbuff[0] = ':';
pathbuff[1] = '\0';
strcat(pathbuff,dir);
strcpy(dir,pathbuff);
}
}
}
/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
static void fln_fix(char *path)
{
int dir_flag = 0, root_flag = 0;
char *r, *p, *q, *s;
/* Skip drive */
if (NULL == (r = strrchr(path, ':')))
r = path;
else
++r;
/* Ignore leading slashes */
while ('\\' == *r)
if ('\\' == r[1])
strcpy(r, &r[1]);
else
{
root_flag = 1;
++r;
}
p = r; /* Change "\\" to "\" */
while (NULL != (p = strchr(p, '\\')))
if ('\\' == p[1])
strcpy(p, &p[1]);
else
++p;
while ('.' == *r) /* Scrunch leading ".\" */
{
if ('.' == r[1])
{
/* Ignore leading ".." */
for (p = (r += 2); *p && (*p != '\\'); ++p)
;
}
else
{
for (p = r + 1 ;*p && (*p != '\\'); ++p)
;
}
strcpy(r, p + ((*p) ? 1 : 0));
}
while ('\\' == path[strlen(path)-1]) /* Strip last '\\' */
{
dir_flag = 1;
path[strlen(path)-1] = '\0';
}
s = r;
/* Look for "\." in path */
while (NULL != (p = strstr(s, "\\.")))
{
if ('.' == p[2])
{
/* Execute this section if ".." found */
q = p - 1;
while (q > r) /* Backup one level */
{
if (*q == '\\')
break;
--q;
}
if (q > r)
{
strcpy(q, p + 3);
s = q;
}
else if ('.' != *q)
{
strcpy(q + ((*q == '\\') ? 1 : 0),
p + 3 + ((*(p + 3)) ? 1 : 0));
s = q;
}
else s = ++p;
}
else
{
/* Execute this section if "." found */
q = p + 2;
for ( ;*q && (*q != '\\'); ++q)
;
strcpy (p, q);
}
}
if (root_flag) /* Embedded ".." could have bubbled up to root */
{
for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
;
if (r != p)
strcpy(r, p);
}
if (dir_flag)
strcat(path, "\\");
}
/*********************************************************************
* _fullpath (MSVCRT.@)
*/
LPSTR __cdecl MSVCRT__fullpath(char * absPath, const char* relPath, unsigned int size)
{
char drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
char res[MAX_PATH];
size_t len;
res[0] = '\0';
if (!relPath || !*relPath)
return MSVCRT__getcwd(absPath, size);
if (size < 4)
{
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return NULL;
}
TRACE(":resolving relative path '%s'\n",relPath);
MSVCRT__splitpath(relPath, drive, dir, file, ext);
/* Get Directory and drive into 'res' */
if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
{
/* Relative or no directory given */
MSVCRT__getdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 : 0, res, MAX_PATH);
strcat(res,"\\");
if (dir[0])
strcat(res,dir);
if (drive[0])
res[0] = drive[0]; /* If given a drive, preserve the letter case */
}
else
{
strcpy(res,drive);
strcat(res,dir);
}
strcat(res,"\\");
strcat(res, file);
strcat(res, ext);
fln_fix(res);
len = strlen(res);
if (len >= MAX_PATH || len >= (size_t)size)
return NULL; /* FIXME: errno? */
if (!absPath)
return MSVCRT__strdup(res);
strcpy(absPath,res);
return absPath;
}
/*********************************************************************
* _makepath (MSVCRT.@)
*/
VOID __cdecl MSVCRT__makepath(char * path, const char * drive,
const char *directory, const char * filename,
const char * extension )
{
char ch;
TRACE("MSVCRT__makepath got %s %s %s %s\n", drive, directory,
filename, extension);
if ( !path )
return;
path[0] = 0;
if (drive && drive[0])
{
path[0] = drive[0];
path[1] = ':';
path[2] = 0;
}
if (directory && directory[0])
{
strcat(path, directory);
ch = path[strlen(path)-1];
if (ch != '/' && ch != '\\')
strcat(path,"\\");
}
if (filename && filename[0])
{
strcat(path, filename);
if (extension && extension[0])
{
if ( extension[0] != '.' )
strcat(path,".");
strcat(path,extension);
}
}
TRACE("MSVCRT__makepath returns %s\n",path);
}
/*********************************************************************
* _searchenv (MSVCRT.@)
*/
void __cdecl MSVCRT__searchenv(const char* file, const char* env, char *buf)
{
char*envVal, *penv;
char curPath[MAX_PATH];
*buf = '\0';
/* Try CWD first */
if (GetFileAttributesA( file ) != 0xFFFFFFFF)
{
GetFullPathNameA( file, MAX_PATH, buf, NULL );
/* Sigh. This error is *always* set, regardless of success */
MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
return;
}
/* Search given environment variable */
envVal = MSVCRT_getenv(env);
if (!envVal)
{
MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
return;
}
penv = envVal;
TRACE(":searching for %s in paths %s\n", file, envVal);
do
{
LPSTR end = penv;
while(*end && *end != ';') end++; /* Find end of next path */
if (penv == end || !*penv)
{
MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
return;
}
strncpy(curPath, penv, end - penv);
if (curPath[end - penv] != '/' || curPath[end - penv] != '\\')
{
curPath[end - penv] = '\\';
curPath[end - penv + 1] = '\0';
}
else
curPath[end - penv] = '\0';
strcat(curPath, file);
TRACE("Checking for file %s\n", curPath);
if (GetFileAttributesA( curPath ) != 0xFFFFFFFF)
{
strcpy(buf, curPath);
MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
return; /* Found */
}
penv = *end ? end + 1 : end;
} while(1);
}
/*
* msvcrt.dll environment functions
*
* Copyright 1996,1998 Marcus Meissner
* Copyright 1996 Jukka Iivonen
* Copyright 1997,2000 Uwe Bonnes
* Copyright 2000 Jon Griffiths
*/
#include "wine/unicode.h"
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
LPWSTR __cdecl wcsrchr( LPWSTR str, WCHAR ch );
/*********************************************************************
* getenv (MSVCRT.@)
*/
char *__cdecl MSVCRT_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;
}
/*********************************************************************
* _wgetenv (MSVCRT.@)
*/
WCHAR *__cdecl MSVCRT__wgetenv(const WCHAR *name)
{
WCHAR* environ = GetEnvironmentStringsW();
WCHAR* pp,*pos = NULL;
unsigned int length;
for (pp = environ; (*pp); pp = pp + strlenW(pp) + 1)
{
pos =wcsrchr(pp,'=');
if (pos)
length = pos -pp;
else
length = strlenW(pp);
if (!strncmpW(pp,name,length)) break;
}
if ((pp)&& (pos))
{
pp = pos+1;
TRACE("got %s\n",debugstr_w(pp));
}
FreeEnvironmentStringsW( environ );
return pp;
}
/*
* msvcrt.dll errno functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
#include "ms_errno.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* INTERNAL: Set the crt and dos errno's from the OS error given. */
void MSVCRT__set_errno(int err)
{
int *errno = GET_THREAD_VAR_PTR(errno);
int *doserrno = GET_THREAD_VAR_PTR(doserrno);
*doserrno = err;
switch(err)
{
#define ERR_CASE(oserr) case oserr:
#define ERR_MAPS(oserr,crterr) case oserr:*errno = crterr;break;
ERR_CASE(ERROR_ACCESS_DENIED)
ERR_CASE(ERROR_NETWORK_ACCESS_DENIED)
ERR_CASE(ERROR_CANNOT_MAKE)
ERR_CASE(ERROR_SEEK_ON_DEVICE)
ERR_CASE(ERROR_LOCK_FAILED)
ERR_CASE(ERROR_FAIL_I24)
ERR_CASE(ERROR_CURRENT_DIRECTORY)
ERR_CASE(ERROR_DRIVE_LOCKED)
ERR_CASE(ERROR_NOT_LOCKED)
ERR_CASE(ERROR_INVALID_ACCESS)
ERR_MAPS(ERROR_LOCK_VIOLATION, MSVCRT_EACCES);
ERR_CASE(ERROR_FILE_NOT_FOUND)
ERR_CASE(ERROR_NO_MORE_FILES)
ERR_CASE(ERROR_BAD_PATHNAME)
ERR_CASE(ERROR_BAD_NETPATH)
ERR_CASE(ERROR_INVALID_DRIVE)
ERR_CASE(ERROR_BAD_NET_NAME)
ERR_CASE(ERROR_FILENAME_EXCED_RANGE)
ERR_MAPS(ERROR_PATH_NOT_FOUND, MSVCRT_ENOENT);
ERR_MAPS(ERROR_IO_DEVICE, MSVCRT_EIO);
ERR_MAPS(ERROR_BAD_FORMAT, MSVCRT_ENOEXEC);
ERR_MAPS(ERROR_INVALID_HANDLE, MSVCRT_EBADF);
ERR_CASE(ERROR_OUTOFMEMORY)
ERR_CASE(ERROR_INVALID_BLOCK)
ERR_CASE(ERROR_NOT_ENOUGH_QUOTA);
ERR_MAPS(ERROR_ARENA_TRASHED, MSVCRT_ENOMEM);
ERR_MAPS(ERROR_BUSY, MSVCRT_EBUSY);
ERR_CASE(ERROR_ALREADY_EXISTS)
ERR_MAPS(ERROR_FILE_EXISTS, MSVCRT_EEXIST);
ERR_MAPS(ERROR_BAD_DEVICE, MSVCRT_ENODEV);
ERR_MAPS(ERROR_TOO_MANY_OPEN_FILES, MSVCRT_EMFILE);
ERR_MAPS(ERROR_DISK_FULL, MSVCRT_ENOSPC);
ERR_MAPS(ERROR_BROKEN_PIPE, MSVCRT_EPIPE);
ERR_MAPS(ERROR_POSSIBLE_DEADLOCK, MSVCRT_EDEADLK);
ERR_MAPS(ERROR_DIR_NOT_EMPTY, MSVCRT_ENOTEMPTY);
ERR_MAPS(ERROR_BAD_ENVIRONMENT, MSVCRT_E2BIG);
ERR_CASE(ERROR_WAIT_NO_CHILDREN)
ERR_MAPS(ERROR_CHILD_NOT_COMPLETE, MSVCRT_ECHILD);
ERR_CASE(ERROR_NO_PROC_SLOTS)
ERR_CASE(ERROR_MAX_THRDS_REACHED)
ERR_MAPS(ERROR_NESTING_NOT_ALLOWED, MSVCRT_EAGAIN);
default:
/* Remaining cases map to EINVAL */
/* FIXME: may be missing some errors above */
*errno = MSVCRT_EINVAL;
}
}
/*********************************************************************
* _errno (MSVCRT.@)
*/
LPINT __cdecl MSVCRT__errno( VOID )
{
return GET_THREAD_VAR_PTR(errno);
}
/*********************************************************************
* __doserrno (MSVCRT.@)
*/
LPINT __cdecl MSVCRT___doserrno( VOID )
{
return GET_THREAD_VAR_PTR(doserrno);
}
char *strerror(int);
/*********************************************************************
* strerror (MSVCRT.@)
*/
char * __cdecl MSVCRT_strerror (int err)
{
return strerror(err); /* FIXME */
}
/**********************************************************************
* _strerror (MSVCRT.@)
*/
extern int sprintf(char *str, const char *format, ...);
LPSTR __cdecl MSVCRT__strerror (LPCSTR err)
{
static char strerrbuff[256]; /* FIXME: Per thread, nprintf */
sprintf(strerrbuff,"%s: %s\n",err,MSVCRT_strerror(GET_THREAD_VAR(errno)));
return strerrbuff;
}
int __cdecl MSVCRT__cprintf( const char * format, ... );
/*********************************************************************
* perror (MSVCRT.@)
*/
void __cdecl MSVCRT_perror (const char *str)
{
MSVCRT__cprintf("%s: %s\n",str,MSVCRT_strerror(GET_THREAD_VAR(errno)));
}
/*
* msvcrt.dll exception handling
*
* Copyright 2000 Jon Griffiths
*
* See http://www.microsoft.com/msj/0197/exception/exception.htm,
* but don't believe all of it.
*
* FIXME: Incomplete, no support for nested exceptions or try block cleanup.
*/
#include <setjmp.h>
#include "ntddk.h"
#include "thread.h"
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef void (*MSVCRT_sig_handler_func)(void);
/* VC++ extensions to Win32 SEH */
typedef struct _SCOPETABLE
{
DWORD previousTryLevel;
int (__cdecl *lpfnFilter)(int, PEXCEPTION_POINTERS);
int (__cdecl *lpfnHandler)(PEXCEPTION_RECORD, PEXCEPTION_FRAME,
PCONTEXT, PEXCEPTION_FRAME *);
} SCOPETABLE, *PSCOPETABLE;
typedef struct _MSVCRT_EXCEPTION_REGISTRATION
{
struct _EXCEPTION_REGISTRATION *prev;
void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_FRAME,
PCONTEXT, PEXCEPTION_RECORD);
PSCOPETABLE scopetable;
int trylevel;
int _ebp;
PEXCEPTION_POINTERS xpointers;
} MSVCRT_EXCEPTION_REGISTRATION;
typedef struct _EXCEPTION_REGISTRATION
{
struct _EXCEPTION_REGISTRATION *prev;
void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_FRAME,
PCONTEXT, PEXCEPTION_RECORD);
} EXCEPTION_REGISTRATION;
/*********************************************************************
* _EH_prolog (MSVCRT.@)
*/
void __cdecl MSVCRT__EH_prolog(void)
{
FIXME("stub\n");
}
/*********************************************************************
* _XcptFilter (MSVCRT.@)
*/
int __cdecl MSVCRT__XcptFilter(int ex, PEXCEPTION_POINTERS ptr)
{
FIXME("(%d,%p)semi-stub\n", ex, ptr);
return UnhandledExceptionFilter(ptr);
}
/*******************************************************************
* _global_unwind2 (MSVCRT.@)
*/
void __cdecl MSVCRT__global_unwind2(PEXCEPTION_FRAME frame)
{
#if defined(__GNUC__) && defined(__i386__)
TRACE("(%p)\n",frame);
if (0)
unwind_label: return;
RtlUnwind( frame, &&unwind_label, 0, 0 );
#else
FIXME("(%p) stub\n",frame);
#endif
}
/*******************************************************************
* _local_unwind2 (MSVCRT.@)
*/
void __cdecl MSVCRT__local_unwind2(MSVCRT_EXCEPTION_REGISTRATION *endframe, DWORD nr )
{
FIXME("(%p,%ld) stub\n",endframe,nr);
}
/*********************************************************************
* _except_handler2 (MSVCRT.@)
*/
int __cdecl MSVCRT__except_handler2(PEXCEPTION_RECORD rec,
PEXCEPTION_FRAME frame,
PCONTEXT context, PEXCEPTION_FRAME *dispatcher)
{
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;
}
/*********************************************************************
* _except_handler3 (MSVCRT.@)
*/
int __cdecl MSVCRT__except_handler3(PEXCEPTION_RECORD rec,
MSVCRT_EXCEPTION_REGISTRATION *frame,
PCONTEXT context,void *dispatcher)
{
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;
}
/*********************************************************************
* _abnormal_termination (MSVCRT.@)
*/
int __cdecl MSVCRT__abnormal_termination(void)
{
FIXME("(void)stub\n");
return 0;
}
/*******************************************************************
* _setjmp (MSVCRT.@)
*/
int __cdecl MSVCRT__setjmp(LPDWORD *jmpbuf)
{
FIXME(":(%p): stub\n",jmpbuf);
return 0;
}
/*********************************************************************
* longjmp (MSVCRT.@)
*/
void __cdecl MSVCRT_longjmp(jmp_buf env, int val)
{
FIXME("MSVCRT_longjmp semistub, expect crash\n");
longjmp(env, val);
}
/*********************************************************************
* signal (MSVCRT.@)
*/
void * __cdecl MSVCRT_signal(int sig, MSVCRT_sig_handler_func func)
{
FIXME("(%d %p):stub\n", sig, func);
return (void*)-1;
}
/*
* msvcrt.dll exit functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* MT */
extern CRITICAL_SECTION MSVCRT_exit_cs;
#define LOCK_EXIT EnterCriticalSection(&MSVCRT_exit_cs)
#define UNLOCK_EXIT LeaveCriticalSection(&MSVCRT_exit_cs)
typedef void (__cdecl *MSVCRT_atexit_func)(void);
static MSVCRT_atexit_func *MSVCRT_atexit_table = NULL;
static int MSVCRT_atexit_table_size = 0;
static int MSVCRT_atexit_registered = 0; /* Points to free slot */
extern int MSVCRT_app_type;
/* INTERNAL: call atexit functions */
void __MSVCRT__call_atexit(void)
{
/* Note: should only be called with the exit lock held */
TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
/* Last registered gets executed first */
while (MSVCRT_atexit_registered > 0)
{
MSVCRT_atexit_registered--;
TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
(*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
TRACE("returned\n");
}
}
/*********************************************************************
* __dllonexit (MSVCRT.@)
*/
void __cdecl MSVCRT___dllonexit (MSVCRT_atexit_func func, MSVCRT_atexit_func **start,
MSVCRT_atexit_func **end)
{
FIXME("(%p,%p,%p)stub\n", func, start,end);
/* FIXME: How do we know when to increase the table? */
}
/*********************************************************************
* _exit (MSVCRT.@)
*/
void __cdecl MSVCRT__exit(int exitcode)
{
TRACE("(%d)\n", exitcode);
ExitProcess(exitcode);
}
/*********************************************************************
* _amsg_exit (MSVCRT.@)
*/
void __cdecl MSVCRT__amsg_exit(int errnum)
{
TRACE("(%d)\n", errnum);
/* FIXME: text for the error number. */
if (MSVCRT_app_type == 2)
{
/* FIXME: MsgBox */
}
MSVCRT__cprintf("\nruntime error R60%d\n",errnum);
MSVCRT__exit(255);
}
/*********************************************************************
* abort (MSVCRT.@)
*/
void __cdecl MSVCRT_abort(void)
{
TRACE("(void)\n");
if (MSVCRT_app_type == 2)
{
/* FIXME: MsgBox */
}
MSVCRT__cputs("\nabnormal program termination\n");
MSVCRT__exit(3);
}
/*********************************************************************
* _assert (MSVCRT.@)
*/
void __cdecl MSVCRT__assert(const char* str, const char* file, unsigned int line)
{
TRACE("(%s,%s,%d)\n",str,file,line);
if (MSVCRT_app_type == 2)
{
/* FIXME: MsgBox */
}
MSVCRT__cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
MSVCRT_abort();
}
/*********************************************************************
* _c_exit (MSVCRT.@)
*/
void __cdecl MSVCRT__c_exit(void)
{
TRACE("(void)\n");
/* All cleanup is done on DLL detach; Return to caller */
}
/*********************************************************************
* _cexit (MSVCRT.@)
*/
void __cdecl MSVCRT__cexit(void)
{
TRACE("(void)\n");
/* All cleanup is done on DLL detach; Return to caller */
}
/*********************************************************************
* _onexit (MSVCRT.@)
*/
MSVCRT_atexit_func __cdecl MSVCRT__onexit(MSVCRT_atexit_func func)
{
TRACE("(%p)\n",func);
if (!func)
return NULL;
LOCK_EXIT;
if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
{
MSVCRT_atexit_func *newtable;
TRACE("expanding table\n");
newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
if (!newtable)
{
TRACE("failed!\n");
UNLOCK_EXIT;
return NULL;
}
memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
MSVCRT_atexit_table_size += 32;
if (MSVCRT_atexit_table)
MSVCRT_free (MSVCRT_atexit_table);
MSVCRT_atexit_table = newtable;
}
MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
MSVCRT_atexit_registered++;
UNLOCK_EXIT;
return func;
}
/*********************************************************************
* exit (MSVCRT.@)
*/
void __cdecl MSVCRT_exit(int exitcode)
{
TRACE("(%d)\n",exitcode);
LOCK_EXIT;
__MSVCRT__call_atexit();
UNLOCK_EXIT;
ExitProcess(exitcode);
}
/*********************************************************************
* atexit (MSVCRT.@)
*/
int __cdecl MSVCRT_atexit(MSVCRT_atexit_func func)
{
TRACE("(%p)\n", func);
return MSVCRT__onexit(func) == func ? 0 : -1;
}
/*********************************************************************
* _purecall (MSVCRT.@)
*/
void __cdecl MSVCRT__purecall(void)
{
TRACE("(void)\n");
MSVCRT__amsg_exit( 25 );
}
/*
* msvcrt.dll file functions
*
* Copyright 1996,1998 Marcus Meissner
* Copyright 1996 Jukka Iivonen
* Copyright 1997,2000 Uwe Bonnes
* Copyright 2000 Jon Griffiths
*/
#include <time.h>
#include "ntddk.h"
#include "msvcrt.h"
#include "ms_errno.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* stat() mode bits */
#define _S_IFMT 0170000
#define _S_IFREG 0100000
#define _S_IFDIR 0040000
#define _S_IFCHR 0020000
#define _S_IFIFO 0010000
#define _S_IREAD 0000400
#define _S_IWRITE 0000200
#define _S_IEXEC 0000100
/* for stat mode, permissions apply to all,owner and group */
#define MSVCRT_S_IREAD (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6))
#define MSVCRT_S_IWRITE (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6))
#define MSVCRT_S_IEXEC (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6))
/* _open modes */
#define _O_RDONLY 0x0000
#define _O_WRONLY 0x0001
#define _O_RDWR 0x0002
#define _O_APPEND 0x0008
#define _O_CREAT 0x0100
#define _O_TRUNC 0x0200
#define _O_EXCL 0x0400
#define _O_TEXT 0x4000
#define _O_BINARY 0x8000
#define _O_TEMPORARY 0x0040 /* Will be closed and deleted on exit */
/* _access() bit flags FIXME: incomplete */
#define W_OK 2
typedef struct _crtfile
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file; /* fd */
int _charbuf;
int _bufsiz;
char *_tmpfname;
} MSVCRT_FILE;
/* file._flag flags */
#define _IOREAD 0x0001
#define _IOWRT 0x0002
#define _IOEOF 0x0010
#define _IOERR 0x0020
#define _IORW 0x0080
#define _IOAPPEND 0x0200
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define MSVCRT_stdin (&MSVCRT__iob[0])
#define MSVCRT_stdout (&MSVCRT__iob[1])
#define MSVCRT_stderr (&MSVCRT__iob[2])
struct _stat
{
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
unsigned int st_rdev;
int st_size;
int st_atime;
int st_mtime;
int st_ctime;
};
typedef long MSVCRT_fpos_t;
struct _utimbuf
{
time_t actime;
time_t modtime;
};
/* FIXME: Make this dynamic */
#define MSVCRT_MAX_FILES 257
HANDLE MSVCRT_handles[MSVCRT_MAX_FILES];
MSVCRT_FILE* MSVCRT_files[MSVCRT_MAX_FILES];
int MSVCRT_flags[MSVCRT_MAX_FILES];
char *MSVCRT_tempfiles[MSVCRT_MAX_FILES];
MSVCRT_FILE MSVCRT__iob[3];
static int MSVCRT_fdstart = 3; /* first unallocated fd */
static int MSVCRT_fdend = 3; /* highest allocated fd */
/* INTERNAL: process umask */
static int MSVCRT_umask = 0;
/* INTERNAL: Static buffer for temp file name */
static char MSVCRT_tmpname[MAX_PATH];
static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e';
static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't';
static const unsigned int CMD = 'c' << 16 | 'm' << 8 | 'd';
static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm';
extern CRITICAL_SECTION MSVCRT_file_cs;
#define LOCK_FILES EnterCriticalSection(&MSVCRT_file_cs)
#define UNLOCK_FILES LeaveCriticalSection(&MSVCRT_file_cs)
time_t __cdecl MSVCRT_time(time_t *);
int __cdecl MSVCRT__getdrive(void);
/* INTERNAL: Get the HANDLE for a fd */
static HANDLE MSVCRT__fdtoh(int fd)
{
if (fd < 0 || fd >= MSVCRT_fdend ||
MSVCRT_handles[fd] == INVALID_HANDLE_VALUE)
{
WARN(":fd (%d) - no handle!\n",fd);
SET_THREAD_VAR(doserrno,0);
SET_THREAD_VAR(errno,MSVCRT_EBADF);
return INVALID_HANDLE_VALUE;
}
return MSVCRT_handles[fd];
}
/* INTERNAL: free a file entry fd */
static void MSVCRT__free_fd(int fd)
{
MSVCRT_handles[fd] = INVALID_HANDLE_VALUE;
MSVCRT_files[fd] = 0;
MSVCRT_flags[fd] = 0;
TRACE(":fd (%d) freed\n",fd);
if (fd < 3)
return; /* dont use 0,1,2 for user files */
if (fd == MSVCRT_fdend - 1)
MSVCRT_fdend--;
if (fd < MSVCRT_fdstart)
MSVCRT_fdstart = fd;
}
/* INTERNAL: Allocate an fd slot from a Win32 HANDLE */
static int MSVCRT__alloc_fd(HANDLE hand, int flag)
{
int fd = MSVCRT_fdstart;
TRACE(":handle (%d) allocating fd (%d)\n",hand,fd);
if (fd >= MSVCRT_MAX_FILES)
{
WARN(":files exhausted!\n");
return -1;
}
MSVCRT_handles[fd] = hand;
MSVCRT_flags[fd] = flag;
/* locate next free slot */
if (fd == MSVCRT_fdend)
MSVCRT_fdstart = ++MSVCRT_fdend;
else
while(MSVCRT_fdstart < MSVCRT_fdend &&
MSVCRT_handles[MSVCRT_fdstart] != INVALID_HANDLE_VALUE)
MSVCRT_fdstart++;
return fd;
}
/* INTERNAL: Allocate a FILE* for an fd slot
* This is done lazily to avoid memory wastage for low level open/write
* usage when a FILE* is not requested (but may be later).
*/
static MSVCRT_FILE* MSVCRT__alloc_fp(int fd)
{
TRACE(":fd (%d) allocating FILE*\n",fd);
if (fd < 0 || fd >= MSVCRT_fdend ||
MSVCRT_handles[fd] == INVALID_HANDLE_VALUE)
{
WARN(":invalid fd %d\n",fd);
SET_THREAD_VAR(doserrno,0);
SET_THREAD_VAR(errno,MSVCRT_EBADF);
return NULL;
}
if (!MSVCRT_files[fd])
{
if ((MSVCRT_files[fd] = MSVCRT_calloc(sizeof(MSVCRT_FILE),1)))
{
MSVCRT_files[fd]->_file = fd;
MSVCRT_files[fd]->_flag = MSVCRT_flags[fd];
MSVCRT_files[fd]->_flag &= ~_IOAPPEND; /* mask out, see above */
}
}
TRACE(":got FILE* (%p)\n",MSVCRT_files[fd]);
return MSVCRT_files[fd];
}
/* INTERNAL: Set up stdin, stderr and stdout */
void MSVCRT_init_io(void)
{
int i;
memset(MSVCRT__iob,0,3*sizeof(MSVCRT_FILE));
MSVCRT_handles[0] = GetStdHandle(STD_INPUT_HANDLE);
MSVCRT_flags[0] = MSVCRT__iob[0]._flag = _IOREAD;
MSVCRT_handles[1] = GetStdHandle(STD_OUTPUT_HANDLE);
MSVCRT_flags[1] = MSVCRT__iob[1]._flag = _IOWRT;
MSVCRT_handles[2] = GetStdHandle(STD_ERROR_HANDLE);
MSVCRT_flags[2] = MSVCRT__iob[2]._flag = _IOWRT;
TRACE(":handles (%d)(%d)(%d)\n",MSVCRT_handles[0],
MSVCRT_handles[1],MSVCRT_handles[2]);
for (i = 0; i < 3; i++)
{
/* FILE structs for stdin/out/err are static and never deleted */
MSVCRT_files[i] = &MSVCRT__iob[i];
MSVCRT__iob[i]._file = i;
MSVCRT_tempfiles[i] = NULL;
}
}
/*********************************************************************
* __p__iob(MSVCRT.@)
*/
MSVCRT_FILE *MSVCRT___p__iob(void)
{
return &MSVCRT__iob[0];
}
/*********************************************************************
* _access (MSVCRT.@)
*/
int __cdecl MSVCRT__access(const char *filename, int mode)
{
DWORD attr = GetFileAttributesA(filename);
if (attr == 0xffffffff)
{
if (!filename)
{
/* FIXME: Should GetFileAttributesA() return this? */
MSVCRT__set_errno(ERROR_INVALID_DATA);
return -1;
}
MSVCRT__set_errno(GetLastError());
return -1;
}
if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & W_OK))
{
MSVCRT__set_errno(ERROR_ACCESS_DENIED);
return -1;
}
TRACE(":file %s, mode (%d) ok\n",filename,mode);
return 0;
}
/*********************************************************************
* _chmod (MSVCRT.@)
*/
int __cdecl MSVCRT__chmod(const char *path, int flags)
{
DWORD oldFlags = GetFileAttributesA(path);
if (oldFlags != 0x0FFFFFFFF)
{
DWORD newFlags = (flags & _S_IWRITE)? oldFlags & ~FILE_ATTRIBUTE_READONLY:
oldFlags | FILE_ATTRIBUTE_READONLY;
if (newFlags == oldFlags || SetFileAttributesA(path, newFlags))
return 0;
}
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* _unlink (MSVCRT.@)
*/
int __cdecl MSVCRT__unlink(const char *path)
{
TRACE("path (%s)\n",path);
if(DeleteFileA(path))
return 0;
TRACE("failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* _close (MSVCRT.@)
*/
int __cdecl MSVCRT__close(int fd)
{
HANDLE hand = MSVCRT__fdtoh(fd);
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand == INVALID_HANDLE_VALUE)
return -1;
/* Dont free std FILE*'s, they are not dynamic */
if (fd > 2 && MSVCRT_files[fd])
MSVCRT_free(MSVCRT_files[fd]);
MSVCRT__free_fd(fd);
if (!CloseHandle(hand))
{
WARN(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
}
if (MSVCRT_tempfiles[fd])
{
TRACE("deleting temporary file '%s'\n",MSVCRT_tempfiles[fd]);
MSVCRT__unlink(MSVCRT_tempfiles[fd]);
MSVCRT_free(MSVCRT_tempfiles[fd]);
MSVCRT_tempfiles[fd] = NULL;
}
TRACE(":ok\n");
return 0;
}
/*********************************************************************
* _commit (MSVCRT.@)
*/
int __cdecl MSVCRT__commit(int fd)
{
HANDLE hand = MSVCRT__fdtoh(fd);
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand == INVALID_HANDLE_VALUE)
return -1;
if (!FlushFileBuffers(hand))
{
if (GetLastError() == ERROR_INVALID_HANDLE)
{
/* FlushFileBuffers fails for console handles
* so we ignore this error.
*/
return 0;
}
TRACE(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
}
TRACE(":ok\n");
return 0;
}
/*********************************************************************
* _eof (MSVCRT.@)
*/
int __cdecl MSVCRT__eof(int fd)
{
DWORD curpos,endpos;
HANDLE hand = MSVCRT__fdtoh(fd);
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand == INVALID_HANDLE_VALUE)
return -1;
/* If we have a FILE* for this file, the EOF flag
* will be set by the read()/write() functions.
*/
if (MSVCRT_files[fd])
return MSVCRT_files[fd]->_flag & _IOEOF;
/* Otherwise we do it the hard way */
curpos = SetFilePointer(hand, 0, NULL, SEEK_CUR);
endpos = SetFilePointer(hand, 0, NULL, FILE_END);
if (curpos == endpos)
return TRUE;
SetFilePointer(hand, curpos, 0, FILE_BEGIN);
return FALSE;
}
/*********************************************************************
* _fcloseall (MSVCRT.@)
*/
int __cdecl MSVCRT__fcloseall(void)
{
int num_closed = 0, i;
for (i = 3; i < MSVCRT_fdend; i++)
if (MSVCRT_handles[i] != INVALID_HANDLE_VALUE)
{
MSVCRT__close(i);
num_closed++;
}
TRACE(":closed (%d) handles\n",num_closed);
return num_closed;
}
/*********************************************************************
* _lseek (MSVCRT.@)
*/
LONG __cdecl MSVCRT__lseek(int fd, LONG offset, int whence)
{
DWORD ret;
HANDLE hand = MSVCRT__fdtoh(fd);
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand == INVALID_HANDLE_VALUE)
return -1;
if (whence < 0 || whence > 2)
{
SET_THREAD_VAR(errno,MSVCRT_EINVAL);
return -1;
}
TRACE(":fd (%d) to 0x%08lx pos %s\n",
fd,offset,(whence==SEEK_SET)?"SEEK_SET":
(whence==SEEK_CUR)?"SEEK_CUR":
(whence==SEEK_END)?"SEEK_END":"UNKNOWN");
if ((ret = SetFilePointer(hand, offset, NULL, whence)) != 0xffffffff)
{
if (MSVCRT_files[fd])
MSVCRT_files[fd]->_flag &= ~_IOEOF;
/* FIXME: What if we seek _to_ EOF - is EOF set? */
return ret;
}
TRACE(":error-last error (%ld)\n",GetLastError());
if (MSVCRT_files[fd])
switch(GetLastError())
{
case ERROR_NEGATIVE_SEEK:
case ERROR_SEEK_ON_DEVICE:
MSVCRT__set_errno(GetLastError());
MSVCRT_files[fd]->_flag |= _IOERR;
break;
default:
break;
}
return -1;
}
/*********************************************************************
* rewind (MSVCRT.@)
*/
VOID __cdecl MSVCRT_rewind(MSVCRT_FILE* file)
{
TRACE(":file (%p) fd (%d)\n",file,file->_file);
MSVCRT__lseek(file->_file,0,SEEK_SET);
file->_flag &= ~(_IOEOF | _IOERR);
}
/*********************************************************************
* _fdopen (MSVCRT.@)
*/
MSVCRT_FILE* __cdecl MSVCRT__fdopen(int fd, const char *mode)
{
MSVCRT_FILE* file = MSVCRT__alloc_fp(fd);
TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,mode,file);
if (file)
MSVCRT_rewind(file);
return file;
}
/*********************************************************************
* _filelength (MSVCRT.@)
*/
LONG __cdecl MSVCRT__filelength(int fd)
{
LONG curPos = MSVCRT__lseek(fd, 0, SEEK_CUR);
if (curPos != -1)
{
LONG endPos = MSVCRT__lseek(fd, 0, SEEK_END);
if (endPos != -1)
{
if (endPos != curPos)
MSVCRT__lseek(fd, curPos, SEEK_SET);
return endPos;
}
}
return -1;
}
/*********************************************************************
* _fileno (MSVCRT.@)
*/
int __cdecl MSVCRT__fileno(MSVCRT_FILE* file)
{
TRACE(":FILE* (%p) fd (%d)\n",file,file->_file);
return file->_file;
}
/*********************************************************************
* _flushall (MSVCRT.@)
*/
int __cdecl MSVCRT__flushall(VOID)
{
int num_flushed = 0, i = 3;
while(i < MSVCRT_fdend)
if (MSVCRT_handles[i] != INVALID_HANDLE_VALUE)
{
if (MSVCRT__commit(i) == -1)
if (MSVCRT_files[i])
MSVCRT_files[i]->_flag |= _IOERR;
num_flushed++;
}
TRACE(":flushed (%d) handles\n",num_flushed);
return num_flushed;
}
/*********************************************************************
* _fstat (MSVCRT.@)
*/
int __cdecl MSVCRT__fstat(int fd, struct _stat* buf)
{
DWORD dw;
BY_HANDLE_FILE_INFORMATION hfi;
HANDLE hand = MSVCRT__fdtoh(fd);
TRACE(":fd (%d) stat (%p)\n",fd,buf);
if (hand == INVALID_HANDLE_VALUE)
return -1;
if (!buf)
{
WARN(":failed-NULL buf\n");
MSVCRT__set_errno(ERROR_INVALID_PARAMETER);
return -1;
}
memset(&hfi, 0, sizeof(hfi));
memset(buf, 0, sizeof(struct _stat));
if (!GetFileInformationByHandle(hand, &hfi))
{
WARN(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(ERROR_INVALID_PARAMETER);
return -1;
}
FIXME(":dwFileAttributes = %d, mode set to 0",hfi.dwFileAttributes);
buf->st_nlink = hfi.nNumberOfLinks;
buf->st_size = hfi.nFileSizeLow;
RtlTimeToSecondsSince1970(&hfi.ftLastAccessTime, &dw);
buf->st_atime = dw;
RtlTimeToSecondsSince1970(&hfi.ftLastWriteTime, &dw);
buf->st_mtime = buf->st_ctime = dw;
return 0;
}
/*********************************************************************
* _futime (MSVCRT.@)
*/
int __cdecl MSVCRT__futime(int fd, struct _utimbuf *t)
{
HANDLE hand = MSVCRT__fdtoh(fd);
FILETIME at, wt;
if (!t)
{
time_t currTime;
MSVCRT_time(&currTime);
RtlSecondsSince1970ToTime(currTime, &at);
memcpy(&wt, &at, sizeof(wt));
}
else
{
RtlSecondsSince1970ToTime(t->actime, &at);
if (t->actime == t->modtime)
memcpy(&wt, &at, sizeof(wt));
else
RtlSecondsSince1970ToTime(t->modtime, &wt);
}
if (!SetFileTime(hand, NULL, &at, &wt))
{
MSVCRT__set_errno(GetLastError());
return -1 ;
}
return 0;
}
/*********************************************************************
* _get_osfhandle (MSVCRT.@)
*/
HANDLE MSVCRT__get_osfhandle(int fd)
{
HANDLE hand = MSVCRT__fdtoh(fd);
HANDLE newhand = hand;
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand != INVALID_HANDLE_VALUE)
{
/* FIXME: I'm not convinced that I should be copying the
* handle here - it may be leaked if the app doesn't
* close it (and the API docs dont say that it should)
* Not duplicating it means that it can't be inherited
* and so lcc's wedit doesn't cope when it passes it to
* child processes. I've an idea that it should either
* be copied by CreateProcess, or marked as inheritable
* when initialised, or maybe both? JG 21-9-00.
*/
DuplicateHandle(GetCurrentProcess(),hand,GetCurrentProcess(),
&newhand,0,TRUE,DUPLICATE_SAME_ACCESS);
}
return newhand;
}
/*********************************************************************
* _isatty (MSVCRT.@)
*/
int __cdecl MSVCRT__isatty(int fd)
{
HANDLE hand = MSVCRT__fdtoh(fd);
TRACE(":fd (%d) handle (%d)\n",fd,hand);
if (hand == INVALID_HANDLE_VALUE)
return 0;
return GetFileType(fd) == FILE_TYPE_CHAR? 1 : 0;
}
/*********************************************************************
* _mktemp (MSVCRT.@)
*/
char *__cdecl MSVCRT__mktemp(char *pattern)
{
int numX = 0;
char *retVal = pattern;
int id;
char letter = 'a';
while(*pattern)
numX = (*pattern++ == 'X')? numX + 1 : 0;
if (numX < 5)
return NULL;
pattern--;
id = GetCurrentProcessId();
numX = 6;
while(numX--)
{
int tempNum = id / 10;
*pattern-- = id - (tempNum * 10) + '0';
id = tempNum;
}
pattern++;
do
{
if (GetFileAttributesA(retVal) == 0xFFFFFFFF &&
GetLastError() == ERROR_FILE_NOT_FOUND)
return retVal;
*pattern = letter++;
} while(letter != '|');
return NULL;
}
/*********************************************************************
* _open (MSVCRT.@)
*/
int __cdecl MSVCRT__open(const char *path,int flags)
{
DWORD access = 0, creation = 0;
int ioflag = 0, fd;
HANDLE hand;
TRACE(":file (%s) mode 0x%04x\n",path,flags);
switch(flags & (_O_RDONLY | _O_WRONLY | _O_RDWR))
{
case _O_RDONLY:
access |= GENERIC_READ;
ioflag |= _IOREAD;
break;
case _O_WRONLY:
access |= GENERIC_WRITE;
ioflag |= _IOWRT;
break;
case _O_RDWR:
access |= GENERIC_WRITE | GENERIC_READ;
ioflag |= _IORW;
break;
}
if (flags & _O_CREAT)
{
if (flags & _O_EXCL)
creation = CREATE_NEW;
else if (flags & _O_TRUNC)
creation = CREATE_ALWAYS;
else
creation = OPEN_ALWAYS;
}
else /* no _O_CREAT */
{
if (flags & _O_TRUNC)
creation = TRUNCATE_EXISTING;
else
creation = OPEN_EXISTING;
}
if (flags & _O_APPEND)
ioflag |= _IOAPPEND;
flags |= _O_BINARY; /* FIXME: Default to text */
if (flags & _O_TEXT)
{
/* Dont warn when writing */
if (ioflag & GENERIC_READ)
FIXME(":TEXT node not implemented\n");
flags &= ~_O_TEXT;
}
if (flags & ~(_O_BINARY|_O_TEXT|_O_APPEND|_O_TRUNC|_O_EXCL
|_O_CREAT|_O_RDWR|_O_TEMPORARY))
TRACE(":unsupported flags 0x%04x\n",flags);
hand = CreateFileA(path, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, creation, FILE_ATTRIBUTE_NORMAL, 0);
if (hand == INVALID_HANDLE_VALUE)
{
WARN(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
}
fd = MSVCRT__alloc_fd(hand, ioflag);
TRACE(":fd (%d) handle (%d)\n",fd, hand);
if (fd > 0)
{
if (flags & _O_TEMPORARY)
MSVCRT_tempfiles[fd] = MSVCRT__strdup(path);
if (ioflag & _IOAPPEND)
MSVCRT__lseek(fd, 0, FILE_END);
}
return fd;
}
/*********************************************************************
* _creat (MSVCRT.@)
*/
int __cdecl MSVCRT__creat(const char *path, int flags)
{
int usedFlags = (flags & _O_TEXT)| _O_CREAT| _O_WRONLY| _O_TRUNC;
return MSVCRT__open(path, usedFlags);
}
/*********************************************************************
* _open_osfhandle (MSVCRT.@)
*/
int __cdecl MSVCRT__open_osfhandle(HANDLE hand, int flags)
{
int fd = MSVCRT__alloc_fd(hand,flags);
TRACE(":handle (%d) fd (%d)\n",hand,fd);
return fd;
}
/*********************************************************************
* _rmtmp (MSVCRT.@)
*/
int __cdecl MSVCRT__rmtmp(void)
{
int num_removed = 0, i;
for (i = 3; i < MSVCRT_fdend; i++)
if (MSVCRT_tempfiles[i])
{
MSVCRT__close(i);
num_removed++;
}
if (num_removed)
TRACE(":removed (%d) temp files\n",num_removed);
return num_removed;
}
/*********************************************************************
* _read (MSVCRT.@)
*/
int __cdecl MSVCRT__read(int fd, LPVOID buf, unsigned int count)
{
DWORD num_read;
HANDLE hand = MSVCRT__fdtoh(fd);
/* Dont trace small reads, it gets *very* annoying */
if (count > 4)
TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count);
if (hand == INVALID_HANDLE_VALUE)
return -1;
/* Set _cnt to 0 so optimised binaries will call our implementation
* of putc/getc. See _filbuf/_flsbuf comments.
*/
if (MSVCRT_files[fd])
MSVCRT_files[fd]->_cnt = 0;
if (ReadFile(hand, buf, count, &num_read, NULL))
{
if (num_read != count && MSVCRT_files[fd])
{
TRACE(":EOF\n");
MSVCRT_files[fd]->_flag |= _IOEOF;
}
return num_read;
}
TRACE(":failed-last error (%ld)\n",GetLastError());
if (MSVCRT_files[fd])
MSVCRT_files[fd]->_flag |= _IOERR;
return -1;
}
/*********************************************************************
* _getw (MSVCRT.@)
*/
int __cdecl MSVCRT__getw(MSVCRT_FILE* file)
{
int i;
if (MSVCRT__read(file->_file, &i, sizeof(int)) != 1)
return MSVCRT_EOF;
return i;
}
/*********************************************************************
* _setmode (MSVCRT.@)
*/
int __cdecl MSVCRT__setmode(int fd,int mode)
{
if (mode & _O_TEXT)
FIXME("fd (%d) mode (%d) TEXT not implemented\n",fd,mode);
return 0;
}
/*********************************************************************
* _stat (MSVCRT.@)
*/
int __cdecl MSVCRT__stat(const char* path, struct _stat * buf)
{
DWORD dw;
WIN32_FILE_ATTRIBUTE_DATA hfi;
unsigned short mode = MSVCRT_S_IREAD;
int plen;
TRACE(":file (%s) buf(%p)\n",path,buf);
if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi))
{
TRACE("failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
return -1;
}
memset(buf,0,sizeof(struct _stat));
/* FIXME: rdev isnt drive num,despite what the docs say-what is it? */
if (isalpha(*path))
buf->st_dev = buf->st_rdev = toupper(*path - 'A'); /* drive num */
else
buf->st_dev = buf->st_rdev = MSVCRT__getdrive() - 1;
plen = strlen(path);
/* Dir, or regular file? */
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
(path[plen-1] == '\\'))
mode |= (_S_IFDIR | MSVCRT_S_IEXEC);
else
{
mode |= _S_IFREG;
/* executable? */
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
{
unsigned int ext = tolower(path[plen-1]) | (tolower(path[plen-2]) << 8)
| (tolower(path[plen-3]) << 16);
if (ext == EXE || ext == BAT || ext == CMD || ext == COM)
mode |= MSVCRT_S_IEXEC;
}
}
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
mode |= MSVCRT_S_IWRITE;
buf->st_mode = mode;
buf->st_nlink = 1;
buf->st_size = hfi.nFileSizeLow;
RtlTimeToSecondsSince1970(&hfi.ftLastAccessTime, &dw);
buf->st_atime = dw;
RtlTimeToSecondsSince1970(&hfi.ftLastWriteTime, &dw);
buf->st_mtime = buf->st_ctime = dw;
TRACE("\n%d %d %d %d %d %d\n", buf->st_mode,buf->st_nlink,buf->st_size,
buf->st_atime,buf->st_mtime, buf->st_ctime);
return 0;
}
/*********************************************************************
* _tell (MSVCRT.@)
*/
LONG __cdecl MSVCRT__tell(int fd)
{
return MSVCRT__lseek(fd, 0, SEEK_CUR);
}
/*********************************************************************
* _tempnam (MSVCRT.@)
*/
char *__cdecl MSVCRT__tempnam(const char *dir, const char *prefix)
{
char tmpbuf[MAX_PATH];
TRACE("dir (%s) prefix (%s)\n",dir,prefix);
if (GetTempFileNameA(dir,prefix,0,tmpbuf))
{
TRACE("got name (%s)\n",tmpbuf);
return MSVCRT__strdup(tmpbuf);
}
TRACE("failed-last error (%ld)\n",GetLastError());
return NULL;
}
/*********************************************************************
* _umask (MSVCRT.@)
*/
int __cdecl MSVCRT__umask(int umask)
{
int old_umask = MSVCRT_umask;
TRACE("umask (%d)\n",umask);
MSVCRT_umask = umask;
return old_umask;
}
/*********************************************************************
* _utime (MSVCRT.@)
*/
int __cdecl MSVCRT__utime(const char *path, struct _utimbuf *t)
{
int fd = MSVCRT__open(path, _O_WRONLY | _O_BINARY);
if (fd > 0)
{
int retVal = MSVCRT__futime(fd, t);
MSVCRT__close(fd);
return retVal;
}
return -1;
}
/*********************************************************************
* _write (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__write(int fd, LPCVOID buf, unsigned int count)
{
DWORD num_written;
HANDLE hand = MSVCRT__fdtoh(fd);
/* Dont trace small writes, it gets *very* annoying */
// if (count > 32)
// TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count);
if (hand == INVALID_HANDLE_VALUE)
return -1;
/* If appending, go to EOF */
if (MSVCRT_flags[fd] & _IOAPPEND)
MSVCRT__lseek(fd, 0, FILE_END);
/* Set _cnt to 0 so optimised binaries will call our implementation
* of putc/getc.
*/
if (MSVCRT_files[fd])
MSVCRT_files[fd]->_cnt = 0;
if (WriteFile(hand, buf, count, &num_written, NULL)
&& (num_written == count))
return num_written;
TRACE(":failed-last error (%ld)\n",GetLastError());
if (MSVCRT_files[fd])
MSVCRT_files[fd]->_flag |= _IOERR;
return -1;
}
/*********************************************************************
* _putw (MSVCRT.@)
*/
int __cdecl MSVCRT__putw(int val, MSVCRT_FILE* file)
{
return MSVCRT__write(file->_file, &val, sizeof(val)) == 1? val : MSVCRT_EOF;
}
/*********************************************************************
* clearerr (MSVCRT.@)
*/
VOID __cdecl MSVCRT_clearerr(MSVCRT_FILE* file)
{
TRACE(":file (%p) fd (%d)\n",file,file->_file);
file->_flag &= ~(_IOERR | _IOEOF);
}
/*********************************************************************
* fclose (MSVCRT.@)
*/
int __cdecl MSVCRT_fclose(MSVCRT_FILE* file)
{
return MSVCRT__close(file->_file);
}
/*********************************************************************
* feof (MSVCRT.@)
*/
int __cdecl MSVCRT_feof(MSVCRT_FILE* file)
{
return file->_flag & _IOEOF;
}
/*********************************************************************
* ferror (MSVCRT.@)
*/
int __cdecl MSVCRT_ferror(MSVCRT_FILE* file)
{
return file->_flag & _IOERR;
}
/*********************************************************************
* fflush (MSVCRT.@)
*/
int __cdecl MSVCRT_fflush(MSVCRT_FILE* file)
{
return MSVCRT__commit(file->_file);
}
/*********************************************************************
* fgetc (MSVCRT.@)
*/
int __cdecl MSVCRT_fgetc(MSVCRT_FILE* file)
{
char c;
if (MSVCRT__read(file->_file,&c,1) != 1)
return MSVCRT_EOF;
return c;
}
/*********************************************************************
* _fgetchar (MSVCRT.@)
*/
int __cdecl MSVCRT__fgetchar(void)
{
return MSVCRT_fgetc(MSVCRT_stdin);
}
/*********************************************************************
* _filbuf (MSVCRT.@)
*/
int __cdecl MSVCRT__filbuf(MSVCRT_FILE* file)
{
return MSVCRT_fgetc(file);
}
/*********************************************************************
* fgetpos (MSVCRT.@)
*/
int __cdecl MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
{
*pos = MSVCRT__tell(file->_file);
return (*pos == -1? -1 : 0);
}
/*********************************************************************
* fgets (MSVCRT.@)
*/
CHAR* __cdecl MSVCRT_fgets(char *s, int size, MSVCRT_FILE* file)
{
int cc;
char * buf_start = s;
TRACE(":file(%p) fd (%d) str (%p) len (%d)\n",
file,file->_file,s,size);
/* BAD, for the whole WINE process blocks... just done this way to test
* windows95's ftp.exe.
* JG - Is this true now we use ReadFile() on stdin too?
*/
for(cc = MSVCRT_fgetc(file); cc != MSVCRT_EOF && cc != '\n';
cc = MSVCRT_fgetc(file))
if (cc != '\r')
{
if (--size <= 0) break;
*s++ = (char)cc;
}
if ((cc == MSVCRT_EOF) && (s == buf_start)) /* If nothing read, return 0*/
{
TRACE(":nothing read\n");
return 0;
}
if (cc == '\n')
if (--size > 0)
*s++ = '\n';
*s = '\0';
TRACE(":got '%s'\n", buf_start);
return buf_start;
}
/*********************************************************************
* fgetwc (MSVCRT.@)
*/
WCHAR __cdecl MSVCRT_fgetwc(MSVCRT_FILE* file)
{
WCHAR wc;
if (MSVCRT__read(file->_file, &wc, sizeof(wc)) != sizeof(wc))
return MSVCRT_WEOF;
return wc;
}
/*********************************************************************
* getwc (MSVCRT.@)
*/
WCHAR __cdecl MSVCRT_getwc(MSVCRT_FILE* file)
{
return MSVCRT_fgetwc(file);
}
/*********************************************************************
* _fgetwchar (MSVCRT.@)
*/
WCHAR __cdecl MSVCRT__fgetwchar(void)
{
return MSVCRT_fgetwc(MSVCRT_stdin);
}
/*********************************************************************
* getwchar (MSVCRT.@)
*/
WCHAR __cdecl MSVCRT_getwchar(void)
{
return MSVCRT__fgetwchar();
}
/*********************************************************************
* fputwc (MSVCRT.@)
*/
WCHAR __cdecl MSVCRT_fputwc(WCHAR wc, MSVCRT_FILE* file)
{
if (MSVCRT__write(file->_file, &wc, sizeof(wc)) != sizeof(wc))
return MSVCRT_WEOF;
return wc;
}
/*********************************************************************
* _fputwchar (MSVCRT.@)
*/
WCHAR __cdecl MSVCRT__fputwchar(WCHAR wc)
{
return MSVCRT_fputwc(wc, MSVCRT_stdout);
}
/*********************************************************************
* fopen (MSVCRT.@)
*/
MSVCRT_FILE* __cdecl MSVCRT_fopen(const char *path, const char *mode)
{
MSVCRT_FILE* file;
int flags = 0, plus = 0, fd;
const char* search = mode;
TRACE(":path (%s) mode (%s)\n",path,mode);
while (*search)
if (*search++ == '+')
plus = 1;
/* map mode string to open() flags. "man fopen" for possibilities. */
switch(*mode++)
{
case 'R': case 'r':
flags = (plus ? _O_RDWR : _O_RDONLY);
break;
case 'W': case 'w':
flags = _O_CREAT | _O_TRUNC | (plus ? _O_RDWR : _O_WRONLY);
break;
case 'A': case 'a':
flags = _O_CREAT | _O_APPEND | (plus ? _O_RDWR : _O_WRONLY);
break;
default:
return NULL;
}
while (*mode)
switch (*mode++)
{
case 'B': case 'b':
flags |= _O_BINARY;
flags &= ~_O_TEXT;
break;
case 'T': case 't':
flags |= _O_TEXT;
flags &= ~_O_BINARY;
break;
case '+':
break;
default:
FIXME(":unknown flag %c not supported\n",mode[-1]);
}
fd = MSVCRT__open(path, flags);
if (fd < 0)
return NULL;
file = MSVCRT__alloc_fp(fd);
TRACE(":get file (%p)\n",file);
if (!file)
MSVCRT__close(fd);
return file;
}
/*********************************************************************
* _fsopen (MSVCRT.@)
*/
MSVCRT_FILE* __cdecl MSVCRT__fsopen(const char *path, const char *mode, int share)
{
FIXME(":(%s,%s,%d),ignoring share mode!\n",path,mode,share);
return MSVCRT_fopen(path,mode);
}
/*********************************************************************
* fputc (MSVCRT.@)
*/
int __cdecl MSVCRT_fputc(int c, MSVCRT_FILE* file)
{
return MSVCRT__write(file->_file, &c, 1) == 1? c : MSVCRT_EOF;
}
/*********************************************************************
* _flsbuf (MSVCRT.@)
*/
int __cdecl MSVCRT__flsbuf(int c, MSVCRT_FILE* file)
{
return MSVCRT_fputc(c,file);
}
/*********************************************************************
* _fputchar (MSVCRT.@)
*/
int __cdecl MSVCRT__fputchar(int c)
{
return MSVCRT_fputc(c, MSVCRT_stdout);
}
/*********************************************************************
* fread (MSVCRT.@)
*/
DWORD __cdecl MSVCRT_fread(LPVOID ptr, int size, int nmemb, MSVCRT_FILE* file)
{
DWORD read = MSVCRT__read(file->_file,ptr, size * nmemb);
if (read <= 0)
return 0;
return read / size;
}
/*********************************************************************
* freopen (MSVCRT.@)
*
*/
MSVCRT_FILE* __cdecl MSVCRT_freopen(const char *path, const char *mode,MSVCRT_FILE* file)
{
MSVCRT_FILE* newfile;
int fd;
TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n",path,mode,file,file->_file);
if (!file || ((fd = file->_file) < 0) || fd > MSVCRT_fdend)
return NULL;
if (fd > 2)
{
FIXME(":reopen on user file not implemented!\n");
MSVCRT__set_errno(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
}
/* first, create the new file */
if ((newfile = MSVCRT_fopen(path,mode)) == NULL)
return NULL;
if (fd < 3 && SetStdHandle(fd == 0 ? STD_INPUT_HANDLE :
(fd == 1? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE),
MSVCRT_handles[newfile->_file]))
{
/* Redirecting std handle to file , copy over.. */
MSVCRT_handles[fd] = MSVCRT_handles[newfile->_file];
MSVCRT_flags[fd] = MSVCRT_flags[newfile->_file];
memcpy(&MSVCRT__iob[fd], newfile, sizeof (MSVCRT_FILE));
MSVCRT__iob[fd]._file = fd;
/* And free up the resources allocated by fopen, but
* not the HANDLE we copied. */
MSVCRT_free(MSVCRT_files[fd]);
MSVCRT__free_fd(newfile->_file);
return &MSVCRT__iob[fd];
}
WARN(":failed-last error (%ld)\n",GetLastError());
MSVCRT_fclose(newfile);
MSVCRT__set_errno(GetLastError());
return NULL;
}
/*********************************************************************
* fsetpos (MSVCRT.@)
*/
int __cdecl MSVCRT_fsetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
{
return MSVCRT__lseek(file->_file,*pos,SEEK_SET);
}
/*********************************************************************
* fscanf (MSVCRT.@)
*/
int __cdecl MSVCRT_fscanf(MSVCRT_FILE* file, const char *format, ...)
{
/* NOTE: If you extend this function, extend MSVCRT__cscanf in console.c too */
int rd = 0;
int nch;
va_list ap;
if (!*format) return 0;
WARN("%p (\"%s\"): semi-stub\n", file, format);
nch = MSVCRT_fgetc(file);
va_start(ap, format);
while (*format) {
if (*format == ' ') {
/* skip whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT_fgetc(file);
}
else if (*format == '%') {
int st = 0;
format++;
switch(*format) {
case 'd': { /* read an integer */
int*val = va_arg(ap, int*);
int cur = 0;
/* skip initial whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT_fgetc(file);
/* get sign and first digit */
if (nch == '-') {
nch = MSVCRT_fgetc(file);
if (isdigit(nch))
cur = -(nch - '0');
else break;
} else {
if (isdigit(nch))
cur = nch - '0';
else break;
}
nch = MSVCRT_fgetc(file);
/* read until no more digits */
while ((nch!=MSVCRT_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = MSVCRT_fgetc(file);
}
st = 1;
*val = cur;
}
break;
case 'f': { /* read a float */
float*val = va_arg(ap, float*);
float cur = 0;
/* skip initial whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT_fgetc(file);
/* get sign and first digit */
if (nch == '-') {
nch = MSVCRT_fgetc(file);
if (isdigit(nch))
cur = -(nch - '0');
else break;
} else {
if (isdigit(nch))
cur = nch - '0';
else break;
}
/* read until no more digits */
while ((nch!=MSVCRT_EOF) && isdigit(nch)) {
cur = cur*10 + (nch - '0');
nch = MSVCRT_fgetc(file);
}
if (nch == '.') {
/* handle decimals */
float dec = 1;
nch = MSVCRT_fgetc(file);
while ((nch!=MSVCRT_EOF) && isdigit(nch)) {
dec /= 10;
cur += dec * (nch - '0');
nch = MSVCRT_fgetc(file);
}
}
st = 1;
*val = cur;
}
break;
case 's': { /* read a word */
char*str = va_arg(ap, char*);
char*sptr = str;
/* skip initial whitespace */
while ((nch!=MSVCRT_EOF) && isspace(nch))
nch = MSVCRT_fgetc(file);
/* read until whitespace */
while ((nch!=MSVCRT_EOF) && !isspace(nch)) {
*sptr++ = nch; st++;
nch = MSVCRT_fgetc(file);
}
/* terminate */
*sptr = 0;
TRACE("read word: %s\n", str);
}
break;
default: FIXME("unhandled: %%%c\n", *format);
}
if (st) rd++;
else break;
}
else {
/* check for character match */
if (nch == *format)
nch = MSVCRT_fgetc(file);
else break;
}
format++;
}
va_end(ap);
if (nch!=MSVCRT_EOF) {
WARN("need ungetch\n");
}
TRACE("returning %d\n", rd);
return rd;
}
/*********************************************************************
* fseek (MSVCRT.@)
*/
LONG __cdecl MSVCRT_fseek(MSVCRT_FILE* file, LONG offset, int whence)
{
return MSVCRT__lseek(file->_file,offset,whence);
}
/*********************************************************************
* ftell (MSVCRT.@)
*/
LONG __cdecl MSVCRT_ftell(MSVCRT_FILE* file)
{
return MSVCRT__tell(file->_file);
}
/*********************************************************************
* fwrite (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT_fwrite(LPCVOID ptr, int size, int nmemb, MSVCRT_FILE* file)
{
unsigned int written = MSVCRT__write(file->_file, ptr, size * nmemb);
if (written <= 0)
return 0;
return written / size;
}
/*********************************************************************
* fputs (MSVCRT.@)
*/
int __cdecl MSVCRT_fputs(const char *s, MSVCRT_FILE* file)
{
return MSVCRT_fwrite(s,strlen(s),1,file) == 1 ? 0 : MSVCRT_EOF;
}
/*********************************************************************
* getchar (MSVCRT.@)
*/
int __cdecl MSVCRT_getchar(void)
{
return MSVCRT_fgetc(MSVCRT_stdin);
}
/*********************************************************************
* getc (MSVCRT.@)
*/
int __cdecl MSVCRT_getc(MSVCRT_FILE* file)
{
return MSVCRT_fgetc(file);
}
/*********************************************************************
* gets (MSVCRT.@)
*/
char *__cdecl MSVCRT_gets(char *buf)
{
int cc;
char * buf_start = buf;
/* BAD, for the whole WINE process blocks... just done this way to test
* windows95's ftp.exe.
* JG 19/9/00: Is this still true, now we are using ReadFile?
*/
for(cc = MSVCRT_fgetc(MSVCRT_stdin); cc != MSVCRT_EOF && cc != '\n';
cc = MSVCRT_fgetc(MSVCRT_stdin))
if(cc != '\r') *buf++ = (char)cc;
*buf = '\0';
TRACE("got '%s'\n", buf_start);
return buf_start;
}
/*********************************************************************
* putc (MSVCRT.@)
*/
int __cdecl MSVCRT_putc(int c, MSVCRT_FILE* file)
{
return MSVCRT_fputc(c, file);
}
/*********************************************************************
* putchar (MSVCRT.@)
*/
void __cdecl MSVCRT_putchar(int c)
{
MSVCRT_fputc(c, MSVCRT_stdout);
}
/*********************************************************************
* puts (MSVCRT.@)
*/
int __cdecl MSVCRT_puts(const char *s)
{
int retval = MSVCRT_EOF;
if (MSVCRT_fwrite(s,strlen(s),1,MSVCRT_stdout) == 1)
return MSVCRT_fwrite("\n",1,1,MSVCRT_stdout) == 1 ? 0 : MSVCRT_EOF;
return retval;
}
/*********************************************************************
* remove (MSVCRT.@)
*/
int __cdecl MSVCRT_remove(const char *path)
{
TRACE(":path (%s)\n",path);
if (DeleteFileA(path))
return 0;
TRACE(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* scanf (MSVCRT.@)
*/
int __cdecl MSVCRT_scanf(const char *format, ...)
{
va_list valist;
int res;
va_start(valist, format);
res = MSVCRT_fscanf(MSVCRT_stdin, format, valist);
va_end(valist);
return res;
}
/*********************************************************************
* rename (MSVCRT.@)
*/
int __cdecl MSVCRT_rename(const char *oldpath,const char *newpath)
{
TRACE(":from %s to %s\n",oldpath,newpath);
if (MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
return 0;
TRACE(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************
* setbuf (MSVCRT.@)
*/
int __cdecl MSVCRT_setbuf(MSVCRT_FILE* file, char *buf)
{
TRACE(":file (%p) fd (%d) buf (%p)\n", file, file->_file,buf);
if (buf)
WARN(":user buffer will not be used!\n");
/* FIXME: no buffering for now */
return 0;
}
/*********************************************************************
* tmpnam (MSVCRT.@)
*/
char *__cdecl MSVCRT_tmpnam(char *s)
{
char tmpbuf[MAX_PATH];
char* prefix = "TMP";
if (!GetTempPathA(MAX_PATH,tmpbuf) ||
!GetTempFileNameA(tmpbuf,prefix,0,MSVCRT_tmpname))
{
TRACE(":failed-last error (%ld)\n",GetLastError());
return NULL;
}
TRACE(":got tmpnam %s\n",MSVCRT_tmpname);
s = MSVCRT_tmpname;
return s;
}
/*********************************************************************
* tmpfile (MSVCRT.@)
*/
MSVCRT_FILE* __cdecl MSVCRT_tmpfile(void)
{
char *filename = MSVCRT_tmpnam(NULL);
int fd;
fd = MSVCRT__open(filename, _O_CREAT | _O_BINARY | _O_RDWR | _O_TEMPORARY);
if (fd != -1)
return MSVCRT__alloc_fp(fd);
return NULL;
}
extern int vsnprintf(void *, unsigned int, const void*, va_list);
/*********************************************************************
* vfprintf (MSVCRT.@)
*/
int __cdecl MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, va_list valist)
{
char buf[2048], *mem = buf;
int written, resize = sizeof(buf);
/* There are two conventions for vsnprintf failing:
* Return -1 if we truncated, or
* Return the number of bytes that would have been written
* The code below handles both cases
*/
while ((written = vsnprintf(mem, resize, format, valist)) == -1 ||
written > resize)
{
resize = (written == -1 ? resize * 2 : written + 1);
if (mem != buf)
MSVCRT_free (mem);
if (!(mem = (char *)MSVCRT_malloc(resize)))
return MSVCRT_EOF;
}
if (mem != buf)
MSVCRT_free (mem);
return MSVCRT_fwrite(mem, 1, written, file);
}
/*********************************************************************
* fprintf (MSVCRT.@)
*/
int __cdecl MSVCRT_fprintf(MSVCRT_FILE* file, const char *format, ...)
{
va_list valist;
int res;
va_start(valist, format);
res = MSVCRT_vfprintf(file, format, valist);
va_end(valist);
return res;
}
/*********************************************************************
* printf (MSVCRT.@)
*/
int __cdecl MSVCRT_printf(const char *format, ...)
{
va_list valist;
int res;
va_start(valist, format);
res = MSVCRT_vfprintf(MSVCRT_stdout, format, valist);
va_end(valist);
return res;
}
/*
* msvcrt.dll heap functions
*
* Copyright 2000 Jon Griffiths
*
* Note: Win32 heap operations are MT safe. We only lock the new
* handler and non atomic heap operations
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* MT */
extern CRITICAL_SECTION MSVCRT_heap_cs;
#define LOCK_HEAP EnterCriticalSection(&MSVCRT_heap_cs)
#define UNLOCK_HEAP LeaveCriticalSection(&MSVCRT_heap_cs)
/* heap function constants */
#define MSVCRT_HEAPEMPTY -1
#define MSVCRT_HEAPOK -2
#define MSVCRT_HEAPBADBEGIN -3
#define MSVCRT_HEAPBADNODE -4
#define MSVCRT_HEAPEND -5
#define MSVCRT_HEAPBADPTR -6
#define MSVCRT_FREEENTRY 0
#define MSVCRT_USEDENTRY 1
typedef struct MSVCRT_heapinfo
{
int * _pentry;
size_t _size;
int _useflag;
} MSVCRT_HEAPINFO;
typedef void (*MSVCRT_new_handler_func)(void);
static MSVCRT_new_handler_func MSVCRT_new_handler;
static int MSVCRT_new_mode;
/*********************************************************************
* ??2@YAPAXI@Z (MSVCRT.@)
*/
void *__cdecl MSVCRT_operator_new(unsigned long size)
{
void *retval = HeapAlloc(GetProcessHeap(), 0, size);
TRACE("(%ld) returning %p\n", size, retval);
LOCK_HEAP;
if(retval && MSVCRT_new_handler)
(*MSVCRT_new_handler)();
UNLOCK_HEAP;
return retval;
}
/*********************************************************************
* ??3@YAXPAX@Z (MSVCRT.@)
*/
void __cdecl MSVCRT_operator_delete(void *mem)
{
TRACE("(%p)\n", mem);
HeapFree(GetProcessHeap(), 0, mem);
}
/*********************************************************************
* ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@)
*/
MSVCRT_new_handler_func __cdecl MSVCRT__query_new_handler(void)
{
return MSVCRT_new_handler;
}
/*********************************************************************
* ?_query_new_mode@@YAHXZ (MSVCRT.@)
*/
int __cdecl MSVCRT__query_new_mode(void)
{
return MSVCRT_new_mode;
}
/*********************************************************************
* ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@)
*/
MSVCRT_new_handler_func __cdecl MSVCRT__set_new_handler(MSVCRT_new_handler_func func)
{
MSVCRT_new_handler_func old_handler;
LOCK_HEAP;
old_handler = MSVCRT_new_handler;
MSVCRT_new_handler = func;
UNLOCK_HEAP;
return old_handler;
}
/*********************************************************************
* ?_set_new_mode@@YAHH@Z (MSVCRT.@)
*/
int __cdecl MSVCRT__set_new_mode(int mode)
{
int old_mode;
LOCK_HEAP;
old_mode = MSVCRT_new_mode;
MSVCRT_new_mode = mode;
UNLOCK_HEAP;
return old_mode;
}
/*********************************************************************
* _expand (MSVCRT.@)
*/
void *__cdecl MSVCRT__expand(void *mem, unsigned int size)
{
return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
}
/*********************************************************************
* _heapchk (MSVCRT.@)
*/
int __cdecl MSVCRT__heapchk(void)
{
if (!HeapValidate( GetProcessHeap(), 0, NULL))
{
MSVCRT__set_errno(GetLastError());
return MSVCRT_HEAPBADNODE;
}
return MSVCRT_HEAPOK;
}
/*********************************************************************
* _heapmin (MSVCRT.@)
*/
int __cdecl MSVCRT__heapmin(void)
{
if (!HeapCompact( GetProcessHeap(), 0 ))
{
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
MSVCRT__set_errno(GetLastError());
return -1;
}
return 0;
}
/*********************************************************************
* _heapwalk (MSVCRT.@)
*/
int __cdecl MSVCRT__heapwalk(MSVCRT_HEAPINFO *next)
{
PROCESS_HEAP_ENTRY phe;
LOCK_HEAP;
phe.lpData = next->_pentry;
phe.cbData = next->_size;
phe.wFlags = next->_useflag == MSVCRT_USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
!HeapValidate( GetProcessHeap(), 0, phe.lpData ))
{
UNLOCK_HEAP;
MSVCRT__set_errno(GetLastError());
return MSVCRT_HEAPBADNODE;
}
do
{
if (!HeapWalk( GetProcessHeap(), &phe ))
{
UNLOCK_HEAP;
if (GetLastError() == ERROR_NO_MORE_ITEMS)
return MSVCRT_HEAPEND;
MSVCRT__set_errno(GetLastError());
if (!phe.lpData)
return MSVCRT_HEAPBADBEGIN;
return MSVCRT_HEAPBADNODE;
}
} while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
UNLOCK_HEAP;
next->_pentry = phe.lpData;
next->_size = phe.cbData;
next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? MSVCRT_USEDENTRY : MSVCRT_FREEENTRY;
return MSVCRT_HEAPOK;
}
/*********************************************************************
* _heapset (MSVCRT.@)
*/
int __cdecl MSVCRT__heapset(unsigned int value)
{
int retval;
MSVCRT_HEAPINFO heap;
memset( &heap, 0, sizeof(MSVCRT_HEAPINFO) );
LOCK_HEAP;
while ((retval = MSVCRT__heapwalk(&heap)) == MSVCRT_HEAPOK)
{
if (heap._useflag == MSVCRT_FREEENTRY)
memset(heap._pentry, value, heap._size);
}
UNLOCK_HEAP;
return retval == MSVCRT_HEAPEND? MSVCRT_HEAPOK : retval;
}
/*********************************************************************
* _msize (MSVCRT.@)
*/
long __cdecl MSVCRT__msize(void *mem)
{
long size = HeapSize(GetProcessHeap(),0,mem);
if (size == -1)
{
WARN(":Probably called with non wine-allocated memory, ret = -1\n");
/* At least the Win32 crtdll/msvcrt also return -1 in this case */
}
return size;
}
/*********************************************************************
* calloc (MSVCRT.@)
*/
void *__cdecl MSVCRT_calloc(unsigned int size, unsigned int count)
{
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
}
/*********************************************************************
* free (MSVCRT.@)
*/
void __cdecl MSVCRT_free(void *ptr)
{
HeapFree(GetProcessHeap(),0,ptr);
}
/*********************************************************************
* malloc (MSVCRT.@)
*/
void * __cdecl MSVCRT_malloc(unsigned int size)
{
void *ret = HeapAlloc(GetProcessHeap(),0,size);
if (!ret)
MSVCRT__set_errno(GetLastError());
return ret;
}
/*********************************************************************
* realloc (MSVCRT.@)
*/
void *__cdecl MSVCRT_realloc(void *ptr, unsigned int size)
{
return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
}
/*
* msvcrt.dll locale functions
*
* Copyright 2000 Jon Griffiths
*/
#include "winnt.h"
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* FIXME: Need to hold locale for each LC_* type and aggregate
* string to produce lc_all.
*/
#define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */
#define MAX_LOCALE_LENGTH 256
char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH];
LCID MSVCRT_current_lc_all_lcid;
unsigned int MSVCRT_current_lc_all_cp;
/* MT */
extern CRITICAL_SECTION MSVCRT_locale_cs;
#define LOCK_LOCALE EnterCriticalSection(&MSVCRT_locale_cs)
#define UNLOCK_LOCALE LeaveCriticalSection(&MSVCRT_locale_cs)
/* ctype data modified when the locale changes */
extern WORD MSVCRT__ctype [257];
extern WORD MSVCRT_current_ctype[257];
extern WORD* MSVCRT__pctype;
/* mbctype data modified when the locale changes */
extern int MSVCRT___mb_cur_max;
extern unsigned char MSVCRT_mbctype[257];
#define MSVCRT_LEADBYTE 0x8000
/* Locales */
#define MSVCRT_LC_ALL 0
#define MSVCRT_LC_COLLATE 1
#define MSVCRT_LC_CTYPE 2
#define MSVCRT_LC_MONETARY 3
#define MSVCRT_LC_NUMERIC 4
#define MSVCRT_LC_TIME 5
#define MSVCRT_LC_MIN MSVCRT_LC_ALL
#define MSVCRT_LC_MAX MSVCRT_LC_TIME
/* Friendly country strings & iso codes for synonym support.
* Based on MS documentation for setlocale().
*/
static const char* _country_synonyms[] =
{
"Hong Kong","HK",
"Hong-Kong","HK",
"New Zealand","NZ",
"New-Zealand","NZ",
"PR China","CN",
"PR-China","CN",
"United Kingdom","GB",
"United-Kingdom","GB",
"Britain","GB",
"England","GB",
"Great Britain","GB",
"United States","US",
"United-States","US",
"America","US"
};
/* INTERNAL: Map a synonym to an ISO code */
static void remap_synonym(char *name)
{
size_t i;
for (i = 0; i < sizeof(_country_synonyms)/sizeof(char*); i += 2 )
{
if (!strcasecmp(_country_synonyms[i],name))
{
TRACE(":Mapping synonym %s to %s\n",name,_country_synonyms[i+1]);
name[0] = _country_synonyms[i+1][0];
name[1] = _country_synonyms[i+1][1];
name[2] = '\0';
return;
}
}
}
/* Note: Flags are weighted in order of matching importance */
#define FOUND_LANGUAGE 0x4
#define FOUND_COUNTRY 0x2
#define FOUND_CODEPAGE 0x1
typedef struct {
char search_language[MAX_ELEM_LEN];
char search_country[MAX_ELEM_LEN];
char search_codepage[MAX_ELEM_LEN];
char found_language[MAX_ELEM_LEN];
char found_country[MAX_ELEM_LEN];
char found_codepage[MAX_ELEM_LEN];
unsigned int match_flags;
LANGID found_lang_id;
} locale_search_t;
#define CONTINUE_LOOKING TRUE
#define STOP_LOOKING FALSE
/* INTERNAL: Get and compare locale info with a given string */
static int compare_info(LCID lcid, DWORD flags, char* buff, const char* cmp)
{
buff[0] = 0;
GetLocaleInfoA(lcid, flags|LOCALE_NOUSEROVERRIDE,buff, MAX_ELEM_LEN);
if (!buff[0] || !cmp[0])
return 0;
/* Partial matches are allowed, e.g. "Germ" matches "Germany" */
return !strncasecmp(cmp, buff, strlen(cmp));
}
/* INTERNAL: Callback for enumerated languages */
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
static BOOL CALLBACK
find_best_locale_proc(HMODULE hModule UNUSED, LPCSTR type UNUSED,
LPCSTR name UNUSED, WORD LangID, LONG lParam)
{
locale_search_t *res = (locale_search_t *)lParam;
const LCID lcid = MAKELCID(LangID, SORT_DEFAULT);
char buff[MAX_ELEM_LEN];
unsigned int flags = 0;
if(PRIMARYLANGID(LangID) == LANG_NEUTRAL)
return CONTINUE_LOOKING;
/* Check Language */
if (compare_info(lcid,LOCALE_SISO639LANGNAME,buff,res->search_language) ||
compare_info(lcid,LOCALE_SABBREVLANGNAME,buff,res->search_language) ||
compare_info(lcid,LOCALE_SENGLANGUAGE,buff,res->search_language))
{
TRACE(":Found language: %s->%s\n", res->search_language, buff);
flags |= FOUND_LANGUAGE;
memcpy(res->found_language,res->search_language,MAX_ELEM_LEN);
}
else if (res->match_flags & FOUND_LANGUAGE)
{
return CONTINUE_LOOKING;
}
/* Check Country */
if (compare_info(lcid,LOCALE_SISO3166CTRYNAME,buff,res->search_country) ||
compare_info(lcid,LOCALE_SABBREVCTRYNAME,buff,res->search_country) ||
compare_info(lcid,LOCALE_SENGCOUNTRY,buff,res->search_country))
{
TRACE("Found country:%s->%s\n", res->search_country, buff);
flags |= FOUND_COUNTRY;
memcpy(res->found_country,res->search_country,MAX_ELEM_LEN);
}
else if (res->match_flags & FOUND_COUNTRY)
{
return CONTINUE_LOOKING;
}
/* Check codepage */
if (compare_info(lcid,LOCALE_IDEFAULTCODEPAGE,buff,res->search_codepage) ||
(compare_info(lcid,LOCALE_IDEFAULTANSICODEPAGE,buff,res->search_codepage)))
{
TRACE("Found codepage:%s->%s\n", res->search_codepage, buff);
flags |= FOUND_CODEPAGE;
memcpy(res->found_codepage,res->search_codepage,MAX_ELEM_LEN);
}
else if (res->match_flags & FOUND_CODEPAGE)
{
return CONTINUE_LOOKING;
}
if (flags > res->match_flags)
{
/* Found a better match than previously */
res->match_flags = flags;
res->found_lang_id = LangID;
}
if (flags & (FOUND_LANGUAGE & FOUND_COUNTRY & FOUND_CODEPAGE))
{
TRACE(":found exact locale match\n");
return STOP_LOOKING;
}
return CONTINUE_LOOKING;
}
extern int atoi(const char *);
/* Internal: Find the LCID for a locale specification */
static LCID MSVCRT_locale_to_LCID(locale_search_t* locale)
{
LCID lcid;
EnumResourceLanguagesA(GetModuleHandleA("KERNEL32"), RT_STRINGA,
(LPCSTR)LOCALE_ILANGUAGE,find_best_locale_proc,
(LONG)locale);
if (!locale->match_flags)
return 0;
/* If we were given something that didn't match, fail */
if (locale->search_country[0] && !(locale->match_flags & FOUND_COUNTRY))
return 0;
lcid = MAKELCID(locale->found_lang_id, SORT_DEFAULT);
/* Populate partial locale, translating LCID to locale string elements */
if (!locale->found_codepage[0])
{
/* Even if a codepage is not enumerated for a locale
* it can be set if valid */
if (locale->search_codepage[0])
{
if (IsValidCodePage(atoi(locale->search_codepage)))
memcpy(locale->found_codepage,locale->search_codepage,MAX_ELEM_LEN);
else
{
/* Special codepage values: OEM & ANSI */
if (strcasecmp(locale->search_codepage,"OCP"))
{
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
}
if (strcasecmp(locale->search_codepage,"ACP"))
{
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
}
else
return 0;
if (!atoi(locale->found_codepage))
return 0;
}
}
else
{
/* Prefer ANSI codepages if present */
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
if (!locale->found_codepage[0] || !atoi(locale->found_codepage))
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
}
}
GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE|LOCALE_NOUSEROVERRIDE,
locale->found_language, MAX_ELEM_LEN);
GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY|LOCALE_NOUSEROVERRIDE,
locale->found_country, MAX_ELEM_LEN);
return lcid;
}
extern int snprintf(char *, int, const char *, ...);
/* INTERNAL: Set ctype behaviour for a codepage */
static void MSVCRT_set_ctype(unsigned int codepage, LCID lcid)
{
CPINFO cp;
memset(&cp, 0, sizeof(CPINFO));
if (GetCPInfo(codepage, &cp))
{
int i;
char str[3];
unsigned char *traverse = (unsigned char *)cp.LeadByte;
memset(MSVCRT_current_ctype, 0, sizeof(MSVCRT__ctype));
MSVCRT_current_lc_all_cp = codepage;
/* Switch ctype macros to MBCS if needed */
MSVCRT___mb_cur_max = cp.MaxCharSize;
/* Set remaining ctype flags: FIXME: faster way to do this? */
str[1] = str[2] = 0;
for (i = 0; i < 256; i++)
{
if (!(MSVCRT__pctype[i] & MSVCRT_LEADBYTE))
{
str[0] = i;
GetStringTypeA(lcid, CT_CTYPE1, str, 1, MSVCRT__pctype + i);
}
}
/* Set leadbyte flags */
while (traverse[0] || traverse[1])
{
for( i = traverse[0]; i <= traverse[1]; i++ )
MSVCRT_current_ctype[i+1] |= MSVCRT_LEADBYTE;
traverse += 2;
};
}
}
/*********************************************************************
* setlocale (MSVCRT.@)
*/
char *__cdecl MSVCRT_setlocale(int category, const char *locale)
{
LCID lcid = 0;
locale_search_t lc;
int haveLang, haveCountry, haveCP;
char* next;
int lc_all = 0;
TRACE("(%d %s)\n",category,locale);
if (category < MSVCRT_LC_MIN || category > MSVCRT_LC_MAX)
return NULL;
if (locale == NULL)
{
/* Report the current Locale */
return MSVCRT_current_lc_all;
}
LOCK_LOCALE;
if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_')
{
FIXME(":restore previous locale not implemented!\n");
/* FIXME: Easiest way to do this is parse the string and
* call this function recursively with its elements,
* Where they differ for each lc_ type.
*/
UNLOCK_LOCALE;
return MSVCRT_current_lc_all;
}
/* Default Locale: Special case handling */
if (!strlen(locale) || ((toupper(locale[0]) == 'C') && !locale[1]))
{
MSVCRT_current_lc_all[0] = 'C';
MSVCRT_current_lc_all[1] = '\0';
MSVCRT_current_lc_all_cp = GetACP();
switch (category) {
case MSVCRT_LC_ALL:
lc_all = 1; /* Fall through all cases ... */
case MSVCRT_LC_COLLATE:
if (!lc_all) break;
case MSVCRT_LC_CTYPE:
/* Restore C locale ctype info */
MSVCRT___mb_cur_max = 1;
memcpy(MSVCRT_current_ctype, MSVCRT__ctype, sizeof(MSVCRT__ctype));
memset(MSVCRT_mbctype, 0, sizeof(MSVCRT_mbctype));
if (!lc_all) break;
case MSVCRT_LC_MONETARY:
if (!lc_all) break;
case MSVCRT_LC_NUMERIC:
if (!lc_all) break;
case MSVCRT_LC_TIME:
}
UNLOCK_LOCALE;
return MSVCRT_current_lc_all;
}
/* Get locale elements */
haveLang = haveCountry = haveCP = 0;
memset(&lc,0,sizeof(lc));
next = strchr(locale,'_');
if (next && next != locale)
{
haveLang = 1;
strncpy(lc.search_language,locale,next-locale);
locale += next-locale+1;
}
next = strchr(locale,'.');
if (next)
{
haveCP = 1;
if (next == locale)
{
locale++;
strncpy(lc.search_codepage, locale, MAX_ELEM_LEN);
}
else
{
if (haveLang)
{
haveCountry = 1;
strncpy(lc.search_country,locale,next-locale);
locale += next-locale+1;
}
else
{
haveLang = 1;
strncpy(lc.search_language,locale,next-locale);
locale += next-locale+1;
}
strncpy(lc.search_codepage, locale, MAX_ELEM_LEN);
}
}
else
{
if (haveLang)
{
haveCountry = 1;
strncpy(lc.search_country, locale, MAX_ELEM_LEN);
}
else
{
haveLang = 1;
strncpy(lc.search_language, locale, MAX_ELEM_LEN);
}
}
if (haveCountry)
remap_synonym(lc.search_country);
if (haveCP && !haveCountry && !haveLang)
{
FIXME(":Codepage only locale not implemented");
/* FIXME: Use default lang/country and skip locale_to_LCID()
* call below...
*/
UNLOCK_LOCALE;
return NULL;
}
lcid = MSVCRT_locale_to_LCID(&lc);
TRACE(":found LCID %ld\n",lcid);
if (lcid == 0)
{
UNLOCK_LOCALE;
return NULL;
}
MSVCRT_current_lc_all_lcid = lcid;
snprintf(MSVCRT_current_lc_all,MAX_LOCALE_LENGTH,"%s_%s.%s",
lc.found_language,lc.found_country,lc.found_codepage);
switch (category) {
case MSVCRT_LC_ALL:
lc_all = 1; /* Fall through all cases ... */
case MSVCRT_LC_COLLATE:
if (!lc_all) break;
case MSVCRT_LC_CTYPE:
MSVCRT_set_ctype(atoi(lc.found_codepage),lcid);
if (!lc_all) break;
case MSVCRT_LC_MONETARY:
if (!lc_all) break;
case MSVCRT_LC_NUMERIC:
if (!lc_all) break;
case MSVCRT_LC_TIME:
}
UNLOCK_LOCALE;
return MSVCRT_current_lc_all;
}
/*********************************************************************
* _Getdays (MSVCRT.@)
*/
const char *__cdecl MSVCRT__Getdays(void)
{
static const char *MSVCRT_days = ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:"
"Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
/* FIXME: Use locale */
TRACE("(void) semi-stub");
return MSVCRT_days;
}
/*********************************************************************
* _Getmonths (MSVCRT.@)
*/
const char *__cdecl MSVCRT__Getmonths(void)
{
static const char *MSVCRT_months = ":Jan:January:Feb:February:Mar:March:Apr:"
"April:May:May:Jun:June:Jul:July:Aug:August:Sep:September:Oct:"
"October:Nov:November:Dec:December";
/* FIXME: Use locale */
TRACE("(void) semi-stub");
return MSVCRT_months;
}
/*********************************************************************
* _Getnames (MSVCRT.@)
*/
const char *__cdecl MSVCRT__Getnames(void)
{
/* FIXME: */
TRACE("(void) stub");
return "";
}
/*********************************************************************
* _Strftime (MSVCRT.@)
*/
const char *__cdecl MSVCRT__Strftime(char *out, unsigned int len, const char *fmt,
const /* struct tm */ void *tm, void *foo)
{
/* FIXME: */
TRACE("(%p %d %s %p %p) stub", out, len, fmt, tm, foo);
return "";
}
/* FIXME: MBCP probably belongs in mbcs.c */
/*********************************************************************
* _setmbcp (MSVCRT.@)
*/
void __cdecl MSVCRT__setmbcp(int cp)
{
LOCK_LOCALE;
if (MSVCRT_current_lc_all_cp != cp)
{
/* FIXME: set ctype behaviour for this cp */
MSVCRT_current_lc_all_cp = cp;
}
UNLOCK_LOCALE;
}
/*********************************************************************
* _getmbcp (MSVCRT.@)
*/
int __cdecl MSVCRT__getmbcp(void)
{
return MSVCRT_current_lc_all_cp;
}
/*
* msvcrt.dll initialisation functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* Index to TLS */
DWORD MSVCRT_tls_index;
/* MT locks */
CRITICAL_SECTION MSVCRT_heap_cs;
CRITICAL_SECTION MSVCRT_file_cs;
CRITICAL_SECTION MSVCRT_exit_cs;
CRITICAL_SECTION MSVCRT_console_cs;
CRITICAL_SECTION MSVCRT_locale_cs;
static inline BOOL MSVCRT_init_tls(void);
static inline BOOL MSVCRT_free_tls(void);
static inline void MSVCRT_init_critical_sections(void);
static inline void MSVCRT_free_critical_sections(void);
#ifdef __GNUC__
const char *MSVCRT_get_reason(DWORD reason) __attribute__((unused));
#else
const char *MSVCRT_get_reason(DWORD reason);
#endif
void MSVCRT_init_io(void);
void MSVCRT_init_console(void);
void MSVCRT_free_console(void);
void MSVCRT_init_args(void);
void MSVCRT_free_args(void);
void MSVCRT_init_vtables(void);
char *__cdecl MSVCRT_setlocale(int category, const char *locale);
/*********************************************************************
* Init
*/
BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
MSVCRT_thread_data *tls;
TRACE("(0x%08x, %s, %p) pid(%ld), tid(%ld), tls(%ld)\n",
hinstDLL, MSVCRT_get_reason(fdwReason), lpvReserved,
(long)GetCurrentProcessId(), (long)GetCurrentThreadId(),
(long)MSVCRT_tls_index);
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
if (!MSVCRT_init_tls())
return FALSE;
MSVCRT_init_vtables();
MSVCRT_init_critical_sections();
MSVCRT_init_io();
MSVCRT_init_console();
MSVCRT_init_args();
MSVCRT_setlocale(0, "C");
TRACE("finished process init\n");
/* FALL THROUGH for Initial TLS allocation!! */
case DLL_THREAD_ATTACH:
TRACE("starting thread init\n");
/* Create TLS */
tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(MSVCRT_thread_data));
if (!tls || !TlsSetValue(MSVCRT_tls_index, tls))
{
ERR("TLS init failed! error = %ld\n", GetLastError());
return FALSE;
}
TRACE("finished thread init\n");
break;
case DLL_PROCESS_DETACH:
MSVCRT_free_critical_sections();
MSVCRT__fcloseall();
MSVCRT_free_console();
MSVCRT_free_args();
if (!MSVCRT_free_tls())
return FALSE;
TRACE("finished process free\n");
break;
case DLL_THREAD_DETACH:
/* Free TLS */
tls = TlsGetValue(MSVCRT_tls_index);
if (!tls)
{
ERR("TLS free failed! error = %ld\n", GetLastError());
return FALSE;
}
HeapFree(GetProcessHeap(), 0, tls);
TRACE("finished thread free\n");
break;
}
return TRUE;
}
static inline BOOL MSVCRT_init_tls(void)
{
MSVCRT_tls_index = TlsAlloc();
if (MSVCRT_tls_index == TLS_OUT_OF_INDEXES)
{
ERR("TlsAlloc() failed!\n");
return FALSE;
}
return TRUE;
}
static inline BOOL MSVCRT_free_tls(void)
{
if (!TlsFree(MSVCRT_tls_index))
{
ERR("TlsFree() failed!\n");
return FALSE;
}
return TRUE;
}
static inline void MSVCRT_init_critical_sections(void)
{
InitializeCriticalSectionAndSpinCount(&MSVCRT_heap_cs, 4000);
InitializeCriticalSection(&MSVCRT_file_cs);
InitializeCriticalSection(&MSVCRT_exit_cs);
InitializeCriticalSection(&MSVCRT_console_cs);
InitializeCriticalSection(&MSVCRT_locale_cs);
}
static inline void MSVCRT_free_critical_sections(void)
{
DeleteCriticalSection(&MSVCRT_locale_cs);
DeleteCriticalSection(&MSVCRT_console_cs);
DeleteCriticalSection(&MSVCRT_exit_cs);
DeleteCriticalSection(&MSVCRT_file_cs);
DeleteCriticalSection(&MSVCRT_heap_cs);
}
const char *MSVCRT_get_reason(DWORD reason)
{
switch (reason)
{
case DLL_PROCESS_ATTACH: return "DLL_PROCESS_ATTACH";
case DLL_PROCESS_DETACH: return "DLL_PROCESS_DETACH";
case DLL_THREAD_ATTACH: return "DLL_THREAD_ATTACH";
case DLL_THREAD_DETACH: return "DLL_THREAD_DETACH";
}
return "UNKNOWN";
}
/*********************************************************************
* Fixup functions
*
* Anything not really understood but needed to make the DLL work
*/
void MSVCRT_I10_OUTPUT(void)
{
/* FIXME: This is probably data, not a function */
}
void MSVCRT___unDName(void)
{
/* Called by all VC compiled progs on startup. No idea what it does */
}
void MSVCRT___unDNameEx(void)
{
/* As above */
}
/*
* msvcrt.dll math functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
#include "ms_errno.h"
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
DEFAULT_DEBUG_CHANNEL(msvcrt);
#ifndef HAVE_FINITE
#ifndef finite /* Could be a macro */
#ifdef isfinite
#define finite(x) isfinite(x)
#else
#define finite(x) (!isnan(x)) /* At least catch some cases */
#endif
#endif
#endif
#ifndef signbit
#define signbit(x) 0
#endif
/* fpclass constants */
#define _FPCLASS_SNAN 1
#define _FPCLASS_QNAN 2
#define _FPCLASS_NINF 4
#define _FPCLASS_NN 8
#define _FPCLASS_ND 16
#define _FPCLASS_NZ 32
#define _FPCLASS_PZ 64
#define _FPCLASS_PD 128
#define _FPCLASS_PN 256
#define _FPCLASS_PINF 512
/* _statusfp bit flags */
#define _SW_INEXACT 0x1
#define _SW_UNDERFLOW 0x2
#define _SW_OVERFLOW 0x4
#define _SW_ZERODIVIDE 0x8
#define _SW_INVALID 0x10
#define _SW_DENORMAL 0x80000
/* _controlfp masks and bitflags - x86 only so far*/
#ifdef __i386__
#define _MCW_EM 0x8001f
#define _EM_INEXACT 0x1
#define _EM_UNDERFLOW 0x2
#define _EM_OVERFLOW 0x4
#define _EM_ZERODIVIDE 0x8
#define _EM_INVALID 0x10
#define _MCW_RC 0x300
#define _RC_NEAR 0x0
#define _RC_DOWN 0x100
#define _RC_UP 0x200
#define _RC_CHOP 0x300
#define _MCW_PC 0x30000
#define _PC_64 0x0
#define _PC_53 0x10000
#define _PC_24 0x20000
#define _MCW_IC 0x40000
#define _IC_AFFINE 0x40000
#define _IC_PROJECTIVE 0x0
#define _EM_DENORMAL 0x80000
#endif
typedef struct __MSVCRT_complex
{
double real;
double imaginary;
} MSVCRT_complex;
typedef struct __MSVCRT_exception
{
int type;
char *name;
double arg1;
double arg2;
double retval;
} MSVCRT_exception;
typedef int (__cdecl *MSVCRT_matherr_func)(MSVCRT_exception *);
static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL;
#if defined(__GNUC__) && defined(__i386__)
#define FPU_DOUBLE(var) double var; \
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
#define FPU_DOUBLES(var1,var2) double var1,var2; \
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
/*********************************************************************
* _CIacos (MSVCRT.@)
*/
double __cdecl MSVCRT__CIacos(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return acos(x);
}
/*********************************************************************
* _CIasin (MSVCRT.@)
*/
double __cdecl MSVCRT__CIasin(void)
{
FPU_DOUBLE(x);
if (x < -1.0 || x > 1.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return asin(x);
}
/*********************************************************************
* _CIatan (MSVCRT.@)
*/
double __cdecl MSVCRT__CIatan(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return atan(x);
}
/*********************************************************************
* _CIatan2 (MSVCRT.@)
*/
double __cdecl MSVCRT__CIatan2(void)
{
FPU_DOUBLES(x,y);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return atan2(x,y);
}
/*********************************************************************
* _CIcos (MSVCRT.@)
*/
double __cdecl MSVCRT__CIcos(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return cos(x);
}
/*********************************************************************
* _CIcosh (MSVCRT.@)
*/
double __cdecl MSVCRT__CIcosh(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return cosh(x);
}
/*********************************************************************
* _CIexp (MSVCRT.@)
*/
double __cdecl MSVCRT__CIexp(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return exp(x);
}
/*********************************************************************
* _CIfmod (MSVCRT.@)
*/
double __cdecl MSVCRT__CIfmod(void)
{
FPU_DOUBLES(x,y);
if (!finite(x) || !finite(y)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return fmod(x,y);
}
/*********************************************************************
* _CIlog (MSVCRT.@)
*/
double __cdecl MSVCRT__CIlog(void)
{
FPU_DOUBLE(x);
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return log(x);
}
/*********************************************************************
* _CIlog10 (MSVCRT.@)
*/
double __cdecl MSVCRT__CIlog10(void)
{
FPU_DOUBLE(x);
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE);
return log10(x);
}
/*********************************************************************
* _CIpow (MSVCRT.@)
*/
double __cdecl MSVCRT__CIpow(void)
{
double z;
FPU_DOUBLES(x,y);
/* FIXME: If x < 0 and y is not integral, set EDOM */
z = pow(x,y);
if (!finite(z)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return z;
}
/*********************************************************************
* _CIsin (MSVCRT.@)
*/
double __cdecl MSVCRT__CIsin(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return sin(x);
}
/*********************************************************************
* _CIsinh (MSVCRT.@)
*/
double __cdecl MSVCRT__CIsinh(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return sinh(x);
}
/*********************************************************************
* _CIsqrt (MSVCRT.@)
*/
double __cdecl MSVCRT__CIsqrt(void)
{
FPU_DOUBLE(x);
if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return sqrt(x);
}
/*********************************************************************
* _CItan (MSVCRT.@)
*/
double __cdecl MSVCRT__CItan(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return tan(x);
}
/*********************************************************************
* _CItanh (MSVCRT.@)
*/
double __cdecl MSVCRT__CItanh(void)
{
FPU_DOUBLE(x);
if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return tanh(x);
}
#else /* defined(__GNUC__) && defined(__i386__) */
/* The above cannot be called on non x86 platforms, stub them for linking */
#define IX86_ONLY(func) double __cdecl MSVCRT_##func(void) { return 0.0; }
IX86_ONLY(_CIacos)
IX86_ONLY(_CIasin)
IX86_ONLY(_CIatan)
IX86_ONLY(_CIatan2)
IX86_ONLY(_CIcos)
IX86_ONLY(_CIcosh)
IX86_ONLY(_CIexp)
IX86_ONLY(_CIfmod)
IX86_ONLY(_CIlog)
IX86_ONLY(_CIlog10)
IX86_ONLY(_CIpow)
IX86_ONLY(_CIsin)
IX86_ONLY(_CIsinh)
IX86_ONLY(_CIsqrt)
IX86_ONLY(_CItan)
IX86_ONLY(_CItanh)
#endif /* defined(__GNUC__) && defined(__i386__) */
/*********************************************************************
* _fpclass (MSVCRT.@)
*/
int __cdecl MSVCRT__fpclass(double num)
{
#if defined(HAVE_FPCLASS) || defined(fpclass)
switch (fpclass( num ))
{
case FP_SNAN: return _FPCLASS_SNAN;
case FP_QNAN: return _FPCLASS_QNAN;
case FP_NINF: return _FPCLASS_NINF;
case FP_PINF: return _FPCLASS_PINF;
case FP_NDENORM: return _FPCLASS_ND;
case FP_PDENORM: return _FPCLASS_PD;
case FP_NZERO: return _FPCLASS_NZ;
case FP_PZERO: return _FPCLASS_PZ;
case FP_NNORM: return _FPCLASS_NN;
}
return _FPCLASS_PN;
#elif defined (fpclassify)
switch (fpclassify( num ))
{
case FP_NAN: return _FPCLASS_QNAN;
case FP_INFINITE: return signbit(num) ? _FPCLASS_NINF : _FPCLASS_PINF;
case FP_SUBNORMAL: return signbit(num) ?_FPCLASS_ND : _FPCLASS_PD;
case FP_ZERO: return signbit(num) ? _FPCLASS_NZ : _FPCLASS_PZ;
}
return signbit(num) ? _FPCLASS_NN : _FPCLASS_PN;
#else
if (!finite(num))
return _FPCLASS_QNAN;
return num == 0.0 ? _FPCLASS_PZ : (d < 0 ? _FPCLASS_NN : _FPCLASS_PN);
#endif
}
/*********************************************************************
* _rotl (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__rotl(unsigned int num, int shift)
{
shift &= 31;
return (num << shift) | (num >> (32-shift));
}
/*********************************************************************
* _logb (MSVCRT.@)
*/
double __cdecl MSVCRT__logb(double num)
{
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return logb(num);
}
/*********************************************************************
* _lrotl (MSVCRT.@)
*/
unsigned long __cdecl MSVCRT__lrotl(unsigned long num, int shift)
{
shift &= 0x1f;
return (num << shift) | (num >> (32-shift));
}
/*********************************************************************
* _lrotr (MSVCRT.@)
*/
unsigned long __cdecl MSVCRT__lrotr(unsigned long num, int shift)
{
shift &= 0x1f;
return (num >> shift) | (num << (32-shift));
}
/*********************************************************************
* _rotr (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__rotr(unsigned int num, int shift)
{
shift &= 0x1f;
return (num >> shift) | (num << (32-shift));
}
/*********************************************************************
* _scalb (MSVCRT.@)
*/
double __cdecl MSVCRT__scalb(double num, long power)
{
/* Note - Can't forward directly as libc expects y as double */
double dblpower = (double)power;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
return scalb(num, dblpower);
}
/*********************************************************************
* _matherr (MSVCRT.@)
*/
int __cdecl MSVCRT__matherr(MSVCRT_exception *e)
{
if (e)
TRACE("(%p = %d, %s, %g %g %g)\n",e, e->type, e->name, e->arg1, e->arg2,
e->retval);
else
TRACE("(null)\n");
if (MSVCRT_default_matherr_func)
return MSVCRT_default_matherr_func(e);
ERR(":Unhandled math error!\n");
return 0;
}
/*********************************************************************
* __setusermatherr (MSVCRT.@)
*/
void __cdecl MSVCRT___setusermatherr(MSVCRT_matherr_func func)
{
MSVCRT_default_matherr_func = func;
TRACE(":new matherr handler %p\n", func);
}
/**********************************************************************
* _statusfp (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__statusfp(void)
{
unsigned int retVal = 0;
#if defined(__GNUC__) && defined(__i386__)
unsigned int fpword;
__asm__ __volatile__( "fstsw %0" : "=m" (fpword) : );
if (fpword & 0x1) retVal |= _SW_INVALID;
if (fpword & 0x2) retVal |= _SW_DENORMAL;
if (fpword & 0x4) retVal |= _SW_ZERODIVIDE;
if (fpword & 0x8) retVal |= _SW_OVERFLOW;
if (fpword & 0x10) retVal |= _SW_UNDERFLOW;
if (fpword & 0x20) retVal |= _SW_INEXACT;
#else
FIXME(":Not implemented!\n");
#endif
return retVal;
}
/*********************************************************************
* _clearfp (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__clearfp(void)
{
UINT retVal = MSVCRT__statusfp();
#if defined(__GNUC__) && defined(__i386__)
__asm__ __volatile__( "fnclex" );
#else
FIXME(":Not Implemented\n");
#endif
return retVal;
}
/*********************************************************************
* ldexp (MSVCRT.@)
*/
double __cdecl MSVCRT_ldexp(double num, long exp)
{
double z = ldexp(num,exp);
if (!finite(z))
SET_THREAD_VAR(errno,MSVCRT_ERANGE);
else if (z == 0 && signbit(z))
z = 0.0; /* Convert -0 -> +0 */
return z;
}
/*********************************************************************
* _cabs (MSVCRT.@)
*/
double __cdecl MSVCRT__cabs(MSVCRT_complex num)
{
return sqrt(num.real * num.imaginary + num.real * num.imaginary);
}
/*********************************************************************
* _chgsign (MSVCRT.@)
*/
double __cdecl MSVCRT__chgsign(double num)
{
/* FIXME: +-infinity,Nan not tested */
return -num;
}
/*********************************************************************
* _control87 (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__control87(unsigned int newval, unsigned int mask)
{
#if defined(__GNUC__) && defined(__i386__)
UINT fpword, flags = 0;
/* Get fp control word */
__asm__ __volatile__( "fstsw %0" : "=m" (fpword) : );
/* Convert into mask constants */
if (fpword & 0x1) flags |= _EM_INVALID;
if (fpword & 0x2) flags |= _EM_DENORMAL;
if (fpword & 0x4) flags |= _EM_ZERODIVIDE;
if (fpword & 0x8) flags |= _EM_OVERFLOW;
if (fpword & 0x10) flags |= _EM_UNDERFLOW;
if (fpword & 0x20) flags |= _EM_INEXACT;
switch(fpword & 0xC00) {
case 0xC00: flags |= _RC_UP|_RC_DOWN; break;
case 0x800: flags |= _RC_UP; break;
case 0x400: flags |= _RC_DOWN; break;
}
switch(fpword & 0x300) {
case 0x0: flags |= _PC_24; break;
case 0x200: flags |= _PC_53; break;
case 0x300: flags |= _PC_64; break;
}
if (fpword & 0x1000) flags |= _IC_AFFINE;
/* Mask with parameters */
flags = (flags & ~mask) | (newval & mask);
/* Convert (masked) value back to fp word */
fpword = 0;
if (flags & _EM_INVALID) fpword |= 0x1;
if (flags & _EM_DENORMAL) fpword |= 0x2;
if (flags & _EM_ZERODIVIDE) fpword |= 0x4;
if (flags & _EM_OVERFLOW) fpword |= 0x8;
if (flags & _EM_UNDERFLOW) fpword |= 0x10;
if (flags & _EM_INEXACT) fpword |= 0x20;
switch(flags & (_RC_UP | _RC_DOWN)) {
case _RC_UP|_RC_DOWN: fpword |= 0xC00; break;
case _RC_UP: fpword |= 0x800; break;
case _RC_DOWN: fpword |= 0x400; break;
}
switch (flags & (_PC_24 | _PC_53)) {
case _PC_64: fpword |= 0x300; break;
case _PC_53: fpword |= 0x200; break;
case _PC_24: fpword |= 0x0; break;
}
if (!(flags & _IC_AFFINE)) fpword |= 0x1000;
/* Put fp control word */
__asm__ __volatile__( "fldcw %0" : : "m" (fpword) );
return fpword;
#else
return MSVCRT__controlfp( newVal, mask );
#endif
}
/*********************************************************************
* _controlfp (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__controlfp(unsigned int newval, unsigned int mask)
{
#if defined(__GNUC__) && defined(__i386__)
return MSVCRT__control87( newval, mask );
#else
FIXME(":Not Implemented!\n");
return 0;
#endif
}
/*********************************************************************
* _copysign (MSVCRT.@)
*/
double __cdecl MSVCRT__copysign(double num, double sign)
{
/* FIXME: Behaviour for Nan/Inf? */
if (sign < 0.0)
return num < 0.0 ? num : -num;
return num < 0.0 ? -num : num;
}
/*********************************************************************
* _finite (MSVCRT.@)
*/
int __cdecl MSVCRT__finite(double num)
{
return (finite(num)?1:0); /* See comment for _isnan() */
}
/*********************************************************************
* _fpreset (MSVCRT.@)
*/
void __cdecl MSVCRT__fpreset(void)
{
#if defined(__GNUC__) && defined(__i386__)
__asm__ __volatile__( "fninit" );
#else
FIXME(":Not Implemented!\n");
#endif
}
/*********************************************************************
* _isnan (MSVCRT.@)
*/
INT __cdecl MSVCRT__isnan(double num)
{
/* Some implementations return -1 for true(glibc), msvcrt/crtdll return 1.
* Do the same, as the result may be used in calculations
*/
return isnan(num) ? 1 : 0;
}
/*********************************************************************
* _y0 (MSVCRT.@)
*/
double __cdecl MSVCRT__y0(double num)
{
double retval;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = y0(num);
if (MSVCRT__fpclass(retval) == _FPCLASS_NINF)
{
SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = sqrt(-1);
}
return retval;
}
/*********************************************************************
* _y1 (MSVCRT.@)
*/
double __cdecl MSVCRT__y1(double num)
{
double retval;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = y1(num);
if (MSVCRT__fpclass(retval) == _FPCLASS_NINF)
{
SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = sqrt(-1);
}
return retval;
}
/*********************************************************************
* _yn (MSVCRT.@)
*/
double __cdecl MSVCRT__yn(int order, double num)
{
double retval;
if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = yn(order,num);
if (MSVCRT__fpclass(retval) == _FPCLASS_NINF)
{
SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = sqrt(-1);
}
return retval;
}
/*********************************************************************
* _nextafter (MSVCRT.@)
*/
double __cdecl MSVCRT__nextafter(double num, double next)
{
double retval;
if (!finite(num) || !finite(next)) SET_THREAD_VAR(errno,MSVCRT_EDOM);
retval = nextafter(num,next);
return retval;
}
#include <stdlib.h> /* div_t, ldiv_t */
/*********************************************************************
* div (MSVCRT.@)
* VERSION
* [i386] Windows binary compatible - returns the struct in eax/edx.
*/
#ifdef __i386__
LONGLONG __cdecl MSVCRT_div(int num, int denom)
{
LONGLONG retval;
div_t dt = div(num,denom);
retval = ((LONGLONG)dt.rem << 32) | dt.quot;
return retval;
}
#else
/*********************************************************************
* div (MSVCRT.@)
* VERSION
* [!i386] Non-x86 can't run win32 apps so we don't need binary compatibility
*/
div_t __cdecl MSVCRT_div(int num, int denom)
{
return div(num,denom);
}
#endif /* ifdef __i386__ */
/*********************************************************************
* ldiv (MSVCRT.@)
* VERSION
* [i386] Windows binary compatible - returns the struct in eax/edx.
*/
#ifdef __i386__
ULONGLONG __cdecl MSVCRT_ldiv(long num, long denom)
{
ULONGLONG retval;
ldiv_t ldt = ldiv(num,denom);
retval = ((ULONGLONG)ldt.rem << 32) | (ULONG)ldt.quot;
return retval;
}
#else
/*********************************************************************
* ldiv (MSVCRT.@)
* VERSION
* [!i386] Non-x86 can't run win32 apps so we don't need binary compatibility
*/
ldiv_t __cdecl MSVCRT_ldiv(long num, long denom)
{
return ldiv(num,denom);
}
#endif /* ifdef __i386__ */
/* I _think_ these functions are intended to work around the pentium fdiv bug */
#define DUMMY_FUNC(x) void __cdecl MSVCRT_##x(void) { TRACE("stub"); }
DUMMY_FUNC(_adj_fdiv_m16i)
DUMMY_FUNC(_adj_fdiv_m32)
DUMMY_FUNC(_adj_fdiv_m32i)
DUMMY_FUNC(_adj_fdiv_m64)
DUMMY_FUNC(_adj_fdiv_r)
DUMMY_FUNC(_adj_fdivr_m16i)
DUMMY_FUNC(_adj_fdivr_m32)
DUMMY_FUNC(_adj_fdivr_m32i)
DUMMY_FUNC(_adj_fdivr_m64)
DUMMY_FUNC(_adj_fpatan)
DUMMY_FUNC(_adj_fprem)
DUMMY_FUNC(_adj_fprem1)
DUMMY_FUNC(_adj_fptan)
DUMMY_FUNC(_adjust_fdiv)
DUMMY_FUNC(_safe_fdiv);
DUMMY_FUNC(_safe_fdivr);
DUMMY_FUNC(_safe_fprem);
DUMMY_FUNC(_safe_fprem1);
/*
* msvcrt.dll mbcs functions
*
* Copyright 1999 Alexandre Julliard
* Copyright 2000 Jon Griffths
*
* FIXME
* Not currently binary compatable with win32. MSVCRT_mbctype must be
* populated correctly and the ismb* functions should reference it.
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
unsigned char MSVCRT_mbctype[257];
int MSVCRT___mb_cur_max = 1;
int __cdecl MSVCRT_isleadbyte(int);
char *__cdecl MSVCRT__strset(char *, int);
char *__cdecl MSVCRT__strnset(char *, int, unsigned int);
extern unsigned int MSVCRT_current_lc_all_cp;
/*********************************************************************
* __p__mbctype (MSVCRT.@)
*/
unsigned char *__cdecl MSVCRT___p__mbctype(void)
{
return MSVCRT_mbctype;
}
/*********************************************************************
* __p___mb_cur_max(MSVCRT.@)
*/
int *__cdecl MSVCRT___p___mb_cur_max(void)
{
return &MSVCRT___mb_cur_max;
}
/*********************************************************************
* _mbsnextc(MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__mbsnextc(const char *str)
{
if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*str))
return *str << 8 | str[1];
return *str; /* ASCII CP or SB char */
}
/*********************************************************************
* _mbscmp(MSVCRT.@)
*/
int __cdecl MSVCRT__mbscmp(const char *str, const char *cmp)
{
if(MSVCRT___mb_cur_max > 1)
{
unsigned int strc, cmpc;
do {
if(!*str)
return *cmp ? -1 : 0;
if(!*cmp)
return 1;
strc = MSVCRT__mbsnextc(str);
cmpc = MSVCRT__mbsnextc(cmp);
if(strc != cmpc)
return strc < cmpc ? -1 : 1;
str +=(strc > 255) ? 2 : 1;
cmp +=(strc > 255) ? 2 : 1; /* equal, use same increment */
} while(1);
}
return strcmp(str, cmp); /* ASCII CP */
}
/*********************************************************************
* _mbsicmp(MSVCRT.@)
*/
int __cdecl MSVCRT__mbsicmp(const char *str, const char *cmp)
{
/* FIXME: No tolower() for mb strings yet */
if(MSVCRT___mb_cur_max > 1)
return MSVCRT__mbscmp(str, cmp);
return strcasecmp(str, cmp); /* ASCII CP */
}
/*********************************************************************
* _mbsncmp (MSVCRT.@)
*/
int __cdecl MSVCRT__mbsncmp(const char *str, const char *cmp, unsigned int len)
{
if(!len)
return 0;
if(MSVCRT___mb_cur_max > 1)
{
unsigned int strc, cmpc;
while(len--)
{
if(!*str)
return *cmp ? -1 : 0;
if(!*cmp)
return 1;
strc = MSVCRT__mbsnextc(str);
cmpc = MSVCRT__mbsnextc(cmp);
if(strc != cmpc)
return strc < cmpc ? -1 : 1;
str +=(strc > 255) ? 2 : 1;
cmp +=(strc > 255) ? 2 : 1; /* Equal, use same increment */
}
return 0; /* Matched len chars */
}
return strncmp(str, cmp, len); /* ASCII CP */
}
/*********************************************************************
* _mbsnicmp(MSVCRT.@)
*
* Compare two multibyte strings case insensitively to 'len' characters.
*/
int __cdecl MSVCRT__mbsnicmp(const char *str, const char *cmp, unsigned int len)
{
/* FIXME: No tolower() for mb strings yet */
if(MSVCRT___mb_cur_max > 1)
return MSVCRT__mbsncmp(str, cmp, len);
return strncasecmp(str, cmp, len); /* ASCII CP */
}
/*********************************************************************
* _mbsinc(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsinc(const char *str)
{
if(MSVCRT___mb_cur_max > 1 &&
MSVCRT_isleadbyte(*str))
return(char *)str + 2; /* MB char */
return(char *)str + 1; /* ASCII CP or SB char */
}
/*********************************************************************
* _mbsninc(MSVCRT.@)
*/
char *MSVCRT__mbsninc(const char *str, unsigned int num)
{
if(!str || num < 1)
return NULL;
if(MSVCRT___mb_cur_max > 1)
{
while(num--)
str = MSVCRT__mbsinc(str);
return(char *)str;
}
return(char *)str + num; /* ASCII CP */
}
/*********************************************************************
* _mbslen(MSVCRT.206)
*/
int __cdecl MSVCRT__mbslen(const char *str)
{
if(MSVCRT___mb_cur_max > 1)
{
int len = 0;
while(*str)
{
str += MSVCRT_isleadbyte(*str) ? 2 : 1;
len++;
}
return len;
}
return strlen(str); /* ASCII CP */
}
/*********************************************************************
* _mbsrchr(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsrchr(const char *s,unsigned int x)
{
/* FIXME: handle multibyte strings */
return strrchr(s,x);
}
/*********************************************************************
* mbtowc(MSVCRT.@)
*/
int __cdecl MSVCRT_mbtowc(WCHAR *dst, const char *str, unsigned int n)
{
if(n <= 0 || !str)
return 0;
if(!MultiByteToWideChar(CP_ACP, 0, str, n, dst, 1))
return 0;
/* return the number of bytes from src that have been used */
if(!*str)
return 0;
if(n >= 2 && MSVCRT_isleadbyte(*str) && str[1])
return 2;
return 1;
}
/*********************************************************************
* _mbccpy(MSVCRT.@)
*/
void __cdecl MSVCRT__mbccpy(char *dest, char *src)
{
*dest++ = *src;
if(MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(*src))
*dest = *++src; /* MB char */
}
/*********************************************************************
* _mbbtombc(MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__mbbtombc(unsigned int c)
{
if(MSVCRT___mb_cur_max > 1 &&
((c >= 0x20 && c <=0x7e) ||(c >= 0xa1 && c <= 0xdf)))
{
/* FIXME: I can't get this function to return anything
* different to what I pass it...
*/
}
return c; /* ASCII CP or no MB char */
}
/*********************************************************************
* _mbclen(MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__mbclen(const char *str)
{
return MSVCRT_isleadbyte(*str) ? 2 : 1;
}
/*********************************************************************
* _ismbbkana(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbbkana(unsigned int c)
{
/* FIXME: use lc_ctype when supported, not lc_all */
if(MSVCRT_current_lc_all_cp == 932)
{
/* Japanese/Katakana, CP 932 */
return(c >= 0xa1 && c <= 0xdf);
}
return 0;
}
/*********************************************************************
* _ismbchira(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbchira(unsigned int c)
{
/* FIXME: use lc_ctype when supported, not lc_all */
if(MSVCRT_current_lc_all_cp == 932)
{
/* Japanese/Hiragana, CP 932 */
return(c >= 0x829f && c <= 0x82f1);
}
return 0;
}
/*********************************************************************
* _ismbckata(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbckata(unsigned int c)
{
/* FIXME: use lc_ctype when supported, not lc_all */
if(MSVCRT_current_lc_all_cp == 932)
{
if(c < 256)
return MSVCRT__ismbbkana(c);
/* Japanese/Katakana, CP 932 */
return(c >= 0x8340 && c <= 0x8396 && c != 0x837f);
}
return 0;
}
/*********************************************************************
* _ismbblead(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbblead(unsigned int c)
{
/* FIXME: should reference MSVCRT_mbctype */
return MSVCRT___mb_cur_max > 1 && MSVCRT_isleadbyte(c);
}
/*********************************************************************
* _ismbbtrail(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbbtrail(unsigned int c)
{
/* FIXME: should reference MSVCRT_mbctype */
return !MSVCRT__ismbblead(c);
}
/*********************************************************************
* _ismbslead(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbslead(const char *start, const char *str)
{
/* Lead bytes can also be trail bytes if caller messed up
* iterating through the string...
*/
if(MSVCRT___mb_cur_max > 1)
{
while(start < str)
start += MSVCRT_isleadbyte(*str) ? 2 : 1;
if(start == str)
return MSVCRT_isleadbyte(*str);
}
return 0; /* Must have been a trail, we skipped it */
}
/*********************************************************************
* _ismbstrail(MSVCRT.@)
*/
int __cdecl MSVCRT__ismbstrail(const char *start, const char *str)
{
/* Must not be a lead, and must be preceeded by one */
return !MSVCRT__ismbslead(start, str) && MSVCRT_isleadbyte(str[-1]);
}
/*********************************************************************
* _mbsdec(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsdec(const char *start, const char *cur)
{
if(MSVCRT___mb_cur_max > 1)
return(char *)(MSVCRT__ismbstrail(start,cur-1) ? cur - 2 : cur -1);
return(char *)cur - 1; /* ASCII CP or SB char */
}
/*********************************************************************
* _mbsset(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsset(char *str, unsigned int c)
{
char *ret = str;
if(MSVCRT___mb_cur_max == 1 || c < 256)
return MSVCRT__strset(str, c); /* ASCII CP or SB char */
c &= 0xffff; /* Strip high bits */
while(str[0] && str[1])
{
*str++ = c >> 8;
*str++ = c & 0xff;
}
if(str[0])
str[0] = '\0'; /* FIXME: OK to shorten? */
return ret;
}
/*********************************************************************
* _mbsnset(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsnset(char *str, unsigned int c, unsigned int len)
{
char *ret = str;
if(!len)
return ret;
if(MSVCRT___mb_cur_max == 1 || c < 256)
return MSVCRT__strnset(str, c, len); /* ASCII CP or SB char */
c &= 0xffff; /* Strip high bits */
while(str[0] && str[1] && len--)
{
*str++ = c >> 8;
*str++ = c & 0xff;
}
if(len && str[0])
str[0] = '\0'; /* FIXME: OK to shorten? */
return ret;
}
/*********************************************************************
* _mbstrlen(MSVCRT.@)
*/
int __cdecl MSVCRT__mbstrlen(const char *str)
{
if(MSVCRT___mb_cur_max > 1)
{
int len = 0;
while(*str)
{
str += MSVCRT_isleadbyte(*str) ? 2 : 1;
len++;
}
return len;
}
return strlen(str); /* ASCII CP */
}
/*********************************************************************
* _mbsncpy(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsncpy(char *dst, const char *src, unsigned int len)
{
if(!len)
return dst;
if(MSVCRT___mb_cur_max > 1)
{
char *ret = dst;
while(src[0] && src[1] && len--)
{
*dst++ = *src++;
*dst++ = *src++;
}
if(len--)
{
*dst++ = *src++; /* Last char or '\0' */
while(len--)
*dst++ = '\0';
}
return ret;
}
return strncpy(dst, src, len); /* ASCII CP */
}
/*********************************************************************
* _mbschr(MSVCRT.@)
*
* Find a multibyte character in a multibyte string.
*/
char *__cdecl MSVCRT__mbschr(const char *str, unsigned int c)
{
if(MSVCRT___mb_cur_max > 1)
{
unsigned int next;
while((next = MSVCRT__mbsnextc(str)))
{
if(next == c)
return(char *)str;
str += next > 255 ? 2 : 1;
}
return c ? NULL :(char *)str;
}
return strchr(str, c); /* ASCII CP */
}
/*********************************************************************
* _mbsnccnt(MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__mbsnccnt(const char *str, unsigned int len)
{
int ret = 0;
if(MSVCRT___mb_cur_max > 1)
{
while(*str && len-- > 0)
{
if(MSVCRT_isleadbyte(*str))
{
str++;
len--;
}
ret++;
str++;
}
return ret;
}
return min(strlen(str), len); /* ASCII CP */
}
/*********************************************************************
* _mbsncat(MSVCRT.@)
*/
char *__cdecl MSVCRT__mbsncat(char *dst, const char *src, unsigned int len)
{
if(MSVCRT___mb_cur_max > 1)
{
char *res = dst;
dst += MSVCRT__mbslen(dst);
while(*src && len--)
{
*dst = *src;
if(MSVCRT_isleadbyte(*src))
*++dst = *++src;
dst++;
src++;
}
*dst++ = '\0';
return res;
}
return strncat(dst, src, len); /* ASCII CP */
}
/*
* msvcrt.dll misc functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef INT (__cdecl *MSVCRT_comp_func)(LPCVOID, LPCVOID );
/*********************************************************************
* _beep (MSVCRT.@)
*/
void __cdecl MSVCRT__beep( unsigned int freq, unsigned int duration)
{
TRACE(":Freq %d, Duration %d\n",freq,duration);
Beep(freq, duration);
}
extern int rand(void);
/*********************************************************************
* rand (MSVCRT.@)
*/
INT __cdecl MSVCRT_rand()
{
return (rand() & 0x7fff);
}
/*********************************************************************
* _sleep (MSVCRT.@)
*/
VOID __cdecl MSVCRT__sleep(ULONG timeout)
{
TRACE("MSVCRT__sleep for %ld milliseconds\n",timeout);
Sleep((timeout)?timeout:1);
}
/*********************************************************************
* _lfind (MSVCRT.@)
*/
void* __cdecl MSVCRT__lfind(const void * match, const void * start,
unsigned int * array_size,unsigned int elem_size, MSVCRT_comp_func cf)
{
unsigned int size = *array_size;
if (size)
do
{
if (cf(match, start) == 0)
return (void *)start; /* found */
start += elem_size;
} while (--size);
return NULL;
}
/*********************************************************************
* _lsearch (MSVCRT.@)
*/
void * __cdecl MSVCRT__lsearch(const void * match,void * start,
unsigned int * array_size,unsigned int elem_size, MSVCRT_comp_func cf)
{
unsigned int size = *array_size;
if (size)
do
{
if (cf(match, start) == 0)
return start; /* found */
start += elem_size;
} while (--size);
/* not found, add to end */
memcpy(start, match, elem_size);
array_size[0]++;
return start;
}
/*********************************************************************
* _chkesp (MSVCRT.@)
*/
void __cdecl MSVCRT__chkesp(void)
{
}
#ifndef __WINE_MSVCRT_ERRNO_H
#define __WINE_MSVCRT_ERRNO_H
#define MSVCRT_EPERM 1
#define MSVCRT_ENOENT 2
#define MSVCRT_ESRCH 3
#define MSVCRT_EINTR 4
#define MSVCRT_EIO 5
#define MSVCRT_ENXIO 6
#define MSVCRT_E2BIG 7
#define MSVCRT_ENOEXEC 8
#define MSVCRT_EBADF 9
#define MSVCRT_ECHILD 10
#define MSVCRT_EAGAIN 11
#define MSVCRT_ENOMEM 12
#define MSVCRT_EACCES 13
#define MSVCRT_EFAULT 14
#define MSVCRT_EBUSY 16
#define MSVCRT_EEXIST 17
#define MSVCRT_EXDEV 18
#define MSVCRT_ENODEV 19
#define MSVCRT_ENOTDIR 20
#define MSVCRT_EISDIR 21
#define MSVCRT_EINVAL 22
#define MSVCRT_ENFILE 23
#define MSVCRT_EMFILE 24
#define MSVCRT_ENOTTY 25
#define MSVCRT_EFBIG 27
#define MSVCRT_ENOSPC 28
#define MSVCRT_ESPIPE 29
#define MSVCRT_EROFS 30
#define MSVCRT_EMLINK 31
#define MSVCRT_EPIPE 32
#define MSVCRT_EDOM 33
#define MSVCRT_ERANGE 34
#define MSVCRT_EDEADLK 36
#define MSVCRT_ENAMETOOLONG 38
#define MSVCRT_ENOLCK 39
#define MSVCRT_ENOSYS 40
#define MSVCRT_ENOTEMPTY 41
#endif /* __WINE_MSVCRT_ERRNO_H */
#ifndef __WINE_MSVCRT_H
#define __WINE_MSVCRT_H
#include "config.h"
#include "windef.h"
#include "debugtools.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include <stdarg.h>
/* Files */
#define MSVCRT_EOF -1
#define MSVCRT_WEOF (WCHAR)(0xFFFF)
/* TLS data */
extern DWORD MSVCRT_tls_index;
typedef struct __MSVCRT_thread_data
{
int errno;
int doserrno;
} MSVCRT_thread_data;
#define GET_THREAD_DATA(x) \
x = TlsGetValue(MSVCRT_tls_index)
#define GET_THREAD_VAR(x) \
((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x
#define GET_THREAD_VAR_PTR(x) \
(&((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x)
#define SET_THREAD_VAR(x,y) \
((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x = y
void MSVCRT__set_errno(int);
int __cdecl MSVCRT__fcloseall(void);
void *__cdecl MSVCRT_malloc(unsigned int);
void *__cdecl MSVCRT_calloc(unsigned int, unsigned int);
void __cdecl MSVCRT_free(void *);
int __cdecl MSVCRT__cputs(const char *);
int __cdecl MSVCRT__cprintf( const char *, ... );
char *__cdecl MSVCRT__strdup(const char *);
#endif /* __WINE_MSVCRT_H */
# msvcrt.dll - MS VC++ Run Time Library
name msvcrt
type win32
init MSVCRT_Init
import kernel32.dll
import ntdll.dll
debug_channels (msvcrt)
@ cdecl $I10_OUTPUT() MSVCRT_I10_OUTPUT
@ cdecl ??0__non_rtti_object@@QAE@ABV0@@Z(ptr ptr) MSVCRT___non_rtti_object_copy_ctor
@ cdecl ??0__non_rtti_object@@QAE@PBD@Z(ptr ptr) MSVCRT___non_rtti_object_ctor
@ cdecl ??0bad_cast@@QAE@ABQBD@Z(ptr ptr) MSVCRT_bad_cast_ctor
@ cdecl ??0bad_cast@@QAE@ABV0@@Z(ptr ptr) MSVCRT_bad_cast_copy_ctor
@ cdecl ??0bad_typeid@@QAE@ABV0@@Z(ptr ptr) MSVCRT_bad_typeid_copy_ctor
@ cdecl ??0bad_typeid@@QAE@PBD@Z(ptr ptr) MSVCRT_bad_typeid_ctor
@ cdecl ??0exception@@QAE@ABQBD@Z(ptr ptr) MSVCRT_exception_ctor
@ cdecl ??0exception@@QAE@ABV0@@Z(ptr ptr) MSVCRT_exception_copy_ctor
@ cdecl ??0exception@@QAE@XZ(ptr) MSVCRT_exception_default_ctor
@ cdecl ??1__non_rtti_object@@UAE@XZ(ptr) MSVCRT___non_rtti_object_dtor
@ cdecl ??1bad_cast@@UAE@XZ(ptr) MSVCRT_bad_cast_dtor
@ cdecl ??1bad_typeid@@UAE@XZ(ptr) MSVCRT_bad_typeid_dtor
@ cdecl ??1exception@@UAE@XZ(ptr) MSVCRT_exception_dtor
@ cdecl ??1type_info@@UAE@XZ(ptr) MSVCRT_type_info_dtor
@ cdecl ??2@YAPAXI@Z(long) MSVCRT_operator_new
@ cdecl ??3@YAXPAX@Z(ptr) MSVCRT_operator_delete
@ cdecl ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr ptr) MSVCRT___non_rtti_object_opequals
@ cdecl ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr ptr) MSVCRT_bad_cast_opequals
@ cdecl ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr ptr)MSVCRT_bad_typeid_opequals
@ cdecl ??4exception@@QAEAAV0@ABV0@@Z(ptr ptr) MSVCRT_exception_opequals
@ stdcall ??8type_info@@QBEHABV0@@Z(ptr ptr) MSVCRT_type_info_opequals_equals
@ stdcall ??9type_info@@QBEHABV0@@Z(ptr ptr) MSVCRT_type_info_opnot_equals
@ stub ??_7__non_rtti_object@@6B@
@ stub ??_7bad_cast@@6B@
@ stub ??_7bad_typeid@@6B@
@ stub ??_7exception@@6B@
@ cdecl ??_E__non_rtti_object@@UAEPAXI@Z(ptr long) MSVCRT___non_rtti_object__unknown_E
@ stub ??_Ebad_cast@@UAEPAXI@Z #(ptr long)
@ stub ??_Ebad_typeid@@UAEPAXI@Z #(ptr long)
@ cdecl ??_Eexception@@UAEPAXI@Z(ptr long) MSVCRT_exception__unknown_E
@ cdecl ??_G__non_rtti_object@@UAEPAXI@Z(ptr long) MSVCRT___non_rtti_object__unknown_G
@ stub ??_Gbad_cast@@UAEPAXI@Z #(ptr long)
@ stub ??_Gbad_typeid@@UAEPAXI@Z #(ptr long)
@ cdecl ??_Gexception@@UAEPAXI@Z(ptr long) MSVCRT_exception__unknown_G
@ cdecl ?_query_new_handler@@YAP6AHI@ZXZ() MSVCRT__query_new_handler
@ cdecl ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode
@ cdecl ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) MSVCRT__set_new_handler
@ cdecl ?_set_new_mode@@YAHH@Z(long) MSVCRT__set_new_mode
@ stub ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
@ stub ?before@type_info@@QBEHABV1@@Z #(ptr ptr) stdcall
@ stdcall ?name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_name
@ stdcall ?raw_name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_raw_name
@ stub ?set_new_handler@@YAP6AXXZP6AXXZ@Z
@ stub ?set_terminate@@YAP6AXXZP6AXXZ@Z
@ stub ?set_unexpected@@YAP6AXXZP6AXXZ@Z
@ stub ?terminate@@YAXXZ #()
@ stub ?unexpected@@YAXXZ #()
@ stdcall ?what@exception@@UBEPBDXZ(ptr) MSVCRT_exception_what
@ cdecl -noimport _CIacos() MSVCRT__CIacos
@ cdecl -noimport _CIasin() MSVCRT__CIasin
@ cdecl -noimport _CIatan() MSVCRT__CIatan
@ cdecl -noimport _CIatan2() MSVCRT__CIatan2
@ cdecl -noimport _CIcos() MSVCRT__CIcos
@ cdecl -noimport _CIcosh() MSVCRT__CIcosh
@ cdecl -noimport _CIexp() MSVCRT__CIexp
@ cdecl -noimport _CIfmod() MSVCRT__CIfmod
@ cdecl -noimport _CIlog() MSVCRT__CIlog
@ cdecl -noimport _CIlog10() MSVCRT__CIlog10
@ cdecl -noimport _CIpow() MSVCRT__CIpow
@ cdecl -noimport _CIsin() MSVCRT__CIsin
@ cdecl -noimport _CIsinh() MSVCRT__CIsinh
@ cdecl -noimport _CIsqrt() MSVCRT__CIsqrt
@ cdecl -noimport _CItan() MSVCRT__CItan
@ cdecl -noimport _CItanh() MSVCRT__CItanh
@ stub _CxxThrowException
@ cdecl _EH_prolog() MSVCRT__EH_prolog # FIXME: crashes relay debugging
@ cdecl _Getdays() MSVCRT__Getdays
@ cdecl _Getmonths() MSVCRT__Getmonths
@ cdecl _Getnames() MSVCRT__Getnames
@ extern _HUGE MSVCRT__HUGE
@ cdecl _Strftime(str long str ptr ptr) MSVCRT__Strftime
@ cdecl _XcptFilter(long ptr) MSVCRT__XcptFilter
@ stub __CxxFrameHandler
@ stub __CxxLongjmpUnwind
@ stub __RTCastToVoid
@ stub __RTDynamicCast
@ stub __RTtypeid
@ stub __STRINGTOLD
@ extern __argc MSVCRT___argc
@ extern __argv MSVCRT___argv
@ stub __badioinfo
@ stub __crtCompareStringA
@ stub __crtGetLocaleInfoW
@ stub __crtLCMapStringA
@ cdecl __dllonexit() MSVCRT___dllonexit
@ cdecl __doserrno() MSVCRT___doserrno
@ stub __fpecode #()
@ cdecl __getmainargs(ptr ptr ptr long) MSVCRT___getmainargs
@ extern __initenv MSVCRT___initenv
@ cdecl __isascii(long) MSVCRT___isascii
@ cdecl __iscsym(long) MSVCRT___iscsym
@ cdecl __iscsymf(long) MSVCRT___iscsymf
@ stub __lc_codepage
@ stub __lc_collate
@ stub __lc_handle
@ stub __lconv_init
@ extern __mb_cur_max MSVCRT___mb_cur_max
@ cdecl __p___argc() MSVCRT___p___argc
@ cdecl __p___argv() MSVCRT___p___argv
@ cdecl __p___initenv() MSVCRT___p___initenv
@ cdecl __p___mb_cur_max() MSVCRT___p___mb_cur_max
@ cdecl __p___wargv() MSVCRT___p___wargv
@ cdecl __p___winitenv() MSVCRT___p___winitenv
@ cdecl __p__acmdln() MSVCRT___p__acmdln
@ stub __p__amblksiz #()
@ cdecl __p__commode() MSVCRT___p__commode
@ stub __p__daylight #()
@ stub __p__dstbias #()
@ cdecl __p__environ() MSVCRT___p__environ
@ stub __p__fileinfo #()
@ cdecl __p__fmode() MSVCRT___p__fmode
@ cdecl __p__iob() MSVCRT___p__iob
@ stub __p__mbcasemap #()
@ cdecl __p__mbctype() MSVCRT___p__mbctype
@ cdecl __p__osver() MSVCRT___p__osver
@ cdecl __p__pctype() MSVCRT___p__pctype
@ stub __p__pgmptr #()
@ stub __p__pwctype #()
@ cdecl __p__timezone() MSVCRT___p__timezone
@ stub __p__tzname #()
@ cdecl __p__wcmdln() MSVCRT___p__wcmdln
@ cdecl __p__wenviron() MSVCRT___p__wenviron
@ cdecl __p__winmajor() MSVCRT___p__winmajor
@ cdecl __p__winminor() MSVCRT___p__winminor
@ cdecl __p__winver() MSVCRT___p__winver
@ stub __p__wpgmptr #()
@ stub __pioinfo #()
@ stub __pxcptinfoptrs #()
@ cdecl __set_app_type(long) MSVCRT___set_app_type
@ extern __setlc_active MSVCRT___setlc_active
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
@ forward __threadhandle kernel32.GetCurrentThread
@ forward __threadid kernel32.GetCurrentThreadId
@ cdecl __toascii(long) MSVCRT___toascii
@ cdecl __unDName() MSVCRT___unDName #FIXME
@ cdecl __unDNameEx() MSVCRT___unDNameEx #FIXME
@ extern __unguarded_readlc_active MSVCRT___unguarded_readlc_active
@ extern __wargv MSVCRT___wargv
@ cdecl __wgetmainargs(ptr ptr ptr long) MSVCRT___wgetmainargs
@ extern __winitenv MSVCRT___winitenv
@ cdecl _abnormal_termination() MSVCRT__abnormal_termination
@ cdecl _access(str long) MSVCRT__access
@ extern _acmdln MSVCRT__acmdln
@ cdecl _adj_fdiv_m16i() MSVCRT__adj_fdiv_m16i
@ cdecl _adj_fdiv_m32() MSVCRT__adj_fdiv_m32
@ cdecl _adj_fdiv_m32i() MSVCRT__adj_fdiv_m32i
@ cdecl _adj_fdiv_m64() MSVCRT__adj_fdiv_m64
@ cdecl _adj_fdiv_r() MSVCRT__adj_fdiv_r
@ cdecl _adj_fdivr_m16i() MSVCRT__adj_fdivr_m16i
@ cdecl _adj_fdivr_m32() MSVCRT__adj_fdivr_m32
@ cdecl _adj_fdivr_m32i() MSVCRT__adj_fdivr_m32i
@ cdecl _adj_fdivr_m64() MSVCRT__adj_fdivr_m64
@ cdecl _adj_fpatan() MSVCRT__adj_fpatan
@ cdecl _adj_fprem() MSVCRT__adj_fprem
@ cdecl _adj_fprem1() MSVCRT__adj_fprem1
@ cdecl _adj_fptan() MSVCRT__adj_fptan
@ cdecl _adjust_fdiv() MSVCRT__adjust_fdiv
@ stub _aexit_rtn
@ cdecl _amsg_exit(long) MSVCRT__amsg_exit
@ cdecl _assert(str str long) MSVCRT__assert
@ stub _atodbl
@ stub _atoi64 #(str)
@ stub _atoldbl
@ cdecl _beep(long long) MSVCRT__beep
@ stub _beginthread #(ptr long ptr)
@ cdecl _beginthreadex (ptr long ptr ptr long ptr) MSVCRT__beginthreadex
@ cdecl _c_exit() MSVCRT__c_exit
@ cdecl _cabs(long) MSVCRT__cabs
@ stub _callnewh
@ cdecl _cexit() MSVCRT__cexit
@ cdecl _cgets(str) MSVCRT__cgets
@ cdecl _chdir(str) MSVCRT__chdir
@ cdecl _chdrive(long) MSVCRT__chdrive
@ cdecl _chgsign( double ) MSVCRT__chgsign
@ cdecl -i386 _chkesp() MSVCRT__chkesp
@ cdecl _chmod(str long) MSVCRT__chmod
@ stub _chsize #(long long)
@ cdecl _clearfp() MSVCRT__clearfp
@ cdecl _close(long) MSVCRT__close
@ cdecl _commit(long) MSVCRT__commit
@ extern _commode MSVCRT__commode
@ cdecl _control87(long long) MSVCRT__control87
@ cdecl _controlfp(long long) MSVCRT__controlfp
@ cdecl _copysign( double double ) MSVCRT__copysign
@ varargs _cprintf(str) MSVCRT__cprintf
@ cdecl _cputs(str) MSVCRT__cputs
@ cdecl _creat(str long) MSVCRT__creat
@ varargs _cscanf(str) MSVCRT__cscanf
@ extern _ctype MSVCRT__ctype
@ cdecl _cwait(ptr long long) MSVCRT__cwait
@ stub _daylight
@ stub _dstbias
@ stub _dup #(long)
@ stub _dup2 #(long long)
@ cdecl _ecvt( double long ptr ptr) ecvt
@ stub _endthread #()
@ cdecl _endthreadex(long) MSVCRT__endthreadex
@ extern _environ MSVCRT__environ
@ cdecl _eof(long) MSVCRT__eof
@ cdecl _errno() MSVCRT__errno
@ cdecl _except_handler2(ptr ptr ptr ptr) MSVCRT__except_handler2
@ cdecl _except_handler3(ptr ptr ptr ptr) MSVCRT__except_handler3
@ stub _execl #(str str) varargs
@ stub _execle #(str str) varargs
@ stub _execlp #(str str) varargs
@ stub _execlpe #(str str) varargs
@ stub _execv #(str str)
@ stub _execve #(str str str)
@ stub _execvp #(str str)
@ stub _execvpe #(str str str)
@ cdecl _exit(long) MSVCRT__exit
@ cdecl _expand(ptr long) MSVCRT__expand
@ cdecl _fcloseall() MSVCRT__fcloseall
@ cdecl _fcvt( double long ptr ptr) fcvt
@ cdecl _fdopen(long str) MSVCRT__fdopen
@ cdecl _fgetchar() MSVCRT__fgetchar
@ cdecl _fgetwchar() MSVCRT__fgetwchar
@ cdecl _filbuf(ptr) MSVCRT__filbuf
@ stub _fileinfo
@ cdecl _filelength(long) MSVCRT__filelength
@ stub _filelengthi64 #(long)
@ cdecl _fileno(ptr) MSVCRT__fileno
@ cdecl _findclose(long) MSVCRT__findclose
@ cdecl _findfirst(str ptr) MSVCRT__findfirst
@ stub _findfirsti64 #(str ptr)
@ cdecl _findnext(long ptr) MSVCRT__findnext
@ stub _findnexti64 #(long ptr)
@ cdecl _finite( double ) MSVCRT__finite
@ cdecl _flsbuf(long ptr) MSVCRT__flsbuf
@ cdecl _flushall() MSVCRT__flushall
@ extern _fmode MSVCRT__fmode
@ cdecl _fpclass(double) MSVCRT__fpclass
@ stub _fpieee_flt
@ cdecl _fpreset() MSVCRT__fpreset
@ cdecl _fputchar(long) MSVCRT__fputchar
@ cdecl _fputwchar(long) MSVCRT__fputwchar
@ cdecl _fsopen(str str) MSVCRT__fsopen
@ cdecl _fstat(long ptr) MSVCRT__fstat
@ stub _fstati64 #(long ptr)
@ cdecl _ftime(ptr) MSVCRT__ftime
@ forward _ftol ntdll._ftol
@ cdecl _fullpath(str str long) MSVCRT__fullpath
@ cdecl _futime() MSVCRT__futime
@ cdecl _gcvt( double long str) gcvt
@ cdecl _get_osfhandle(long) MSVCRT__get_osfhandle
@ stub _get_sbh_threshold #()
@ cdecl _getch() MSVCRT__getch
@ cdecl _getche() MSVCRT__getche
@ cdecl _getcwd(str long) MSVCRT__getcwd
@ cdecl _getdcwd(long str long) MSVCRT__getdcwd
@ cdecl _getdiskfree(long ptr) MSVCRT__getdiskfree
@ forward _getdllprocaddr kernel32.GetProcAddress
@ cdecl _getdrive() MSVCRT__getdrive
@ forward _getdrives kernel32.GetLogicalDrives
@ stub _getmaxstdio #()
@ cdecl _getmbcp() MSVCRT__getmbcp
@ forward _getpid kernel32.GetCurrentProcessId
@ stub _getsystime #(ptr)
@ cdecl _getw(ptr) MSVCRT__getw
@ stub _getws #(wstr)
@ cdecl _global_unwind2(ptr) MSVCRT__global_unwind2
@ stub _heapadd #()
@ cdecl _heapchk() MSVCRT__heapchk
@ cdecl _heapmin() MSVCRT__heapmin
@ cdecl _heapset(long) MSVCRT__heapset
@ stub _heapused #(ptr ptr)
@ cdecl _heapwalk(ptr) MSVCRT__heapwalk
@ cdecl _hypot(double double) hypot
@ stub _i64toa #(long str long)
@ stub _i64tow #(long wstr long)
@ cdecl _initterm(ptr ptr) MSVCRT__initterm
@ stub -i386 _inp #(long)
@ stub -i386 _inpd #(long)
@ stub -i386 _inpw #(long)
@ extern _iob MSVCRT__iob
@ cdecl _isatty(long) MSVCRT__isatty
@ cdecl _isctype(long long) MSVCRT__isctype
@ stub _ismbbalnum #(long)
@ stub _ismbbalpha #(long)
@ stub _ismbbgraph #(long)
@ stub _ismbbkalnum #(long)
@ cdecl _ismbbkana(long) MSVCRT__ismbbkana
@ stub _ismbbkprint #(long)
@ stub _ismbbkpunct #(long)
@ cdecl _ismbblead(long) MSVCRT__ismbblead
@ stub _ismbbprint #(long)
@ stub _ismbbpunct #(long)
@ cdecl _ismbbtrail(long) MSVCRT__ismbbtrail
@ stub _ismbcalnum #(long)
@ stub _ismbcalpha #(long)
@ stub _ismbcdigit #(long)
@ stub _ismbcgraph #(long)
@ cdecl _ismbchira(long) MSVCRT__ismbchira
@ cdecl _ismbckata(long) MSVCRT__ismbckata
@ stub _ismbcl0 #(long)
@ stub _ismbcl1 #(long)
@ stub _ismbcl2 #(long)
@ stub _ismbclegal #(long)
@ stub _ismbclower #(long)
@ stub _ismbcprint #(long)
@ stub _ismbcpunct #(long)
@ stub _ismbcspace #(long)
@ stub _ismbcsymbol #(long)
@ stub _ismbcupper #(long)
@ cdecl _ismbslead(ptr ptr) MSVCRT__ismbslead
@ cdecl _ismbstrail(ptr ptr) MSVCRT__ismbstrail
@ cdecl _isnan( double ) MSVCRT__isnan
@ forward _itoa ntdll._itoa
@ cdecl _itow(long wstr long) MSVCRT__itow
@ cdecl _j0(double) j0
@ cdecl _j1(double) j1
@ cdecl _jn(long double) jn
@ cdecl _kbhit() MSVCRT__kbhit
@ stub _lfind
@ cdecl _loaddll(str) MSVCRT__loaddll
@ cdecl _local_unwind2(ptr long) MSVCRT__local_unwind2
@ stub _lock
@ stub _locking #(long long long)
@ cdecl _logb( double ) MSVCRT__logb
@ stub _longjmpex
@ cdecl _lrotl(long long) MSVCRT__lrotl
@ cdecl _lrotr(long long) MSVCRT__lrotr
@ cdecl _lsearch(ptr ptr long long ptr) MSVCRT__lsearch
@ cdecl _lseek(long long long) MSVCRT__lseek
@ stub _lseeki64 #(long long long)
@ forward _ltoa ntdll._ltoa
@ forward _ltow ntdll._ltow
@ cdecl _makepath(str str str str str) MSVCRT__makepath
@ cdecl _mbbtombc(long) MSVCRT__mbbtombc
@ stub _mbbtype #(long long)
@ stub _mbcasemap
@ cdecl _mbccpy (str str) strcpy
@ stub _mbcjistojms #(long)
@ stub _mbcjmstojis #(long)
@ cdecl _mbclen(ptr) MSVCRT__mbclen
@ stub _mbctohira #(long)
@ stub _mbctokata #(long)
@ stub _mbctolower #(long)
@ stub _mbctombb #(long)
@ stub _mbctoupper #(long)
@ stub _mbctype
@ stub _mbsbtype #(ptr long)
@ cdecl _mbscat(str str) strcat
@ cdecl _mbschr(str long) MSVCRT__mbschr
@ cdecl _mbscmp(str str) MSVCRT__mbscmp
@ stub _mbscoll #(str str)
@ cdecl _mbscpy(ptr str) strcpy
@ stub _mbscspn #(str str)
@ cdecl _mbsdec(ptr ptr) MSVCRT__mbsdec
@ cdecl _mbsdup(str) MSVCRT__strdup
@ cdecl _mbsicmp(str str) MSVCRT__mbsicmp
@ stub _mbsicoll #(str str)
@ cdecl _mbsinc(str) MSVCRT__mbsinc
@ cdecl _mbslen(str) MSVCRT__mbslen
@ stub _mbslwr #(str)
@ stub _mbsnbcat #(str str long)
@ stub _mbsnbcmp #(str str long)
@ stub _mbsnbcnt #(ptr long)
@ stub _mbsnbcoll #(str str long)
@ stub _mbsnbcpy #(ptr str long)
@ stub _mbsnbicmp #(str str long)
@ stub _mbsnbicoll #(str str long)
@ stub _mbsnbset #(str long long)
@ cdecl _mbsncat(str str long) MSVCRT__mbsncat
@ cdecl _mbsnccnt(str long) MSVCRT__mbsnccnt
@ cdecl _mbsncmp(str str long) MSVCRT__mbsncmp
@ stub _mbsncoll #(ptr str long)
@ cdecl _mbsncpy(str str long) MSVCRT__mbsncpy
@ cdecl _mbsnextc(str) MSVCRT__mbsnextc
@ cdecl _mbsnicmp(str str long) MSVCRT__mbsnicmp
@ stub _mbsnicoll #(str str long)
@ cdecl _mbsninc(str long) MSVCRT__mbsninc
@ cdecl _mbsnset(str long long) MSVCRT__mbsnset
@ stub _mbspbrk #(str str)
@ cdecl _mbsrchr(str long) MSVCRT__mbsrchr
@ stub _mbsrev #(str)
@ cdecl _mbsset(str long) MSVCRT__mbsset
@ stub _mbsspn #(str str)
@ stub _mbsspnp #(str str)
@ cdecl _mbsstr(str str) strstr
@ stub _mbstok #(str str)
@ cdecl _mbstrlen(str) MSVCRT__mbstrlen
@ stub _mbsupr #(str)
@ cdecl _memccpy(ptr ptr long long) memccpy
@ forward _memicmp ntdll._memicmp
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mktemp(str) MSVCRT__mktemp
@ cdecl _msize(ptr) MSVCRT__msize
@ cdecl _nextafter(double double) MSVCRT__nextafter
@ cdecl _onexit(ptr) MSVCRT__onexit
@ cdecl _open(str long) MSVCRT__open
@ cdecl _open_osfhandle(long long) MSVCRT__open_osfhandle
@ stub _osver
@ stub _outp #(long long)
@ stub _outpd #(long long)
@ stub _outpw #(long long)
@ stub _pclose #(ptr)
@ extern _pctype MSVCRT__pctype
@ stub _pgmptr
@ stub _pipe #(ptr long long)
@ stub _popen #(str str)
@ cdecl _purecall() MSVCRT__purecall
@ cdecl _putch(long) MSVCRT__putch
@ stub _putenv #(str)
@ cdecl _putw(long ptr) MSVCRT__putw
@ stub _putws #(wstr)
@ stub _pwctype
@ cdecl _read(long ptr long) MSVCRT__read
@ cdecl _rmdir(str) MSVCRT__rmdir
@ cdecl _rmtmp() MSVCRT__rmtmp
@ cdecl _rotl(long long) MSVCRT__rotl
@ cdecl _rotr(long long) MSVCRT__rotr
@ cdecl _safe_fdiv() MSVCRT__safe_fdiv
@ cdecl _safe_fdivr() MSVCRT__safe_fdivr
@ cdecl _safe_fprem() MSVCRT__safe_fprem
@ cdecl _safe_fprem1() MSVCRT__safe_fprem1
@ cdecl _scalb( double long) MSVCRT__scalb
@ cdecl _searchenv(str str str) MSVCRT__searchenv
@ stub _seh_longjmp_unwind
@ stub _set_error_mode #(long)
@ stub _set_sbh_threshold #(long)
@ stub _seterrormode #(long)
@ cdecl _setjmp(ptr) MSVCRT__setjmp
@ stub _setjmp3
@ stub _setmaxstdio #(long)
@ cdecl _setmbcp(long) MSVCRT__setmbcp
@ cdecl _setmode(long long) MSVCRT__setmode
@ stub _setsystime #(ptr long)
@ cdecl _sleep(long) MSVCRT__sleep
@ varargs _snprintf(str long str) snprintf
@ stub _snwprintf #(wstr long wstr) varargs
@ stub _sopen
@ stub _spawnl #(str str) varargs
@ stub _spawnle #(str str) varargs
@ stub _spawnlp #(str str) varargs
@ stub _spawnlpe #(str str) varargs
@ cdecl _spawnv(str str) MSVCRT__spawnv
@ cdecl _spawnve(str str str) MSVCRT__spawnve
@ cdecl _spawnvp(str str) MSVCRT__spawnvp
@ cdecl _spawnvpe(str str str) MSVCRT__spawnvpe
@ cdecl _splitpath(str str str str str) MSVCRT__splitpath
@ cdecl _stat(str ptr) MSVCRT__stat
@ stub _stati64 #(str ptr)
@ cdecl _statusfp() MSVCRT__statusfp
@ cdecl _strcmpi(str str) strcasecmp
@ cdecl _strdate(str) MSVCRT__strdate
@ cdecl _strdup(str) MSVCRT__strdup
@ cdecl _strerror(long) MSVCRT__strerror
@ cdecl _stricmp(str str) strcasecmp
@ stub _stricoll #(str str)
@ forward _strlwr ntdll._strlwr
@ stub _strncoll #(str str long)
@ cdecl _strnicmp(str str long) strncasecmp
@ stub _strnicoll #(str str long)
@ cdecl _strnset(str long long) MSVCRT__strnset
@ cdecl _strrev(str) MSVCRT__strrev
@ cdecl _strset(str long) MSVCRT__strset
@ cdecl _strtime(str) MSVCRT__strtime
@ forward _strupr ntdll._strupr
@ cdecl _swab(str str long) MSVCRT__swab
@ stub _sys_errlist #()
@ stub _sys_nerr #()
@ cdecl _tell(long) MSVCRT__tell
@ stub _telli64 #(long)
@ cdecl _tempnam(str str) MSVCRT__tempnam
@ stub _timezone #()
@ cdecl _tolower(long) MSVCRT__tolower
@ cdecl _toupper(long) MSVCRT__toupper
@ stub _tzname
@ stub _tzset #()
@ stub _ui64toa #(long str long)
@ stub _ui64tow #(long wstr long)
@ forward _ultoa ntdll._ultoa
@ forward _ultow ntdll._ultow
@ cdecl _umask(long) MSVCRT__umask
@ cdecl _ungetch(long) MSVCRT__ungetch
@ cdecl _unlink(str) MSVCRT__unlink
@ cdecl _unloaddll(long) MSVCRT__unloaddll
@ stub _unlock
@ cdecl _utime(str ptr) MSVCRT__utime
@ cdecl _vsnprintf(ptr long ptr ptr) vsnprintf
@ stub _vsnwprintf #(wstr long wstr long)
@ stub _waccess #(wstr long)
@ stub _wasctime #(ptr)
@ cdecl _wchdir(wstr) MSVCRT__wchdir
@ stub _wchmod #(wstr long)
@ extern _wcmdln MSVCRT__wcmdln
@ stub _wcreat #(wstr long)
@ cdecl _wcsdup(wstr) MSVCRT__wcsdup
@ forward _wcsicmp ntdll._wcsicmp
@ cdecl _wcsicoll(wstr wstr) MSVCRT__wcsicoll
@ stub _wcslwr #(wstr)
@ stub _wcsncoll #(wstr wstr long)
@ forward _wcsnicmp ntdll._wcsnicmp
@ stub _wcsnicoll #(wstr wstr long)
@ cdecl _wcsnset(wstr long long) MSVCRT__wcsnset
@ cdecl _wcsrev(wstr) MSVCRT__wcsrev
@ cdecl _wcsset(wstr long) MSVCRT__wcsset
@ forward _wcsupr ntdll._wcsupr
@ stub _wctime #(ptr)
@ extern _wenviron MSVCRT__wenviron
@ stub _wexecl #(wstr wstr) varargs
@ stub _wexecle #(wstr wstr) varargs
@ stub _wexeclp #(wstr wstr) varargs
@ stub _wexeclpe #(wstr wstr) varargs
@ stub _wexecv #(wstr wstr)
@ stub _wexecve #(wstr wstr wstr)
@ stub _wexecvp #(wstr wstr)
@ stub _wexecvpe #(wstr wstr wstr)
@ stub _wfdopen #(long wstr)
@ cdecl _wfindfirst(wstr ptr) MSVCRT__wfindfirst
@ stub _wfindfirsti64 #(wstr ptr)
@ cdecl _wfindnext(long ptr) MSVCRT__wfindnext
@ stub _wfindnexti64 #(long ptr)
@ stub _wfopen #(wstr wstr)
@ stub _wfreopen #(wstr wstr ptr)
@ stub _wfsopen #(wstr wstr)
@ stub _wfullpath #(wstr wstr long)
@ cdecl _wgetcwd(wstr long) MSVCRT__wgetcwd
@ cdecl _wgetdcwd(long wstr long) MSVCRT__wgetdcwd
@ cdecl _wgetenv(wstr) MSVCRT__wgetenv
@ extern _winmajor MSVCRT__winmajor
@ extern _winminor MSVCRT__winminor
@ extern _winver MSVCRT__winver
@ stub _wmakepath #(wstr wstr wstr wstr wstr)
@ cdecl _wmkdir(wstr) MSVCRT__wmkdir
@ stub _wmktemp #(wstr)
@ stub _wopen #(wstr long) varargs
@ stub _wperror #(wstr)
@ stub _wpgmptr
@ stub _wpopen #(wstr wstr)
@ stub _wputenv #(wstr)
@ stub _wremove #(wstr)
@ stub _wrename #(wstr wstr)
@ cdecl _write(long ptr long) MSVCRT__write
@ cdecl _wrmdir(wstr) MSVCRT__wrmdir
@ stub _wsearchenv #(wstr wstr wstr)
@ stub _wsetlocale #(long wstr)
@ stub _wsopen #(wstr long long) varargs
@ stub _wspawnl #(long wstr wstr) varargs
@ stub _wspawnle #(long wstr wstr) varargs
@ stub _wspawnlp #(long wstr wstr) varargs
@ stub _wspawnlpe #(long wstr wstr) varargs
@ stub _wspawnv #(long wstr wstr)
@ stub _wspawnve #(long wstr wstr wstr)
@ stub _wspawnvp #(long wstr wstr)
@ stub _wspawnvpe #(long wstr wstr wstr)
@ stub _wsplitpath #(wstr wstr wstr wstr wstr)
@ stub _wstat #(wstr ptr)
@ stub _wstati64 #(wstr ptr)
@ stub _wstrdate #(wstr)
@ stub _wstrtime #(wstr)
@ stub _wsystem #(wstr)
@ stub _wtempnam #(wstr wstr)
@ stub _wtmpnam #(wstr)
@ forward _wtoi NTDLL._wtoi
@ stub _wtoi64 #(wstr)
@ forward _wtol NTDLL._wtol
@ stub _wunlink #(wstr)
@ stub _wutime
@ cdecl _y0(double) MSVCRT__y0
@ cdecl _y1(double) MSVCRT__y1
@ cdecl _yn(long double ) MSVCRT__yn
@ cdecl abort() MSVCRT_abort
@ cdecl abs(long) abs
@ cdecl acos( double ) acos
@ cdecl asctime(ptr) asctime
@ cdecl asin(double) asin
@ cdecl atan(double) atan
@ cdecl atan2(double double) atan2
@ cdecl atexit(ptr) MSVCRT_atexit
@ cdecl atof(str) atof
@ cdecl atoi(str) atoi
@ cdecl atol(str) atol
@ cdecl bsearch(ptr ptr long long ptr) bsearch
@ cdecl calloc(long long) MSVCRT_calloc
@ cdecl ceil(double) ceil
@ cdecl clearerr(ptr) MSVCRT_clearerr
@ cdecl clock() MSVCRT_clock
@ cdecl cos(double) cos
@ cdecl cosh(double) cosh
@ cdecl ctime(ptr) ctime
@ cdecl difftime(long long) MSVCRT_difftime
@ cdecl -noimport div(long long) MSVCRT_div
@ cdecl exit(long) MSVCRT_exit
@ cdecl exp(double) exp
@ cdecl fabs(double) fabs
@ cdecl fclose(ptr) MSVCRT_fclose
@ cdecl feof(ptr) MSVCRT_feof
@ cdecl ferror(ptr) MSVCRT_ferror
@ cdecl fflush(ptr) MSVCRT_fflush
@ cdecl fgetc(ptr) MSVCRT_fgetc
@ cdecl fgetpos(ptr ptr) MSVCRT_fgetpos
@ cdecl fgets(str long ptr) MSVCRT_fgets
@ cdecl fgetwc(ptr) MSVCRT_fgetwc
@ stub fgetws #(wstr long ptr)
@ cdecl floor(double) floor
@ cdecl fmod(double double) fmod
@ cdecl fopen(str str) MSVCRT_fopen
@ varargs fprintf(ptr str) MSVCRT_fprintf
@ cdecl fputc(long ptr) MSVCRT_fputc
@ cdecl fputs(str ptr) MSVCRT_fputs
@ cdecl fputwc(long ptr) MSVCRT_fputwc
@ stub fputws #(wstr ptr)
@ cdecl fread() MSVCRT_fread
@ cdecl free() MSVCRT_free
@ cdecl freopen(str str ptr) MSVCRT_freopen
@ cdecl frexp(double ptr) frexp
@ varargs fscanf(ptr str) MSVCRT_fscanf
@ cdecl fseek(ptr long long) MSVCRT_fseek
@ cdecl fsetpos(ptr ptr) MSVCRT_fsetpos
@ cdecl ftell(ptr) MSVCRT_ftell
@ stub fwprintf #(ptr wstr) varargs
@ cdecl fwrite(ptr long long ptr) MSVCRT_fwrite
@ stub fwscanf #(ptr wstr) varargs
@ cdecl getc(ptr) MSVCRT_getc
@ cdecl getchar() MSVCRT_getchar
@ cdecl getenv(str) MSVCRT_getenv
@ cdecl gets(str) MSVCRT_gets
@ cdecl getwc(ptr) MSVCRT_getwc
@ cdecl getwchar() MSVCRT_getwchar
@ cdecl gmtime(ptr) gmtime
@ forward is_wctype ntdll.iswctype
@ cdecl isalnum(long) MSVCRT_isalnum
@ cdecl isalpha(long) MSVCRT_isalpha
@ cdecl iscntrl(long) MSVCRT_iscntrl
@ cdecl isdigit(long) MSVCRT_isdigit
@ cdecl isgraph(long) MSVCRT_isgraph
@ cdecl isleadbyte(long) MSVCRT_isleadbyte
@ cdecl islower(long) MSVCRT_islower
@ cdecl isprint(long) MSVCRT_isprint
@ cdecl ispunct(long) MSVCRT_ispunct
@ cdecl isspace(long) MSVCRT_isspace
@ cdecl isupper(long) MSVCRT_isupper
@ cdecl iswalnum(long) MSVCRT_iswalnum
@ forward iswalpha ntdll._iswalpha
@ cdecl iswascii(long) MSVCRT_iswascii
@ cdecl iswcntrl(long) MSVCRT_iswcntrl
@ forward iswctype ntdll._iswctype
@ cdecl iswdigit(long) MSVCRT_iswdigit
@ cdecl iswgraph(long) MSVCRT_iswgraph
@ cdecl iswlower(long) MSVCRT_iswlower
@ cdecl iswprint(long) MSVCRT_iswprint
@ cdecl iswpunct(long) MSVCRT_iswpunct
@ cdecl iswspace(long) MSVCRT_iswspace
@ cdecl iswupper(long) MSVCRT_iswupper
@ cdecl iswxdigit(long) MSVCRT_iswxdigit
@ cdecl isxdigit(long) MSVCRT_isxdigit
@ cdecl labs(long) labs
@ cdecl ldexp( double long) MSVCRT_ldexp
@ cdecl -noimport ldiv(long long) MSVCRT_ldiv
@ stub localeconv #()
@ cdecl localtime(ptr) localtime
@ cdecl log(double) log
@ cdecl log10(double) log10
@ cdecl longjmp(long long) MSVCRT_longjmp
@ cdecl malloc(long) MSVCRT_malloc
@ stub mblen #(str long)
@ forward mbstowcs ntdll.mbstowcs
@ cdecl mbtowc(wstr str long) MSVCRT_mbtowc
@ cdecl memchr(ptr long long) memchr
@ cdecl memcmp(ptr ptr long) memcmp
@ cdecl memcpy(ptr ptr long) memcpy
@ cdecl memmove(ptr ptr long) memmove
@ cdecl memset(ptr long long) memset
@ cdecl mktime(ptr) mktime
@ cdecl modf(double ptr) modf
@ cdecl perror(str) MSVCRT_perror
@ cdecl pow(double double) pow
@ varargs printf(str) MSVCRT_printf
@ cdecl putc(long ptr) MSVCRT_putc
@ cdecl putchar(long) MSVCRT_putchar
@ cdecl puts(str) MSVCRT_puts
@ stub putwc #(long ptr)
@ stub putwchar #(long)
@ cdecl qsort(ptr long long ptr) qsort
@ stub raise #(long)
@ cdecl rand() MSVCRT_rand
@ cdecl realloc() MSVCRT_realloc
@ cdecl remove(str) MSVCRT_remove
@ cdecl rename(str str) MSVCRT_rename
@ cdecl rewind(ptr) MSVCRT_rewind
@ varargs scanf(str) MSVCRT_scanf
@ cdecl setbuf(ptr ptr) MSVCRT_setbuf
@ cdecl setlocale(long str) MSVCRT_setlocale
@ stub setvbuf #(ptr str long long)
@ cdecl signal(long long) MSVCRT_signal
@ cdecl sin(double) sin
@ cdecl sinh(double) sinh
@ varargs sprintf(str str) sprintf
@ cdecl sqrt(double) sqrt
@ cdecl srand(long) srand
@ varargs sscanf(str str) sscanf
@ cdecl strcat(str str) strcat
@ cdecl strchr(str long) strchr
@ cdecl strcmp(str str) strcmp
@ cdecl strcoll(str str) strcoll
@ cdecl strcpy(ptr str) strcpy
@ cdecl strcspn(str str) strcspn
@ cdecl strerror(long) MSVCRT_strerror
@ cdecl strftime(str long str ptr) strftime
@ cdecl strlen(str) strlen
@ cdecl strncat(str str long) strncat
@ cdecl strncmp(str str long) strncmp
@ cdecl strncpy(ptr str long) strncpy
@ cdecl strpbrk(str str) strpbrk
@ cdecl strrchr(str long) strrchr
@ cdecl strspn(str str) strspn
@ cdecl strstr(str str) strstr
@ cdecl strtod(str ptr) strtod
@ cdecl strtok(str str) strtok
@ cdecl strtol(str ptr long) strtol
@ cdecl strtoul(str ptr long) strtoul
@ cdecl strxfrm(ptr str long) strxfrm
@ stub swprintf #(wstr wstr) varargs
@ stub swscanf #(wstr wstr) varargs
@ cdecl system(str) MSVCRT_system
@ cdecl tan(double) tan
@ cdecl tanh(double) tanh
@ cdecl time(ptr) MSVCRT_time
@ cdecl tmpfile() MSVCRT_tmpfile
@ cdecl tmpnam(str) MSVCRT_tmpnam
@ forward towlower ntdll.towlower
@ forward towupper ntdll.towupper
@ stub ungetc #(long ptr)
@ stub ungetwc #(long ptr)
@ cdecl vfprintf(ptr str long) MSVCRT_vfprintf
@ stub vfwprintf #(ptr wstr long)
@ stub vprintf #(str long)
@ cdecl vsprintf(ptr str ptr) vsprintf
@ stub vswprintf #(wstr wstr long)
@ stub vwprintf #(wstr long)
@ forward wcscat ntdll.wcscat
@ forward wcschr ntdll.wcschr
@ forward wcscmp ntdll.wcscmp
@ cdecl wcscoll(wstr wstr) MSVCRT_wcscoll
@ forward wcscpy ntdll.wcscpy
@ forward wcscspn ntdll.wcscspn
@ stub wcsftime #(wstr long wstr ptr)
@ forward wcslen ntdll.wcslen
@ forward wcsncat ntdll.wcsncat
@ forward wcsncmp ntdll.wcsncmp
@ forward wcsncpy ntdll.wcsncpy
@ cdecl wcspbrk(wstr wstr) MSVCRT_wcspbrk
@ forward wcsrchr ntdll.wcsrchr
@ forward wcsspn ntdll.wcsspn
@ forward wcsstr ntdll.wcsstr
@ stub wcstod #(wstr ptr)
@ forward wcstok ntdll.wcstok
@ forward wcstol ntdll.wcstol
@ forward wcstombs ntdll.wcstombs
@ stub wcstoul #(wstr ptr long)
@ stub wcsxfrm #(wstr wstr long)
@ cdecl wctomb(ptr long) MSVCRT_wctomb
@ stub wprintf #(wstr) varargs
@ stub wscanf #(wstr) varargs
/*
* msvcrt.dll spawn/exec functions
*
* Copyright 1996,1998 Marcus Meissner
* Copyright 1996 Jukka Iivonen
* Copyright 1997,2000 Uwe Bonnes
* Copyright 2000 Jon Griffiths
*
* FIXME:
* -File handles need some special handling. Sometimes children get
* open file handles, sometimes not. The docs are confusing
* -No check for maximum path/argument/environment size is done
*/
#include "msvcrt.h"
#include "ms_errno.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* Process creation flags */
#define _P_WAIT 0
#define _P_NOWAIT 1
#define _P_OVERLAY 2
#define _P_NOWAITO 3
#define _P_DETACH 4
void __cdecl MSVCRT__exit(int);
void __cdecl MSVCRT__searchenv(const char* file, const char* env, char *buf);
/* FIXME: Check file extenstions for app to run */
static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e';
static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't';
static const unsigned int CMD = 'c' << 16 | 'm' << 8 | 'd';
static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm';
/* INTERNAL: Spawn a child process */
static int __MSVCRT__spawn(int flags, const char *exe, char * args, char *env)
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
if (sizeof(HANDLE) != sizeof(int))
WARN("This call is unsuitable for your architecture\n");
if ((unsigned)flags > _P_DETACH)
{
SET_THREAD_VAR(errno,MSVCRT_EINVAL);
return -1;
}
FIXME(":must dup/kill streams for child process\n");
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcessA(exe, args, NULL, NULL, TRUE,
flags == _P_DETACH ? DETACHED_PROCESS : 0,
env, NULL, &si, &pi))
{
MSVCRT__set_errno(GetLastError());
return -1;
}
switch(flags)
{
case _P_WAIT:
WaitForSingleObject(pi.hProcess,-1); /* wait forvever */
GetExitCodeProcess(pi.hProcess,&pi.dwProcessId);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return (int)pi.dwProcessId;
case _P_DETACH:
CloseHandle(pi.hProcess);
pi.hProcess = 0;
/* fall through */
case _P_NOWAIT:
case _P_NOWAITO:
CloseHandle(pi.hThread);
return (int)pi.hProcess;
case _P_OVERLAY:
MSVCRT__exit(0);
}
return -1; /* can't reach here */
}
/* INTERNAL: Convert argv list to a single 'delim'-seperated string */
static char * __MSVCRT__argvtos(const char * *arg, char delim)
{
const char **search = arg;
long size = 0;
char *ret;
if (!arg && !delim)
return NULL;
/* get length */
while(*search)
{
size += strlen(*search) + 1;
search++;
}
if (!(ret = (char *)MSVCRT_calloc(size + 1, 1)))
return NULL;
/* fill string */
search = arg;
size = 0;
while(*search)
{
int strsize = strlen(*search);
memcpy(ret+size,*search,strsize);
ret[size+strsize] = delim;
size += strsize + 1;
search++;
}
return ret;
}
/*********************************************************************
* _cwait (MSVCRT.@)
*/
int __cdecl MSVCRT__cwait(int *status, int pid, int action)
{
HANDLE hPid = (HANDLE)pid;
int doserrno;
action = action; /* Remove warning */
if (!WaitForSingleObject(hPid, -1)) /* wait forever */
{
if (status)
{
DWORD stat;
GetExitCodeProcess(hPid, &stat);
*status = (int)stat;
}
return (int)pid;
}
doserrno = GetLastError();
if (doserrno == ERROR_INVALID_HANDLE)
{
SET_THREAD_VAR(errno, MSVCRT_ECHILD);
SET_THREAD_VAR(doserrno,doserrno);
}
else
MSVCRT__set_errno(doserrno);
return status ? *status = -1 : -1;
}
/*********************************************************************
* _spawnve (MSVCRT.@)
*/
int __cdecl MSVCRT__spawnve(int flags, const char *name, const char **argv,
const char **envv)
{
char * args = __MSVCRT__argvtos(argv,' ');
char * envs = __MSVCRT__argvtos(envv,0);
LPCSTR fullname = name;
int ret = -1;
FIXME(":not translating name %s to locate program\n",fullname);
TRACE(":call (%s), params (%s), env (%s)\n",name,args,envs?"Custom":"Null");
if (args)
{
ret = __MSVCRT__spawn(flags, fullname, args, envs);
MSVCRT_free(args);
}
if (envs)
MSVCRT_free(envs);
return ret;
}
/*********************************************************************
* _spawnv (MSVCRT.@)
*/
int __cdecl MSVCRT__spawnv(int flags, const char *name, const char **argv)
{
return MSVCRT__spawnve(flags, name, argv, NULL);
}
/*********************************************************************
* _spawnvpe (MSVCRT.@)
*/
int __cdecl MSVCRT__spawnvpe(int flags, const char *name, const char **argv,
const char **envv)
{
char fullname[MAX_PATH];
MSVCRT__searchenv(name, "PATH", fullname);
return MSVCRT__spawnve(flags, fullname[0] ? fullname : name, argv, envv);
}
/*********************************************************************
* _spawnvp (MSVCRT.@)
*/
int __cdecl MSVCRT__spawnvp(int flags, const char *name, const char **argv)
{
return MSVCRT__spawnvpe(flags, name, argv, NULL);
}
/*********************************************************************
* system (MSVCRT.@)
*/
int __cdecl MSVCRT_system(const char *cmd)
{
/* FIXME: should probably launch cmd interpreter in COMSPEC */
return __MSVCRT__spawn(_P_WAIT, cmd, NULL, NULL);
}
/*********************************************************************
* _loaddll (MSVCRT.@)
*/
int __cdecl MSVCRT__loaddll(const char *dllname)
{
return LoadLibraryA(dllname);
}
/*********************************************************************
* _unloaddll (MSVCRT.@)
*/
int __cdecl MSVCRT__unloaddll(int dll)
{
if (FreeLibrary((HANDLE)dll))
return 0;
else
{
int err = GetLastError();
MSVCRT__set_errno(err);
return err;
}
}
/*
* MSVCRT string functions
*
* Copyright 1996,1998 Marcus Meissner
* Copyright 1996 Jukka Iivonen
* Copyright 1997,2000 Uwe Bonnes
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* INTERNAL: MSVCRT_malloc() based strndup */
char * MSVCRT__strndup(const char * buf, unsigned int size)
{
char* ret;
unsigned int len = strlen(buf), max_len;
max_len = size <= len? size : len + 1;
ret = MSVCRT_malloc(max_len);
if (ret)
{
memcpy(ret,buf,max_len);
ret[max_len] = 0;
}
return ret;
}
/*********************************************************************
* _strdec (MSVCRT.@)
*/
char * __cdecl MSVCRT__strdec(const char * str1, const char * str2)
{
/* Hmm. While the docs suggest that the following should work... */
/* return (str2<=str1?0:str2-1); */
/* ...Version 2.50.4170 (NT) from win98 constantly decrements! */
str1 = str1; /* remove warning */
return (char *)str2-1;
}
/*********************************************************************
* _strdup (MSVCRT.@)
*/
char * __cdecl MSVCRT__strdup(const char * str)
{
char * ret = MSVCRT_malloc(strlen(str)+1);
if (ret) strcpy( ret, str );
return ret;
}
/*********************************************************************
* _strinc (MSVCRT.@)
*/
char * __cdecl MSVCRT__strinc(const char * str)
{
return (char*)str+1;
}
/*********************************************************************
* _strnextc (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__strnextc(const char * str)
{
return (unsigned int)*str;
}
/*********************************************************************
* _strninc (MSVCRT.@)
*
* Return a pointer to the 'n'th character in a string
*/
char * __cdecl MSVCRT__strninc(char * str, unsigned int n)
{
return str + n;
}
/*********************************************************************
* _strnset (MSVCRT.@)
*/
char * __cdecl MSVCRT__strnset(char * str, int value, unsigned int len)
{
if (len > 0 && str)
while (*str && len--)
*str++ = value;
return str;
}
/*********************************************************************
* _strrev (MSVCRT.@)
*/
char * __cdecl MSVCRT__strrev (char * str)
{
char * p1;
char * p2;
if (str && *str)
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}
/*********************************************************************
* _strset (MSVCRT.@)
*/
char * __cdecl MSVCRT__strset (char * str, int value)
{
char *ptr = str;
while (*ptr)
*ptr++ = value;
return str;
}
/*********************************************************************
* _strncnt (MSVCRT.@)
*/
unsigned int __cdecl MSVCRT__strncnt(char * str, unsigned int max)
{
unsigned int len = strlen(str);
return (len > max? max : len);
}
/*********************************************************************
* _strspnp (MSVCRT.@)
*/
char * __cdecl MSVCRT__strspnp(char * str1, char * str2)
{
str1 += strspn(str1,str2);
return *str1? str1 : 0;
}
/*********************************************************************
* _swab (MSVCRT.@)
*/
void __cdecl MSVCRT__swab(char * src, char * dst, int len)
{
if (len > 1)
{
len = (unsigned)len >> 1;
while (len--) {
*dst++ = src[1];
*dst++ = *src++;
src++;
}
}
}
/*
* msvcrt.dll thread functions
*
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/*********************************************************************
* _beginthreadex (MSVCRT.@)
*/
unsigned long __cdecl MSVCRT__beginthreadex(void *sec,
unsigned int stack,
LPTHREAD_START_ROUTINE start,
void *arg, unsigned flag,
unsigned int*addr)
{
TRACE("(%p,%d,%p,%p,%d,%p)\n",sec, stack,start, arg,flag,addr);
/* FIXME */
return CreateThread( sec, stack, (LPTHREAD_START_ROUTINE)start, arg,flag,(LPDWORD)addr);
}
/*********************************************************************
* _endthreadex (MSVCRT.@)
*/
void __cdecl MSVCRT__endthreadex(unsigned int retval)
{
TRACE("(%d)\n",retval);
/* FIXME */
ExitThread(retval);
}
/*
* msvcrt.dll date/time functions
*
* Copyright 1996,1998 Marcus Meissner
* Copyright 1996 Jukka Iivonen
* Copyright 1997,2000 Uwe Bonnes
* Copyright 2000 Jon Griffiths
*/
#include <time.h>
#include <sys/times.h>
#include "msvcrt.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef struct __MSVCRT_timeb
{
time_t time;
unsigned short millitm;
short timezone;
short dstflag;
} MSVCRT_timeb;
/* INTERNAL: Return formatted current time/date */
char * MSVCRT_get_current_time(char * out, const char * format)
{
static const time_t bad_time = (time_t)-1;
time_t t;
struct tm *_tm = NULL;
char *retval = NULL;
if (time(&t) != bad_time && (_tm = localtime(&t)) &&
strftime(out,9,format,_tm) == 8)
retval = out;
if (_tm)
MSVCRT_free(_tm);
return retval;
}
/**********************************************************************
* _strdate (MSVCRT.@)
*/
char * __cdecl MSVCRT__strdate (char * date)
{
return MSVCRT_get_current_time(date,"%m/%d/%y");
}
/*********************************************************************
* _strtime (MSVCRT.@)
*/
char * __cdecl MSVCRT__strtime (char * date)
{
return MSVCRT_get_current_time(date,"%H:%M:%S");
}
/*********************************************************************
* clock (MSVCRT.@)
*/
clock_t __cdecl MSVCRT_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 CLOCKS_PER_SEC,
* 10 holds only for Windows/Linux_i86)
*/
return 10*res;
}
/*********************************************************************
* difftime (MSVCRT.@)
*/
double __cdecl MSVCRT_difftime (time_t time1, time_t time2)
{
return (double)(time1 - time2);
}
/*********************************************************************
* time (MSVCRT.@)
*/
time_t __cdecl MSVCRT_time(time_t *buf)
{
time_t curtime = time(NULL);
return buf ? *buf = curtime : curtime;
}
/*********************************************************************
* _ftime (MSVCRT.@)
*/
void __cdecl MSVCRT__ftime (MSVCRT_timeb *buf)
{
buf->time = MSVCRT_time(NULL);
buf->millitm = 0; /* FIXME */
buf->timezone = 0;
buf->dstflag = 0;
}
/*
* msvcrt.dll wide-char functions
*
* Copyright 1999 Alexandre Julliard
* Copyright 2000 Jon Griffiths
*/
#include "msvcrt.h"
#include "winnls.h"
#include "wine/unicode.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
/* INTERNAL: MSVCRT_malloc() based wstrndup */
LPWSTR MSVCRT__wstrndup(LPCWSTR buf, unsigned int size)
{
WCHAR* ret;
unsigned int len = strlenW(buf), max_len;
max_len = size <= len? size : len + 1;
ret = MSVCRT_malloc(max_len * sizeof (WCHAR));
if (ret)
{
memcpy(ret,buf,max_len * sizeof (WCHAR));
ret[max_len] = 0;
}
return ret;
}
/*********************************************************************
* MSVCRT__wcsdup (MSVCRT.@)
*/
LPWSTR __cdecl MSVCRT__wcsdup( LPCWSTR str )
{
LPWSTR ret = NULL;
if (str)
{
int size = (strlenW(str) + 1) * sizeof(WCHAR);
ret = MSVCRT_malloc( size );
if (ret) memcpy( ret, str, size );
}
return ret;
}
/*********************************************************************
* MSVCRT__wcsicoll (MSVCRT.@)
*/
INT __cdecl MSVCRT__wcsicoll( LPCWSTR str1, LPCWSTR str2 )
{
/* FIXME: handle collates */
return strcmpiW( str1, str2 );
}
/*********************************************************************
* MSVCRT__wcsnset (MSVCRT.@)
*/
LPWSTR __cdecl MSVCRT__wcsnset( LPWSTR str, WCHAR c, INT n )
{
LPWSTR ret = str;
while ((n-- > 0) && *str) *str++ = c;
return ret;
}
/*********************************************************************
* MSVCRT__wcsrev (MSVCRT.@)
*/
LPWSTR __cdecl MSVCRT__wcsrev( LPWSTR str )
{
LPWSTR ret = str;
LPWSTR end = str + strlenW(str) - 1;
while (end > str)
{
WCHAR t = *end;
*end-- = *str;
*str++ = t;
}
return ret;
}
/*********************************************************************
* MSVCRT__wcsset (MSVCRT.@)
*/
LPWSTR __cdecl MSVCRT__wcsset( LPWSTR str, WCHAR c )
{
LPWSTR ret = str;
while (*str) *str++ = c;
return ret;
}
/*********************************************************************
* MSVCRT_wcscoll (MSVCRT.@)
*/
DWORD __cdecl MSVCRT_wcscoll( LPCWSTR str1, LPCWSTR str2 )
{
/* FIXME: handle collates */
return strcmpW( str1, str2 );
}
/*********************************************************************
* MSVCRT_wcspbrk (MSVCRT.@)
*/
LPWSTR __cdecl MSVCRT_wcspbrk( LPCWSTR str, LPCWSTR accept )
{
LPCWSTR p;
while (*str)
{
for (p = accept; *p; p++) if (*p == *str) return (LPWSTR)str;
str++;
}
return NULL;
}
/*********************************************************************
* MSVCRT_wctomb (MSVCRT.@)
*/
INT __cdecl MSVCRT_wctomb( LPSTR dst, WCHAR ch )
{
return WideCharToMultiByte( CP_ACP, 0, &ch, 1, dst, 6, NULL, NULL );
}
/*********************************************************************
* MSVCRT_iswalnum (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswalnum( WCHAR wc )
{
return get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/*********************************************************************
* MSVCRT_iswalpha (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswalpha( WCHAR wc )
{
return get_char_typeW(wc) & (C1_ALPHA|C1_LOWER|C1_UPPER);
}
/*********************************************************************
* MSVCRT_iswcntrl (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswcntrl( WCHAR wc )
{
return get_char_typeW(wc) & C1_CNTRL;
}
/*********************************************************************
* MSVCRT_iswdigit (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswdigit( WCHAR wc )
{
return get_char_typeW(wc) & C1_DIGIT;
}
/*********************************************************************
* MSVCRT_iswgraph (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswgraph( WCHAR wc )
{
return get_char_typeW(wc) & (C1_ALPHA|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/*********************************************************************
* MSVCRT_iswlower (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswlower( WCHAR wc )
{
return get_char_typeW(wc) & C1_LOWER;
}
/*********************************************************************
* MSVCRT_iswprint (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswprint( WCHAR wc )
{
return get_char_typeW(wc) & (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
}
/*********************************************************************
* MSVCRT_iswpunct (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswpunct( WCHAR wc )
{
return get_char_typeW(wc) & C1_PUNCT;
}
/*********************************************************************
* MSVCRT_iswspace (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswspace( WCHAR wc )
{
return get_char_typeW(wc) & C1_SPACE;
}
/*********************************************************************
* MSVCRT_iswupper (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswupper( WCHAR wc )
{
return get_char_typeW(wc) & C1_UPPER;
}
/*********************************************************************
* MSVCRT_iswxdigit (MSVCRT.@)
*/
INT __cdecl MSVCRT_iswxdigit( WCHAR wc )
{
return get_char_typeW(wc) & C1_XDIGIT;
}
extern LPSTR __cdecl _itoa( long , LPSTR , INT);
extern LPSTR __cdecl _ultoa( long , LPSTR , INT);
extern LPSTR __cdecl _ltoa( long , LPSTR , INT);
/*********************************************************************
* _itow (MSVCRT.@)
*/
WCHAR* __cdecl MSVCRT__itow(int value,WCHAR* out,int base)
{
char buf[64];
_itoa(value, buf, base);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buf, -1, out, 128);
return out;
}
/*********************************************************************
* _ltow (MSVCRT.@)
*/
WCHAR* __cdecl MSVCRT__ltow(long value,WCHAR* out,int base)
{
char buf[128];
_ltoa(value, buf, base);
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, buf, -1, out, 128);
return out;
}
/*********************************************************************
* _ultow (MSVCRT.@)
*/
WCHAR* __cdecl MSVCRT__ultow(unsigned long value,WCHAR* out,int base)
{
char buf[128];
_ultoa(value, buf, base);
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, buf, -1, out, 128);
return out;
}
...@@ -93,6 +93,7 @@ WINE REGISTRY Version 2 ...@@ -93,6 +93,7 @@ WINE REGISTRY Version 2
"dsound" = "builtin, native" "dsound" = "builtin, native"
"mmsystem" = "builtin" "mmsystem" = "builtin"
"winmm" = "builtin" "winmm" = "builtin"
"msvcrt" = "native, builtin"
"msvideo" = "builtin, native" "msvideo" = "builtin, native"
"msvfw32" = "builtin, native" "msvfw32" = "builtin, native"
"mcicda.drv" = "builtin, native" "mcicda.drv" = "builtin, native"
......
...@@ -43,6 +43,7 @@ static struct tagDllOverride { ...@@ -43,6 +43,7 @@ static struct tagDllOverride {
{"advapi32,crtdll,ntdll", "builtin,native"}, {"advapi32,crtdll,ntdll", "builtin,native"},
{"lz32,lzexpand", "builtin,native"}, {"lz32,lzexpand", "builtin,native"},
{"version,ver", "builtin,native"}, {"version,ver", "builtin,native"},
{"msvcrt", "native,builtin"},
/* "new" interface */ /* "new" interface */
{"comdlg32,commdlg", "builtin,native"}, {"comdlg32,commdlg", "builtin,native"},
{"shell32,shell", "builtin,native"}, {"shell32,shell", "builtin,native"},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment