- Migrate CRTDLL to MSVCRT.
- Many fixes and a load of new functions.
This commit is contained in:
parent
ca43a641b7
commit
1db20bfd33
|
@ -45,6 +45,7 @@ Other DLLs:
|
|||
avifil32/ - COM object to play AVI files
|
||||
comctl32/ - common controls
|
||||
commdlg/ - common dialog boxes (both 16 & 32 bit)
|
||||
crtdll/ - Old C runtime library
|
||||
dplayx/ - DirectX dplayx
|
||||
dsound/ - DirectX dsound
|
||||
imagehlp/ - PE (Portable Executable) Image Helper lib
|
||||
|
@ -55,6 +56,7 @@ Other DLLs:
|
|||
msacm/ - audio compression manager (multimedia) (16 bit)
|
||||
msacm32/ - audio compression manager (multimedia) (32 bit)
|
||||
msnet/
|
||||
msvcrt/ - C runtime library
|
||||
msvideo/ - 16 bit video manager
|
||||
ole32/ - 32 bit OLE 2.0 librairies
|
||||
oleaut32/ - 32 bit OLE 2.0 automation
|
||||
|
|
|
@ -129,6 +129,7 @@ DLLS = \
|
|||
msacm.drv \
|
||||
msacm32 \
|
||||
msnet32 \
|
||||
msvcrt \
|
||||
msvfw32 \
|
||||
odbc32 \
|
||||
ole32 \
|
||||
|
|
|
@ -7000,6 +7000,7 @@ dlls/lzexpand/Makefile
|
|||
dlls/mpr/Makefile
|
||||
dlls/msacm/Makefile
|
||||
dlls/msnet32/Makefile
|
||||
dlls/msvcrt/Makefile
|
||||
dlls/msvideo/Makefile
|
||||
dlls/ntdll/Makefile
|
||||
dlls/odbc32/Makefile
|
||||
|
@ -7241,6 +7242,7 @@ dlls/lzexpand/Makefile
|
|||
dlls/mpr/Makefile
|
||||
dlls/msacm/Makefile
|
||||
dlls/msnet32/Makefile
|
||||
dlls/msvcrt/Makefile
|
||||
dlls/msvideo/Makefile
|
||||
dlls/ntdll/Makefile
|
||||
dlls/odbc32/Makefile
|
||||
|
|
|
@ -1200,6 +1200,7 @@ dlls/lzexpand/Makefile
|
|||
dlls/mpr/Makefile
|
||||
dlls/msacm/Makefile
|
||||
dlls/msnet32/Makefile
|
||||
dlls/msvcrt/Makefile
|
||||
dlls/msvideo/Makefile
|
||||
dlls/ntdll/Makefile
|
||||
dlls/odbc32/Makefile
|
||||
|
|
|
@ -32,6 +32,7 @@ DLLFILES = \
|
|||
mpr/libmpr.@LIBEXT@ \
|
||||
msacm/libmsacm32.@LIBEXT@ \
|
||||
msnet32/libmsnet32.@LIBEXT@ \
|
||||
msvcrt/libmsvcrt.@LIBEXT@ \
|
||||
msvideo/libmsvfw32.@LIBEXT@ \
|
||||
ntdll/libntdll.@LIBEXT@ \
|
||||
odbc32/libodbc32.@LIBEXT@ \
|
||||
|
@ -145,6 +146,7 @@ SUBDIRS = \
|
|||
mpr \
|
||||
msacm \
|
||||
msnet32 \
|
||||
msvcrt \
|
||||
msvideo \
|
||||
ntdll \
|
||||
odbc32 \
|
||||
|
@ -283,6 +285,9 @@ libmsacm32.@LIBEXT@ libmsacm.@LIBEXT@: msacm/libmsacm32.@LIBEXT@
|
|||
libmsnet32.@LIBEXT@: 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@
|
||||
$(RM) $@ && $(LN_S) msvideo/libmsvfw32.@LIBEXT@ $@
|
||||
|
||||
|
@ -418,6 +423,7 @@ lzexpand/liblz32.@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@
|
||||
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@
|
||||
odbc32/libodbc32.@LIBEXT@: libntdll.@LIBEXT@
|
||||
ole32/libole32.@LIBEXT@: libadvapi32.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ librpcrt4.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Makefile
|
||||
msvcrt.spec.c
|
|
@ -0,0 +1,36 @@
|
|||
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:
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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)));
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* 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 );
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* 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 */
|
||||
}
|
||||
|
|
@ -0,0 +1,729 @@
|
|||
/*
|
||||
* 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);
|
||||
|
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
* 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 */
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#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 */
|
|
@ -0,0 +1,43 @@
|
|||
#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 */
|
|
@ -0,0 +1,767 @@
|
|||
# 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
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* 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
|
|||
"dsound" = "builtin, native"
|
||||
"mmsystem" = "builtin"
|
||||
"winmm" = "builtin"
|
||||
"msvcrt" = "native, builtin"
|
||||
"msvideo" = "builtin, native"
|
||||
"msvfw32" = "builtin, native"
|
||||
"mcicda.drv" = "builtin, native"
|
||||
|
|
|
@ -43,6 +43,7 @@ static struct tagDllOverride {
|
|||
{"advapi32,crtdll,ntdll", "builtin,native"},
|
||||
{"lz32,lzexpand", "builtin,native"},
|
||||
{"version,ver", "builtin,native"},
|
||||
{"msvcrt", "native,builtin"},
|
||||
/* "new" interface */
|
||||
{"comdlg32,commdlg", "builtin,native"},
|
||||
{"shell32,shell", "builtin,native"},
|
||||
|
|
Loading…
Reference in New Issue