mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 13:45:06 +00:00
Samuel Serapión (samdwise51 AT gmail DOT com):
- Sync parts of msvcrt with Wine (more will follow) This makes us passing a lot more msvcrt Wine tests (like all heap tests) svn path=/trunk/; revision=33747
This commit is contained in:
parent
c6aa541df2
commit
1e95911991
File diff suppressed because it is too large
Load diff
|
@ -39,6 +39,7 @@
|
|||
</directory>
|
||||
<directory name="except">
|
||||
<file>abnorter.c</file>
|
||||
<file>checkesp.c</file>
|
||||
<file>cpp.c</file>
|
||||
<file>cppexcept.c</file>
|
||||
<file>matherr.c</file>
|
||||
|
@ -416,6 +417,7 @@
|
|||
<file>wcsnlen.c</file>
|
||||
<file>wcsrchr.c</file>
|
||||
</ifnot>
|
||||
<file>atol.c</file>
|
||||
<file>atof.c</file>
|
||||
<file>ctype.c</file>
|
||||
<file>lasttok.c</file>
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "wine/debug.h"
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <internal/wine/msvcrt.h>
|
||||
#include <internal/wine/cppexcept.h>
|
||||
|
|
|
@ -1,15 +1,106 @@
|
|||
#include <precomp.h>
|
||||
#include "include/internal/wine/msvcrt.h"
|
||||
#include "include/internal/wine/cppexcept.h"
|
||||
|
||||
typedef void (*sighandler_t)(int);
|
||||
static sighandler_t sighandlers[NSIG] = { SIG_DFL };
|
||||
|
||||
/* The exception codes are actually NTSTATUS values */
|
||||
static const struct
|
||||
{
|
||||
NTSTATUS status;
|
||||
int signal;
|
||||
} float_exception_map[] = {
|
||||
{ EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
|
||||
{ EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
|
||||
{ EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
|
||||
{ EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
|
||||
{ EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
|
||||
{ EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
|
||||
{ EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
|
||||
};
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
int
|
||||
_XcptFilter(DWORD ExceptionCode,
|
||||
struct _EXCEPTION_POINTERS * ExceptionInfo)
|
||||
struct _EXCEPTION_POINTERS * except)
|
||||
{
|
||||
//fixme XcptFilter
|
||||
// return UnhandledExceptionFilter(ExceptionInfo);
|
||||
return 0;
|
||||
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
||||
sighandler_t handler;
|
||||
|
||||
if (!except || !except->ExceptionRecord)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
switch (except->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
if ((handler = sighandlers[SIGSEGV]) != SIG_DFL)
|
||||
{
|
||||
if (handler != SIG_IGN)
|
||||
{
|
||||
sighandlers[SIGSEGV] = SIG_DFL;
|
||||
handler(SIGSEGV);
|
||||
}
|
||||
ret = EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
break;
|
||||
/* According to msdn,
|
||||
* the FPE signal handler takes as a second argument the type of
|
||||
* floating point exception.
|
||||
*/
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
|
||||
{
|
||||
if (handler != SIG_IGN)
|
||||
{
|
||||
int i, float_signal = _FPE_INVALID;
|
||||
|
||||
sighandlers[SIGFPE] = SIG_DFL;
|
||||
for (i = 0; i < sizeof(float_exception_map) /
|
||||
sizeof(float_exception_map[0]); i++)
|
||||
{
|
||||
if (float_exception_map[i].status ==
|
||||
except->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
float_signal = float_exception_map[i].signal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
((float_handler)handler)(SIGFPE, float_signal);
|
||||
}
|
||||
ret = EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
if ((handler = sighandlers[SIGILL]) != SIG_DFL)
|
||||
{
|
||||
if (handler != SIG_IGN)
|
||||
{
|
||||
sighandlers[SIGILL] = SIG_DFL;
|
||||
handler(SIGILL);
|
||||
}
|
||||
ret = EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
|
||||
{
|
||||
/* only filter c++ exceptions */
|
||||
if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
|
||||
return _XcptFilter( ex, ptr );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -138,8 +138,8 @@ void _CxxThrowException(exception*,const cxx_exception_type*);
|
|||
static inline const char *dbgstr_type_info( const type_info *info )
|
||||
{
|
||||
if (!info) return "{}";
|
||||
return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}",
|
||||
info->vtable, info->mangled, info->name ? info->name : "" );
|
||||
return "{}";/*sprintf( "{vtable=%p name=%s (%s)}",
|
||||
info->vtable, info->mangled, info->name ? info->name : "" );*/
|
||||
}
|
||||
|
||||
/* compute the this pointer for a base class of a given type */
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "float.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
|
||||
//#include "msvcrt/string.h"
|
||||
#include "eh.h"
|
||||
|
||||
typedef unsigned short MSVCRT_wchar_t;
|
||||
|
@ -132,6 +134,9 @@ extern void msvcrt_free_console(void);
|
|||
extern void msvcrt_init_args(void);
|
||||
extern void msvcrt_free_args(void);
|
||||
|
||||
#define MSVCRT__OUT_TO_DEFAULT 0
|
||||
#define MSVCRT__REPORT_ERRMODE 3
|
||||
|
||||
/* run-time error codes */
|
||||
#define _RT_STACK 0
|
||||
#define _RT_NULLPTR 1
|
||||
|
@ -183,6 +188,17 @@ struct MSVCRT___JUMP_BUFFER {
|
|||
};
|
||||
#endif /* __i386__ */
|
||||
|
||||
typedef void (*float_handler)(int, int);
|
||||
|
||||
void _default_handler(int signal);
|
||||
|
||||
typedef struct _sig_element
|
||||
{
|
||||
int signal;
|
||||
char *signame;
|
||||
__p_sig_fn_t handler;
|
||||
}sig_element;
|
||||
|
||||
typedef void* (*malloc_func_t)(size_t);
|
||||
typedef void (*free_func_t)(void*);
|
||||
#define MSVCRT_malloc malloc
|
||||
|
|
|
@ -724,3 +724,8 @@ int __crtLCMapStringA(
|
|||
*/
|
||||
return LCMapStringA(lcid,mapflags,src,srclen,dst,dstlen);
|
||||
}
|
||||
|
||||
int CDECL _getmbcp(void)
|
||||
{
|
||||
return MSVCRT___lc_codepage;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <math.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
||||
double _CIsin(double x);
|
||||
double _CIcos(double x);
|
||||
|
@ -131,3 +131,89 @@ double _CIfmod(double x, double y)
|
|||
{
|
||||
return fmod(x, y);
|
||||
}
|
||||
|
||||
/* The following functions are likely workarounds for the pentium fdiv bug */
|
||||
void __stdcall _adj_fdiv_m32( unsigned int arg )
|
||||
{
|
||||
DPRINT("_adj_fdiv_m32 stub\n");
|
||||
}
|
||||
void __stdcall _adj_fdiv_m32i( int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdiv_m32i stub\n");
|
||||
}
|
||||
|
||||
void __stdcall _adj_fdiv_m64( unsigned __int64 arg )
|
||||
{
|
||||
DPRINT1("_adj_fdiv_m64 stub\n");
|
||||
}
|
||||
|
||||
void _adj_fdiv_r(void)
|
||||
{
|
||||
DPRINT1("_adj_fdiv_r stub\n");
|
||||
}
|
||||
|
||||
void __stdcall _adj_fdivr_m32( unsigned int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdivr_m32i stub\n");
|
||||
}
|
||||
|
||||
void __stdcall _adj_fdivr_m32i( int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdivr_m32i stub\n");
|
||||
}
|
||||
|
||||
void __stdcall _adj_fdivr_m64( unsigned __int64 arg )
|
||||
{
|
||||
DPRINT1("_adj_fdivr_m64 stub\n");
|
||||
}
|
||||
|
||||
void _adj_fpatan(void)
|
||||
{
|
||||
DPRINT1("_adj_fpatan stub\n");
|
||||
}
|
||||
|
||||
void __stdcall _adj_fdiv_m16i( short arg )
|
||||
{
|
||||
DPRINT("_adj_fdiv_m16i stub\n");
|
||||
}
|
||||
|
||||
void __stdcall _adj_fdivr_m16i( short arg )
|
||||
{
|
||||
DPRINT("_adj_fdivr_m16i stub\n");
|
||||
}
|
||||
|
||||
void _adj_fprem(void)
|
||||
{
|
||||
DPRINT("_adj_fprem stub\n");
|
||||
}
|
||||
|
||||
void _adj_fprem1(void)
|
||||
{
|
||||
DPRINT("_adj_fprem1 stub\n");
|
||||
}
|
||||
|
||||
void _adj_fptan(void)
|
||||
{
|
||||
DPRINT("_adj_fptan stub\n");
|
||||
}
|
||||
|
||||
void _safe_fdiv(void)
|
||||
{
|
||||
DPRINT("_safe_fdiv stub\n");
|
||||
}
|
||||
|
||||
void _safe_fdivr(void)
|
||||
{
|
||||
DPRINT("_safe_fdivr stub\n");
|
||||
}
|
||||
|
||||
void _safe_fprem(void)
|
||||
{
|
||||
DPRINT("_safe_fprem stub\n");
|
||||
}
|
||||
|
||||
void _safe_fprem1(void)
|
||||
{
|
||||
DPRINT("_safe_fprem1 stub\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -133,3 +133,23 @@ int _ismbcl2(unsigned int c)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
int _ismbcgraph(unsigned int ch)
|
||||
{
|
||||
//wchar_t wch = msvcrt_mbc_to_wc( ch );
|
||||
//return (get_char_typeW( wch ) & (C1_UPPER | C1_LOWER | C1_DIGIT | C1_PUNCT | C1_ALPHA));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
int _ismbcpunct(unsigned int ch)
|
||||
{
|
||||
//wchar_t wch = msvcrt_mbc_to_wc( ch );
|
||||
//return (get_char_typeW( wch ) & C1_PUNCT);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -64,3 +64,11 @@ int _ismbslead( const unsigned char *str, const unsigned char *t)
|
|||
return _ismbblead( *s);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
unsigned char *__p__mbctype(void)
|
||||
{
|
||||
return _mbctype;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
int __STRINGTOLD( long double *value, char **endptr, const char *str, int flags )
|
||||
{
|
||||
DPRINT1("%p %p %s %x stub\n", value, endptr, str, flags );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* $I10_OUTPUT (MSVCRT.@)
|
||||
* Function not really understood but needed to make the DLL work
|
||||
|
@ -12,127 +18,11 @@ void MSVCRT_I10_OUTPUT(void)
|
|||
/* FIXME: This is probably data, not a function */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdiv_m32 (MSVCRT.@)
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void __stdcall _adj_fdiv_m32( unsigned int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdiv_m32 stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdiv_m32i (MSVCRT.@)
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void __stdcall _adj_fdiv_m32i( int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdiv_m32i stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdiv_m64 (MSVCRT.@)
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void __stdcall _adj_fdiv_m64( unsigned __int64 arg )
|
||||
{
|
||||
DPRINT1("_adj_fdiv_m64 stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdiv_r (MSVCRT.@)
|
||||
* FIXME
|
||||
* This function is likely to have the wrong number of arguments.
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void _adj_fdiv_r(void)
|
||||
{
|
||||
DPRINT1("_adj_fdiv_r stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdivr_m32 (MSVCRT.@)
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void __stdcall _adj_fdivr_m32( unsigned int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdivr_m32i stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdivr_m32i (MSVCRT.@)
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void __stdcall _adj_fdivr_m32i( int arg )
|
||||
{
|
||||
DPRINT1("_adj_fdivr_m32i stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fdivr_m64 (MSVCRT.@)
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void __stdcall _adj_fdivr_m64( unsigned __int64 arg )
|
||||
{
|
||||
DPRINT1("_adj_fdivr_m64 stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* _adj_fpatan (MSVCRT.@)
|
||||
* FIXME
|
||||
* This function is likely to have the wrong number of arguments.
|
||||
*
|
||||
* NOTE
|
||||
* I _think_ this function is intended to work around the Pentium
|
||||
* fdiv bug.
|
||||
*/
|
||||
void _adj_fpatan(void)
|
||||
{
|
||||
DPRINT1("_adj_fpatan stub\n");
|
||||
}
|
||||
|
||||
|
||||
void __crtCompareStringA(void)
|
||||
{
|
||||
DPRINT1("__crtCompareStringA stub\n");
|
||||
}
|
||||
|
||||
void __crtGetLocaleInfoW(void)
|
||||
{
|
||||
DPRINT1("__crtGetLocaleInfoW stub\n");
|
||||
}
|
||||
|
||||
void __p__amblksiz(void)
|
||||
{
|
||||
DPRINT1("__p__amblksiz stub\n");
|
||||
}
|
||||
|
||||
void __p__dstbias(void)
|
||||
{
|
||||
DPRINT1("__p__dstbias stub\n");
|
||||
}
|
||||
|
||||
void __fileinfo(void)
|
||||
{
|
||||
DPRINT1("__fileinfo stub\n");
|
||||
|
@ -142,3 +32,26 @@ void stub(void)
|
|||
{
|
||||
DPRINT1("stub\n");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _getmaxstdio (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _getmaxstdio(void)
|
||||
{
|
||||
DPRINT1("stub, always returns 512\n");
|
||||
return 512;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _setmaxstdio_ (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _setmaxstdio(int newmax)
|
||||
{
|
||||
int res;
|
||||
if( newmax > 2048)
|
||||
res = -1;
|
||||
else
|
||||
res = newmax;
|
||||
DPRINT1("stub: setting new maximum for number of simultaneously open files not implemented,returning %d\n",res);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <string.h>
|
||||
#include <process.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include<internal/debug.h>
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -112,3 +114,9 @@ int system(const char *command)
|
|||
|
||||
return nStatus;
|
||||
}
|
||||
|
||||
int CDECL _wsystem(const wchar_t* cmd)
|
||||
{
|
||||
DPRINT1("_wsystem stub\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,5 @@
|
|||
#include <precomp.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void _default_handler(int signal);
|
||||
|
||||
typedef struct _sig_element
|
||||
{
|
||||
int signal;
|
||||
char *signame;
|
||||
__p_sig_fn_t handler;
|
||||
}
|
||||
sig_element;
|
||||
|
||||
#include "include/internal/wine/msvcrt.h"
|
||||
|
||||
static sig_element signal_list[] =
|
||||
{
|
||||
|
@ -34,8 +20,6 @@ static sig_element signal_list[] =
|
|||
//void ( *signal( int sig, void (__cdecl *func) ( int sig [, int subcode ] )) ) ( int sig );
|
||||
|
||||
|
||||
|
||||
|
||||
__p_sig_fn_t signal(int sig, __p_sig_fn_t func)
|
||||
{
|
||||
__p_sig_fn_t temp;
|
||||
|
@ -139,3 +123,6 @@ void _default_handler(int sig)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
#include <precomp.h>
|
||||
#include "doserrmap.h"
|
||||
#include <internal/wine/msvcrt.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
@ -71,4 +72,40 @@ void _dosmaperr(unsigned long oserror)
|
|||
__set_errno(EINVAL);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* _set_error_mode (MSVCRT.@)
|
||||
*
|
||||
* Set the error mode, which describes where the C run-time writes error
|
||||
* messages.
|
||||
*
|
||||
* PARAMS
|
||||
* mode - the new error mode
|
||||
*
|
||||
* RETURNS
|
||||
* The old error mode.
|
||||
*
|
||||
* TODO
|
||||
* This function does not have a proper implementation; the error mode is
|
||||
* never used.
|
||||
*/
|
||||
int CDECL _set_error_mode(int mode)
|
||||
{
|
||||
static int current_mode = MSVCRT__OUT_TO_DEFAULT;
|
||||
|
||||
const int old = current_mode;
|
||||
if ( MSVCRT__REPORT_ERRMODE != mode ) {
|
||||
current_mode = mode;
|
||||
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* _seterrormode (MSVCRT.@)
|
||||
*/
|
||||
void CDECL _seterrormode(int mode)
|
||||
{
|
||||
SetErrorMode( mode );
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -5,15 +5,6 @@
|
|||
unsigned char _cpumode = 0;
|
||||
unsigned char *_cpumode_dll = &_cpumode;
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
void _seterrormode(int nMode)
|
||||
{
|
||||
SetErrorMode(nMode);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -10,3 +10,10 @@ _ttol(const _TCHAR *str)
|
|||
{
|
||||
return _tcstol(str, 0, 10);
|
||||
}
|
||||
|
||||
int _atoldbl(long double *value, const char *str)
|
||||
{
|
||||
/* FIXME needs error checking for huge/small values */
|
||||
//*value = strtold(str,0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <precomp.h>
|
||||
#include <sys/stat.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
@ -78,3 +80,9 @@ int _fstati64(int fd, struct _stati64* statbuf)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _fstat64(int fd, struct __stat64* buf)
|
||||
{
|
||||
DPRINT1("stub\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
|
||||
#include <precomp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <direct.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* for stat mode, permissions apply to all,owner and group */
|
||||
#define ALL_S_IREAD (S_IREAD | (S_IREAD >> 3) | (S_IREAD >> 6))
|
||||
#define ALL_S_IWRITE (S_IWRITE | (S_IWRITE >> 3) | (S_IWRITE >> 6))
|
||||
#define ALL_S_IEXEC (S_IEXEC | (S_IEXEC >> 3) | (S_IEXEC >> 6))
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
@ -118,3 +127,69 @@ int _stati64 (const char *path, struct _stati64 *buffer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _stat64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _stat64(const char* path, struct __stat64 * buf)
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
DPRINT1("failed (%d)\n",GetLastError());
|
||||
*_errno() = ERROR_FILE_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
memset(buf,0,sizeof(struct __stat64));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs say-what is it?
|
||||
Bon 011120: This FIXME seems incorrect
|
||||
Also a letter as first char isn't enough to be classified
|
||||
as a drive letter
|
||||
*/
|
||||
if (isalpha(*path)&& (*(path+1)==':'))
|
||||
buf->st_dev = buf->st_rdev = toupper(*path) - 'A'; /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
plen = strlen(path);
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
char* ext = strrchr(path, '.');
|
||||
if (ext && (!_stricmp(ext, ".exe") || !_stricmp(ext, ".com") || !_stricmp(ext, ".bat") ||
|
||||
!_stricmp(ext, ".cmd")))
|
||||
mode |= S_IEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
|
||||
DPRINT("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 32),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
|
||||
#include <precomp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <wchar.h>
|
||||
#include <direct.h>
|
||||
|
||||
/* for stat mode, permissions apply to all,owner and group */
|
||||
#define ALL_S_IREAD (S_IREAD | (S_IREAD >> 3) | (S_IREAD >> 6))
|
||||
#define ALL_S_IWRITE (S_IWRITE | (S_IWRITE >> 3) | (S_IWRITE >> 6))
|
||||
#define ALL_S_IEXEC (S_IEXEC | (S_IEXEC >> 3) | (S_IEXEC >> 6))
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
@ -117,3 +124,61 @@ int _wstati64 (const wchar_t *path, struct _stati64 *buffer)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _wstat64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _wstat64(const wchar_t* path, struct __stat64 * buf)
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
if (!GetFileAttributesExW(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(struct __stat64));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs says-what is it? */
|
||||
if (iswalpha(*path))
|
||||
buf->st_dev = buf->st_rdev = towupper(*path - 'A'); /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
plen = wcslen(path);
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
|
||||
{
|
||||
wchar_t* ext = wcsrchr(path, L'.');
|
||||
if (ext && (!_wcsicmp(ext, L".exe") || !_wcsicmp(ext, L".com") ||
|
||||
!_wcsicmp(ext, L".bat") || !_wcsicmp(ext, L".cmd")))
|
||||
mode |= S_IEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1436,3 +1436,25 @@ mktime(struct tm * tmp)
|
|||
{
|
||||
return time1(tmp, localsub, 0L);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
char **
|
||||
__p__tzname(void)
|
||||
{
|
||||
return _tzname;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _dstbias (MSVCRT.@)
|
||||
*/
|
||||
int _dstbias = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* __p_dstbias (MSVCRT.@)
|
||||
*/
|
||||
int * __p__dstbias(void)
|
||||
{
|
||||
return &_dstbias;
|
||||
}
|
||||
|
|
|
@ -34,12 +34,20 @@
|
|||
#define LOCK_HEAP _mlock( _HEAP_LOCK )
|
||||
#define UNLOCK_HEAP _munlock( _HEAP_LOCK )
|
||||
|
||||
/* _aligned */
|
||||
#define SAVED_PTR(x) ((void *)((DWORD_PTR)((char *)x - sizeof(void *)) & \
|
||||
~(sizeof(void *) - 1)))
|
||||
#define ALIGN_PTR(ptr, alignment, offset) ((void *) \
|
||||
((((DWORD_PTR)((char *)ptr + alignment + sizeof(void *) + offset)) & \
|
||||
~(alignment - 1)) - offset))
|
||||
|
||||
typedef void (*MSVCRT_new_handler_func)(unsigned long size);
|
||||
|
||||
static MSVCRT_new_handler_func MSVCRT_new_handler;
|
||||
static int MSVCRT_new_mode;
|
||||
|
||||
/* FIXME - According to documentation it should be 480 bytes, at runtime default is 0 */
|
||||
static size_t MSVCRT_sbh_threshold = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* ??2@YAPAXI@Z (MSVCRT.@)
|
||||
|
@ -118,6 +126,33 @@ int MSVCRT__set_new_mode(int mode)
|
|||
return old_mode;
|
||||
}
|
||||
|
||||
int CDECL _callnewh(unsigned long size)
|
||||
{
|
||||
if(MSVCRT_new_handler)
|
||||
(*MSVCRT_new_handler)(size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _get_sbh_threshold (MSVCRT.@)
|
||||
*/
|
||||
size_t CDECL _get_sbh_threshold(void)
|
||||
{
|
||||
return MSVCRT_sbh_threshold;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _set_sbh_threshold (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _set_sbh_threshold(size_t threshold)
|
||||
{
|
||||
if(threshold > 1016)
|
||||
return 0;
|
||||
else
|
||||
MSVCRT_sbh_threshold = threshold;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _heapadd (MSVCRT.@)
|
||||
*/
|
||||
|
@ -127,3 +162,175 @@ int _heapadd(void* mem, size_t size)
|
|||
*_errno() = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CDECL _aligned_free(void *memblock)
|
||||
{
|
||||
if (memblock)
|
||||
{
|
||||
void **saved = SAVED_PTR(memblock);
|
||||
free(*saved);
|
||||
}
|
||||
}
|
||||
|
||||
void * CDECL _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
void *memblock, *temp, **saved;
|
||||
|
||||
/* alignment must be a power of 2 */
|
||||
if ((alignment & (alignment - 1)) != 0)
|
||||
{
|
||||
*_errno() = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* offset must be less than size */
|
||||
if (offset >= size)
|
||||
{
|
||||
*_errno() = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* don't align to less than void pointer size */
|
||||
if (alignment < sizeof(void *))
|
||||
alignment = sizeof(void *);
|
||||
|
||||
/* allocate enough space for void pointer and alignment */
|
||||
temp = malloc(size + alignment + sizeof(void *));
|
||||
|
||||
if (!temp)
|
||||
return NULL;
|
||||
|
||||
/* adjust pointer for proper alignment and offset */
|
||||
memblock = ALIGN_PTR(temp, alignment, offset);
|
||||
|
||||
/* Save the real allocation address below returned address */
|
||||
/* so it can be found later to free. */
|
||||
saved = SAVED_PTR(memblock);
|
||||
*saved = temp;
|
||||
|
||||
return memblock;
|
||||
}
|
||||
|
||||
void * CDECL _aligned_malloc(size_t size, size_t alignment)
|
||||
{
|
||||
return _aligned_offset_malloc(size, alignment, 0);
|
||||
}
|
||||
|
||||
void * CDECL _aligned_offset_realloc(void *memblock, size_t size,
|
||||
size_t alignment, size_t offset)
|
||||
{
|
||||
void * temp, **saved;
|
||||
size_t old_padding, new_padding, old_size;
|
||||
|
||||
if (!memblock)
|
||||
return _aligned_offset_malloc(size, alignment, offset);
|
||||
|
||||
/* alignment must be a power of 2 */
|
||||
if ((alignment & (alignment - 1)) != 0)
|
||||
{
|
||||
*_errno() = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* offset must be less than size */
|
||||
if (offset >= size)
|
||||
{
|
||||
*_errno() = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
_aligned_free(memblock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* don't align to less than void pointer size */
|
||||
if (alignment < sizeof(void *))
|
||||
alignment = sizeof(void *);
|
||||
|
||||
/* make sure alignment and offset didn't change */
|
||||
saved = SAVED_PTR(memblock);
|
||||
|
||||
if (memblock != ALIGN_PTR(*saved, alignment, offset))
|
||||
{
|
||||
*_errno() = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old_padding = (char *)memblock - (char *)*saved;
|
||||
|
||||
/* Get previous size of block */
|
||||
old_size = _msize(*saved);
|
||||
if (old_size == -1)
|
||||
{
|
||||
/* It seems this function was called with an invalid pointer. Bail out. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Adjust old_size to get amount of actual data in old block. */
|
||||
if (old_size < old_padding)
|
||||
{
|
||||
/* Shouldn't happen. Something's weird, so bail out. */
|
||||
return NULL;
|
||||
}
|
||||
old_size -= old_padding;
|
||||
|
||||
temp = realloc(*saved, size + alignment + sizeof(void *));
|
||||
|
||||
if (!temp)
|
||||
return NULL;
|
||||
|
||||
/* adjust pointer for proper alignment and offset */
|
||||
memblock = ALIGN_PTR(temp, alignment, offset);
|
||||
|
||||
/* Save the real allocation address below returned address */
|
||||
/* so it can be found later to free. */
|
||||
saved = SAVED_PTR(memblock);
|
||||
|
||||
new_padding = (char *)memblock - (char *)temp;
|
||||
|
||||
/*
|
||||
Memory layout of old block is as follows:
|
||||
+-------+---------------------+-+--------------------------+-----------+
|
||||
| ... | "old_padding" bytes | | ... "old_size" bytes ... | ... |
|
||||
+-------+---------------------+-+--------------------------+-----------+
|
||||
^ ^ ^
|
||||
| | |
|
||||
*saved saved memblock
|
||||
|
||||
|
||||
Memory layout of new block is as follows:
|
||||
+-------+-----------------------------+-+----------------------+-------+
|
||||
| ... | "new_padding" bytes | | ... "size" bytes ... | ... |
|
||||
+-------+-----------------------------+-+----------------------+-------+
|
||||
^ ^ ^
|
||||
| | |
|
||||
temp saved memblock
|
||||
|
||||
However, in the new block, actual data is still written as follows
|
||||
(because it was copied by MSVCRT_realloc):
|
||||
+-------+---------------------+--------------------------------+-------+
|
||||
| ... | "old_padding" bytes | ... "old_size" bytes ... | ... |
|
||||
+-------+---------------------+--------------------------------+-------+
|
||||
^ ^ ^
|
||||
| | |
|
||||
temp saved memblock
|
||||
|
||||
Therefore, min(old_size,size) bytes of actual data have to be moved
|
||||
from the offset they were at in the old block (temp + old_padding),
|
||||
to the offset they have to be in the new block (temp + new_padding == memblock).
|
||||
*/
|
||||
|
||||
if (new_padding != old_padding)
|
||||
memmove((char *)memblock, (char *)temp + old_padding, (old_size < size) ? old_size : size);
|
||||
|
||||
*saved = temp;
|
||||
|
||||
return memblock;
|
||||
}
|
||||
|
||||
void * CDECL _aligned_realloc(void *memblock, size_t size, size_t alignment)
|
||||
{
|
||||
return _aligned_offset_realloc(memblock, size, alignment, 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue