diff --git a/reactos/dll/win32/crtdll/crtdll.rbuild b/reactos/dll/win32/crtdll/crtdll.rbuild index 17e9b22ecc4..97a72f59390 100644 --- a/reactos/dll/win32/crtdll/crtdll.rbuild +++ b/reactos/dll/win32/crtdll/crtdll.rbuild @@ -18,6 +18,7 @@ "extern __attribute__ ((dllexport))" crt + wine kernel32 ntdll precomp.h diff --git a/reactos/dll/win32/crtdll/dllmain.c b/reactos/dll/win32/crtdll/dllmain.c index 0481162b9ea..4f41f358e26 100644 --- a/reactos/dll/win32/crtdll/dllmain.c +++ b/reactos/dll/win32/crtdll/dllmain.c @@ -23,9 +23,11 @@ #include #include #include +#include +#include -#define NDEBUG -#include +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(crtdll); /* EXTERNAL PROTOTYPES ********************************************************/ @@ -114,7 +116,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) { case DLL_PROCESS_ATTACH://1 /* initialize version info */ - DPRINT("Attach %d\n", nAttachCount); + //TRACE("Attach %d\n", nAttachCount); _osver = GetVersion(); @@ -157,8 +159,10 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* FIXME: Initialization of the WINE code */ msvcrt_init_mt_locks(); + setlocale(0, "C"); + //_setmbcp(_MB_CP_LOCALE); - DPRINT("Attach done\n"); + TRACE("Attach done\n"); break; case DLL_THREAD_ATTACH://2 @@ -169,7 +173,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) break; case DLL_PROCESS_DETACH://0 - DPRINT("Detach %d\n", nAttachCount); + //TRACE("Detach %d\n", nAttachCount); /* FIXME: more cleanup... */ _fcloseall(); _atexit_cleanup(); @@ -190,7 +194,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* destroy heap */ HeapDestroy(hHeap); - DPRINT("Detach done\n"); + TRACE("Detach done\n"); break; } diff --git a/reactos/dll/win32/msvcrt/dllmain.c b/reactos/dll/win32/msvcrt/dllmain.c index 34907715ba7..ca835f2612a 100644 --- a/reactos/dll/win32/msvcrt/dllmain.c +++ b/reactos/dll/win32/msvcrt/dllmain.c @@ -22,10 +22,11 @@ #include #include +#include +#include -#define NDEBUG -#include - +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); /* EXTERNAL PROTOTYPES ********************************************************/ @@ -96,20 +97,22 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* FIXME: more initializations... */ - /* FIXME: Initialization of the WINE code */ + /* Initialization of the WINE code */ msvcrt_init_mt_locks(); + setlocale(0, "C"); + //_setmbcp(_MB_CP_LOCALE); - DPRINT("Attach done\n"); + TRACE("Attach done\n"); break; - case DLL_THREAD_ATTACH://2 + case DLL_THREAD_ATTACH: break; - case DLL_THREAD_DETACH://4 + case DLL_THREAD_DETACH: FreeThreadData(NULL); break; - case DLL_PROCESS_DETACH://0 + case DLL_PROCESS_DETACH: //DPRINT1("Detach %d\n", nAttachCount); //DPRINT("Detach\n"); /* FIXME: more cleanup... */ @@ -132,7 +135,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* destroy heap */ HeapDestroy(hHeap); - DPRINT("Detach done\n"); + TRACE("Detach done\n"); break; } diff --git a/reactos/dll/win32/msvcrt/msvcrt.rbuild b/reactos/dll/win32/msvcrt/msvcrt.rbuild index 4f243255bbe..75af5b3e4f5 100644 --- a/reactos/dll/win32/msvcrt/msvcrt.rbuild +++ b/reactos/dll/win32/msvcrt/msvcrt.rbuild @@ -26,6 +26,5 @@ ntdll precomp.h dllmain.c - stubs.c msvcrt.rc diff --git a/reactos/dll/win32/msvcrt/stubs.c b/reactos/dll/win32/msvcrt/stubs.c deleted file mode 100644 index 1dc017f3f65..00000000000 --- a/reactos/dll/win32/msvcrt/stubs.c +++ /dev/null @@ -1,95 +0,0 @@ -/* File generated automatically from dll\win32\msvcrt\msvcrt.spec; do not edit! */ -/* This file can be copied, modified and distributed without restriction. */ - -#include -#include "windef.h" -#include "winbase.h" -#include "wine/config.h" -#include "wine/exception.h" - -void __wine_spec_unimplemented_stub( const char *module, const char *function ) -{ - ULONG_PTR args[2]; - - args[0] = (ULONG_PTR)module; - args[1] = (ULONG_PTR)function; - RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args ); -} - -static const char __wine_spec_file_name[] = "msvcrt.dll"; - -void __wine_stub_msvcrt_dll_81(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__STRINGTOLD"); } -void __wine_stub_msvcrt_dll_86(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__crtCompareStringW"); } -void __wine_stub_msvcrt_dll_92(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__get_app_type"); } -void __wine_stub_msvcrt_dll_99(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__lc_collate"); } -void __wine_stub_msvcrt_dll_116(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__p__fileinfo"); } -void __wine_stub_msvcrt_dll_119(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__p__mbcasemap"); } -void __wine_stub_msvcrt_dll_124(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__p__pwctype"); } -void __wine_stub_msvcrt_dll_134(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "__pxcptinfoptrs"); } -void __wine_stub_msvcrt_dll_150(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_adj_fdiv_m16i"); } -void __wine_stub_msvcrt_dll_155(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_adj_fdivr_m16i"); } -void __wine_stub_msvcrt_dll_159(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_adj_fpatan"); } -void __wine_stub_msvcrt_dll_160(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_adj_fprem"); } -void __wine_stub_msvcrt_dll_161(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_adj_fprem1"); } -void __wine_stub_msvcrt_dll_162(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_adj_fptan"); } -void __wine_stub_msvcrt_dll_164(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_aligned_free"); } -void __wine_stub_msvcrt_dll_165(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_aligned_malloc"); } -void __wine_stub_msvcrt_dll_166(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_aligned_offset_malloc"); } -void __wine_stub_msvcrt_dll_167(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_aligned_offset_realloc"); } -void __wine_stub_msvcrt_dll_168(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_aligned_realloc"); } -void __wine_stub_msvcrt_dll_171(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_atodbl"); } -void __wine_stub_msvcrt_dll_173(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_atoldbl"); } -void __wine_stub_msvcrt_dll_179(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_callnewh"); } -void __wine_stub_msvcrt_dll_185(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_chkesp"); } -void __wine_stub_msvcrt_dll_202(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_dstbias"); } -void __wine_stub_msvcrt_dll_242(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_fpieee_flt"); } -void __wine_stub_msvcrt_dll_248(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_fstat64"); } -void __wine_stub_msvcrt_dll_256(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_get_sbh_threshold"); } -void __wine_stub_msvcrt_dll_257(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_get_terminate"); } -void __wine_stub_msvcrt_dll_258(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_get_unexpected"); } -void __wine_stub_msvcrt_dll_267(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_getmaxstdio"); } -void __wine_stub_msvcrt_dll_268(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_getmbcp"); } -void __wine_stub_msvcrt_dll_270(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_getsystime"); } -void __wine_stub_msvcrt_dll_278(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_heapused"); } -void __wine_stub_msvcrt_dll_284(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_inp"); } -void __wine_stub_msvcrt_dll_285(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_inpd"); } -void __wine_stub_msvcrt_dll_286(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_inpw"); } -void __wine_stub_msvcrt_dll_290(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbalnum"); } -void __wine_stub_msvcrt_dll_291(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbalpha"); } -void __wine_stub_msvcrt_dll_292(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbgraph"); } -void __wine_stub_msvcrt_dll_293(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbkalnum"); } -void __wine_stub_msvcrt_dll_295(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbkprint"); } -void __wine_stub_msvcrt_dll_296(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbkpunct"); } -void __wine_stub_msvcrt_dll_298(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbprint"); } -void __wine_stub_msvcrt_dll_299(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbbpunct"); } -void __wine_stub_msvcrt_dll_304(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbcgraph"); } -void __wine_stub_msvcrt_dll_307(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbcl0"); } -void __wine_stub_msvcrt_dll_308(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbcl1"); } -void __wine_stub_msvcrt_dll_309(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbcl2"); } -void __wine_stub_msvcrt_dll_310(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbclegal"); } -void __wine_stub_msvcrt_dll_313(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_ismbcpunct"); } -void __wine_stub_msvcrt_dll_332(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_longjmpex"); } -void __wine_stub_msvcrt_dll_341(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_matherr"); } -void __wine_stub_msvcrt_dll_373(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_mbsnbcpy_s"); } -void __wine_stub_msvcrt_dll_407(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_outp"); } -void __wine_stub_msvcrt_dll_408(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_outpd"); } -void __wine_stub_msvcrt_dll_409(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_outpw"); } -void __wine_stub_msvcrt_dll_425(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_safe_fdiv"); } -void __wine_stub_msvcrt_dll_426(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_safe_fdivr"); } -void __wine_stub_msvcrt_dll_427(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_safe_fprem"); } -void __wine_stub_msvcrt_dll_428(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_safe_fprem1"); } -void __wine_stub_msvcrt_dll_432(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_set_error_mode"); } -void __wine_stub_msvcrt_dll_433(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_set_sbh_threshold"); } -void __wine_stub_msvcrt_dll_437(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_setmaxstdio"); } -void __wine_stub_msvcrt_dll_455(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_stat64"); } -void __wine_stub_msvcrt_dll_542(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wperror"); } -void __wine_stub_msvcrt_dll_543(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wpgmptr"); } -void __wine_stub_msvcrt_dll_553(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wspawnl"); } -void __wine_stub_msvcrt_dll_554(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wspawnle"); } -void __wine_stub_msvcrt_dll_555(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wspawnlp"); } -void __wine_stub_msvcrt_dll_556(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wspawnlpe"); } -void __wine_stub_msvcrt_dll_564(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wstat64"); } -void __wine_stub_msvcrt_dll_567(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wsystem"); } -void __wine_stub_msvcrt_dll_569(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "_wtmpnam"); } -void __wine_stub_msvcrt_dll_709(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "strcat_s"); } -void __wine_stub_msvcrt_dll_714(void) { __wine_spec_unimplemented_stub(__wine_spec_file_name, "strcpy_s"); } diff --git a/reactos/lib/sdk/crt/crt.rbuild b/reactos/lib/sdk/crt/crt.rbuild index 6cb16dd0c3a..12b8df32cef 100644 --- a/reactos/lib/sdk/crt/crt.rbuild +++ b/reactos/lib/sdk/crt/crt.rbuild @@ -82,7 +82,7 @@ chsize.c close.c commit.c - create.c + creat.c dup.c dup2.c eof.c @@ -108,7 +108,7 @@ utime.c waccess.c wchmod.c - wcreate.c + wcreat.c wfind.c wmktemp.c wopen.c @@ -285,6 +285,7 @@ fgets.c fgetws.c filbuf.c + file.c fileno.c flsbuf.c fopen.c diff --git a/reactos/lib/sdk/crt/direct/chdrive.c b/reactos/lib/sdk/crt/direct/chdrive.c index 2730a617a45..309ad8fea39 100644 --- a/reactos/lib/sdk/crt/direct/chdrive.c +++ b/reactos/lib/sdk/crt/direct/chdrive.c @@ -1,9 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crt/?????? - * PURPOSE: Unknown - * PROGRAMER: Unknown + * FILE: lib/crt/chdrive.c + * PURPOSE: Change the current drive. + * PROGRAMER: WINE * UPDATE HISTORY: * 25/11/05: Added license header */ diff --git a/reactos/lib/sdk/crt/direct/getdcwd.c b/reactos/lib/sdk/crt/direct/getdcwd.c index baf6c5d182d..bab272cff4b 100644 --- a/reactos/lib/sdk/crt/direct/getdcwd.c +++ b/reactos/lib/sdk/crt/direct/getdcwd.c @@ -1,6 +1,5 @@ #include #include -#include #include /* @@ -60,3 +59,4 @@ _TCHAR* _tgetdcwd(int drive, _TCHAR * buf, int size) return buf; } + diff --git a/reactos/lib/sdk/crt/except/matherr.c b/reactos/lib/sdk/crt/except/matherr.c index 2684f1cb65a..da94b71ffc4 100644 --- a/reactos/lib/sdk/crt/except/matherr.c +++ b/reactos/lib/sdk/crt/except/matherr.c @@ -1,20 +1,51 @@ #include + +#define __USE_ISOC9X 1 +#define __USE_ISOC99 1 #include +#ifdef HAVE_IEEEFP_H +#include +#endif -int _matherr(struct _exception* e) +#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 + +typedef int (*MSVCRT_matherr_func)(struct _exception *); + +static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL; + +int CDECL _matherr(struct _exception *e) { - return 0; + 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; } -/* - * not exported by NTDLL - * - * @unimplemented +/********************************************************************* + * __setusermatherr (MSVCRT.@) */ -void __setusermatherr(int (*handler)(struct _exception*)) +void CDECL __setusermatherr(MSVCRT_matherr_func func) { - + MSVCRT_default_matherr_func = func; + TRACE(":new matherr handler %p\n", func); } @@ -29,5 +60,6 @@ int _fpieee_flt( int (*handler)(_FPIEEE_RECORD*) ) { + FIXME("Unimplemented!\n"); return 0; } diff --git a/reactos/lib/sdk/crt/except/xcptfil.c b/reactos/lib/sdk/crt/except/xcptfil.c index c69cc26c3d0..e617af5119e 100644 --- a/reactos/lib/sdk/crt/except/xcptfil.c +++ b/reactos/lib/sdk/crt/except/xcptfil.c @@ -1,6 +1,6 @@ #include -#include "include/internal/wine/msvcrt.h" -#include "include/internal/wine/cppexcept.h" +#include "internal/wine/msvcrt.h" +#include "internal/wine/cppexcept.h" typedef void (*sighandler_t)(int); static sighandler_t sighandlers[NSIG] = { SIG_DFL }; @@ -104,3 +104,4 @@ int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr) + diff --git a/reactos/lib/sdk/crt/float/fpreset.c b/reactos/lib/sdk/crt/float/fpreset.c index 6cbd4e2edf6..f73446402fd 100644 --- a/reactos/lib/sdk/crt/float/fpreset.c +++ b/reactos/lib/sdk/crt/float/fpreset.c @@ -10,12 +10,14 @@ #include -/* - * @unimplemented +/********************************************************************* + * _fpreset (MSVCRT.@) */ -void _fpreset(void) +void CDECL _fpreset(void) { - /* FIXME: This causes an exception */ -// __asm__ __volatile__("fninit\n\t"); - return; +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__( "fninit" ); +#else + FIXME(":Not Implemented!\n"); +#endif } diff --git a/reactos/lib/sdk/crt/float/i386/clearfp.c b/reactos/lib/sdk/crt/float/i386/clearfp.c index 09923b989a4..e42d67a2cfc 100644 --- a/reactos/lib/sdk/crt/float/i386/clearfp.c +++ b/reactos/lib/sdk/crt/float/i386/clearfp.c @@ -12,18 +12,17 @@ unsigned int _statusfp( void ); -/* - * @implemented +/********************************************************************* + * _clearfp (MSVCRT.@) */ -unsigned int _clearfp (void) +unsigned int CDECL _clearfp(void) { - unsigned short __res = _statusfp(); -#ifdef __GNUC__ -__asm__ __volatile__ ( - "fclex \n\t" - ); + unsigned int retVal = _statusfp(); +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__( "fnclex" ); #else -#endif /*__GNUC__*/ - return __res; + FIXME(":Not Implemented\n"); +#endif + return retVal; } diff --git a/reactos/lib/sdk/crt/float/i386/cntrlfp.c b/reactos/lib/sdk/crt/float/i386/cntrlfp.c index 48ff7f8f34e..836f54bb3bd 100644 --- a/reactos/lib/sdk/crt/float/i386/cntrlfp.c +++ b/reactos/lib/sdk/crt/float/i386/cntrlfp.c @@ -1,6 +1,7 @@ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include +#include #define X87_CW_IM (1<<0) /* Invalid operation mask */ #define X87_CW_DM (1<<1) /* Denormal operand mask */ @@ -25,150 +26,83 @@ /* * @implemented */ -unsigned int _controlfp(unsigned int unNew, unsigned int unMask) + +unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask) { - return _control87(unNew,unMask); -} - -/* - * @implemented - */ -unsigned int _control87(unsigned int unNew, unsigned int unMask) -{ - unsigned int FpuCw; - unsigned int DummyCw = 0; - - /* get the controlword */ - asm volatile("fstcw %0\n\t" : "=m"(FpuCw)); - FpuCw &= 0x0000ffff; - - /* translate it into _control87 format */ - if (FpuCw & X87_CW_IM) - DummyCw |= _EM_INVALID; - if (FpuCw & X87_CW_DM) - DummyCw |= _EM_DENORMAL; - if (FpuCw & X87_CW_ZM) - DummyCw |= _EM_ZERODIVIDE; - if (FpuCw & X87_CW_OM) - DummyCw |= _EM_OVERFLOW; - if (FpuCw & X87_CW_UM) - DummyCw |= _EM_UNDERFLOW; - if (FpuCw & X87_CW_PM) - DummyCw |= _EM_INEXACT; - - switch (FpuCw & X87_CW_PC_MASK) - { - case X87_CW_PC24: - DummyCw |= _PC_24; - break; - case X87_CW_PC53: - DummyCw |= _PC_53; - break; - case X87_CW_PC64: - DummyCw |= _PC_64; - break; - } - - switch (FpuCw & X87_CW_RC_MASK) - { - case X87_CW_RC_NEAREST: - DummyCw |= _RC_NEAR; - break; - case X87_CW_RC_DOWN: - DummyCw |= _RC_DOWN; - break; - case X87_CW_RC_UP: - DummyCw |= _RC_UP; - break; - case X87_CW_RC_ZERO: - DummyCw |= _RC_CHOP; - break; - } - - /* unset (un)masked bits */ - DummyCw &= ~unMask; - unNew &= unMask; - - /* set new bits */ - DummyCw |= unNew; - - /* translate back into x87 format - * FIXME: translate infinity control! - */ - FpuCw = 0; - if (DummyCw & _EM_INVALID) - FpuCw |= X87_CW_IM; - if (DummyCw & _EM_DENORMAL) - FpuCw |= X87_CW_DM; - if (DummyCw & _EM_ZERODIVIDE) - FpuCw |= X87_CW_ZM; - if (DummyCw & _EM_OVERFLOW) - FpuCw |= X87_CW_OM; - if (DummyCw & _EM_UNDERFLOW) - FpuCw |= X87_CW_UM; - if (DummyCw & _EM_INEXACT) - FpuCw |= X87_CW_PM; - - switch (DummyCw & _MCW_PC) - { - case _PC_24: - FpuCw |= X87_CW_PC24; - break; - case _PC_53: - FpuCw |= X87_CW_PC53; - break; - case _PC_64: - default: - FpuCw |= X87_CW_PC64; - break; - } - - switch (DummyCw & _MCW_RC) - { - case _RC_NEAR: - FpuCw |= X87_CW_RC_NEAREST; - break; - case _RC_DOWN: - FpuCw |= X87_CW_RC_DOWN; - break; - case _RC_UP: - FpuCw |= X87_CW_RC_UP; - break; - case _RC_CHOP: - FpuCw |= X87_CW_RC_ZERO; - break; - } - - /* set controlword */ - asm volatile("fldcw %0" : : "m"(FpuCw)); - - return DummyCw; - -#if 0 /* The follwing is the original code, broken I think! -blight */ -register unsigned int __res; -#ifdef __GNUC__ -__asm__ __volatile__ ( - "pushl %%eax \n\t" /* make room on stack */ - "fstcw (%%esp) \n\t" - "fwait \n\t" - "popl %%eax \n\t" - "andl $0xffff, %%eax \n\t" /* OK; we have the old value ready */ - - "movl %1, %%ecx \n\t" - "notl %%ecx \n\t" - "andl %%eax, %%ecx \n\t" /* the bits we want to keep */ - - "movl %2, %%edx \n\t" - "andl %1, %%edx \n\t" /* the bits we want to change */ - - "orl %%ecx, %%edx\n\t" /* the new value */ - "pushl %%edx \n\t" - "fldcw (%%esp) \n\t" - "popl %%edx \n\t" - - :"=a" (__res):"r" (unNew),"r" (unMask): "dx", "cx"); +#ifdef __i386__ + return _control87( newval, mask & ~_EM_DENORMAL ); #else -#endif /*__GNUC__*/ - return __res; + FIXME(":Not Implemented!\n"); + return 0; +#endif +} + +/********************************************************************* + * _control87 (MSVCRT.@) + */ +unsigned int CDECL _control87(unsigned int newval, unsigned int mask) +{ +#if defined(__GNUC__) && defined(__i386__) + unsigned int fpword = 0; + unsigned int flags = 0; + + TRACE("(%08x, %08x): Called\n", newval, mask); + + /* Get fp control word */ + __asm__ __volatile__( "fstcw %0" : "=m" (fpword) : ); + + TRACE("Control word before : %08x\n", 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; + + TRACE("Control word after : %08x\n", fpword); + + /* Put fp control word */ + __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); + + return flags; +#else + FIXME(":Not Implemented!\n"); + return 0; #endif } diff --git a/reactos/lib/sdk/crt/float/i386/statfp.c b/reactos/lib/sdk/crt/float/i386/statfp.c index e612ed32bf7..9df070ba32e 100644 --- a/reactos/lib/sdk/crt/float/i386/statfp.c +++ b/reactos/lib/sdk/crt/float/i386/statfp.c @@ -9,21 +9,34 @@ */ #include +#include "float.h" -/* - * @implemented +//WTF IS HAPPENING WITH float.h !??!?! +#define _SW_INVALID 0x00000010 /* invalid */ +#define _SW_ZERODIVIDE 0x00000008 /* zero divide */ +#define _SW_UNDERFLOW 0x00000002 /* underflow */ +#define _SW_OVERFLOW 0x00000004 /* overflow */ +#define _SW_INEXACT 0x00000001 /* inexact (precision) */ +#define _SW_DENORMAL 0x00080000 /* denormal status bit */ + +/********************************************************************** + * _statusfp (MSVCRT.@) */ -unsigned int _statusfp (void) +unsigned int CDECL _statusfp(void) { + unsigned int retVal = 0; +#if defined(__GNUC__) && defined(__i386__) + unsigned int fpword; -register unsigned short __res; -#ifdef __GNUC__ -__asm__ __volatile__ ( - "fstsw %0 \n\t" -// "movzwl %ax, %eax" - :"=a" (__res) - ); + __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 -#endif /*__GNUC__*/ - return __res; + FIXME(":Not implemented!\n"); +#endif + return retVal; } diff --git a/reactos/lib/sdk/crt/float/nafter.c b/reactos/lib/sdk/crt/float/nafter.c index 1d07b92f5d2..60a316edba0 100644 --- a/reactos/lib/sdk/crt/float/nafter.c +++ b/reactos/lib/sdk/crt/float/nafter.c @@ -15,6 +15,7 @@ */ double _nextafter( double x, double y ) { + WARN("This function is not implemented correctly\n"); if ( x == y) return x; diff --git a/reactos/lib/sdk/crt/include/float.h b/reactos/lib/sdk/crt/include/float.h index 86b1b4dfded..087b59092b6 100644 --- a/reactos/lib/sdk/crt/include/float.h +++ b/reactos/lib/sdk/crt/include/float.h @@ -72,11 +72,18 @@ #define _FPCLASS_PINF 0x0200 /* Positive Infinity */ #endif /* __MINGW_FPCLASS_DEFINED */ -/* invalid subconditions (_SW_INVALID also set) */ -#define _SW_UNEMULATED 0x0040 /* unemulated instruction */ -#define _SW_SQRTNEG 0x0080 /* square root of a neg number */ -#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ -#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ +/* _statusfp bit flags */ +#define _SW_INEXACT 0x00000001 /* inexact (precision) */ +#define _SW_UNDERFLOW 0x00000002 /* underflow */ +#define _SW_OVERFLOW 0x00000004 /* overflow */ +#define _SW_ZERODIVIDE 0x00000008 /* zero divide */ +#define _SW_INVALID 0x00000010 /* invalid */ +#define _SW_DENORMAL 0x00080000 /* denormal status bit */ + +#define _SW_UNEMULATED 0x00000040 /* unemulated instruction */ +#define _SW_SQRTNEG 0x00000080 /* square root of a neg number */ +#define _SW_STACKOVERFLOW 0x00000200 /* FP stack overflow */ +#define _SW_STACKUNDERFLOW 0x00000400 /* FP stack underflow */ /* Floating point error signals and return codes */ #define _FPE_INVALID 0x81 @@ -169,3 +176,4 @@ _CRTIMP int __cdecl _isnan (double); #endif /* _FLOAT_H_ */ + diff --git a/reactos/lib/sdk/crt/include/internal/debug.h b/reactos/lib/sdk/crt/include/internal/debug.h deleted file mode 100644 index de9b59bd5dc..00000000000 --- a/reactos/lib/sdk/crt/include/internal/debug.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: include/msvcrt/msvcrtdbg.h - * PURPOSE: Useful debugging macros - * PROGRAMMER: - * UPDATE HISTORY: - * - */ - -/* - * NOTE: Define NDEBUG before including this header to disable debugging - * macros - */ - -#ifndef __MSVCRT_DEBUG -#define __MSVCRT_DEBUG - -#include -#include - - -#define MK_STR(s) #s - -#ifdef _UNICODE - #define sT "S" -#else - #define sT "s" -#endif - -unsigned long DbgPrint(const char *Format,...); - -#ifdef __GNUC__ - #define TRACE(...) -#endif - -#ifdef DBG - #ifdef __GNUC__ - #define DPRINT1(args...) do { DbgPrint("(MSVCRT:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); - #else - #define DPRINT1 DbgPrint - #endif - #define CHECKPOINT1 do { DbgPrint("MSVCRT:%s:%d\n",__FILE__,__LINE__); } while(0); -#else - #ifdef __GNUC__ - #define DPRINT1(args...) - #else - #define DPRINT DbgPrint - #endif - #define CHECKPOINT1 -#endif - -#if !defined(NDEBUG) && defined(DBG) - #ifdef __GNUC__ - #define DPRINT(args...) do { DbgPrint("(MSVCRT:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); - #endif - #define CHECKPOINT do { DbgPrint("MSVCRT:%s:%d\n",__FILE__,__LINE__); } while(0); -#else - #ifdef __GNUC__ - #define DPRINT(args...) - #else - #define DPRINT DbgPrint - #endif - #define CHECKPOINT -#endif /* NDEBUG */ - - -#if 0 - - #define TRACE_RETURN(format_str, ret_type) \ - ret_type __return_value__; \ - static char* __return_format_str__ = "%s ret: "format_str"\n" - - #define FUNCTION(func) \ - static char* __func_name__ = #func - - #define TRACE(a,b...) DPRINT1(a"\n", b) - - #define RETURN(a) \ - do{ __return_value__ = (a); DPRINT1(__return_format_str__ ,__func_name__,__return_value__); return __return_value__ ; }while(0) - -#endif - - -/* ULONG CDECL DbgPrint(PCH Format, ...); */ -ULONG DbgPrint(PCCH Format,...); -/* unsigned long DbgPrint(const char* Format, ...); */ - - - -/* #define TRACE 0 ? (void)0 : Trace */ - -/* void Trace(TCHAR* lpszFormat, ...); */ - - - -#endif /* __MSVCRT_DEBUG */ diff --git a/reactos/lib/sdk/crt/include/internal/mbstring.h b/reactos/lib/sdk/crt/include/internal/mbstring.h index 65d89d19c47..f86473e4ff0 100644 --- a/reactos/lib/sdk/crt/include/internal/mbstring.h +++ b/reactos/lib/sdk/crt/include/internal/mbstring.h @@ -1,22 +1,43 @@ #ifndef __CRT_INTERNAL_MBSTRING_H #define __CRT_INTERNAL_MBSTRING_H -#define _KNJ_M ((char)0x01) /* Non-punctuation of Kana-set */ -#define _KNJ_P ((char)0x02) /* Punctuation of Kana-set */ -#define _KNJ_1 ((char)0x04) /* Legal 1st byte of double byte stream */ -#define _KNJ_2 ((char)0x08) /* Legal 2nd btye of double byte stream */ +#define _MALPHA 0x01 +#define _MBLANK 0x02 +#define _MDIGIT 0x04 +#define _MKMOJI 0x08 +#define _MKPNCT 0x10 +#define _MLEAD 0x20 +#define _MPUNCT 0x40 +#define _MTRAIL 0x80 +#define _MBALNUM (_MALPHA | _MDIGIT | _MKPNCT | _MKMOJI) +#define _MBALPHA (_MALPHA | _MKPNCT | _MKMOJI) +#define _MBGRAPH (_MALPHA | _MDIGIT | _MPUNCT | _MKPNCT | _MKMOJI) +#define _MBKANA (_MKPNCT | _MKMOJI) +#define _MBPRINT (_MALPHA | _MDIGIT | _MPUNCT | _MBLANK | _MKPNCT | _MKMOJI) +#define _MBPUNCT (_MPUNCT | _MKPNCT) -#define ___ 0 -#define _1_ _KNJ_1 /* Legal 1st byte of double byte code */ -#define __2 _KNJ_2 /* Legal 2nd byte of double byte code */ -#define _M_ _KNJ_M /* Non-puntuation in Kana-set */ -#define _P_ _KNJ_P /* Punctuation of Kana-set */ -#define _12 (_1_|__2) -#ifndef _M2 -#define _M2 (_M_|__2) -#endif -#define _P2 (_P_|__2) +#define _MBLMASK(c) ((c) & 255) +#define _MBHMASK(c) ((c) & ~255) +#define _MBGETL(c) ((c) & 255) +#define _MBGETH(c) (((c) >> 8) & 255) + +#define _MBIS16(c) ((c) & 0xff00) + +/* Macros */ +#define B _MBLANK +#define D _MDIGIT +#define P _MPUNCT +#define T _MTRAIL + +/* Macros */ +#define AT (_MALPHA | _MTRAIL) +#define GT (_MKPNCT | _MTRAIL) +#define KT (_MKMOJI | _MTRAIL) +#define LT (_MLEAD | _MTRAIL) +#define PT (_MPUNCT | _MTRAIL) + +extern unsigned char _mbctype[257]; #if defined (_MSC_VER) diff --git a/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h b/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h index cd59850a1b8..f28dff77984 100644 --- a/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h +++ b/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h @@ -20,16 +20,9 @@ #define __WINE_MSVCRT_H #include -#include -#include #include -#include - -#include "float.h" #include "windef.h" #include "winbase.h" -#include "winerror.h" -#include "winnls.h" #include "eh.h" @@ -133,44 +126,12 @@ extern void msvcrt_init_console(void); extern void msvcrt_free_console(void); extern void msvcrt_init_args(void); extern void msvcrt_free_args(void); +extern void msvcrt_init_signals(void); +extern void msvcrt_free_signals(void); #define MSVCRT__OUT_TO_DEFAULT 0 #define MSVCRT__REPORT_ERRMODE 3 -/* run-time error codes */ -#define _RT_STACK 0 -#define _RT_NULLPTR 1 -#define _RT_FLOAT 2 -#define _RT_INTDIV 3 -#define _RT_EXECMEM 5 -#define _RT_EXECFORM 6 -#define _RT_EXECENV 7 -#define _RT_SPACEARG 8 -#define _RT_SPACEENV 9 -#define _RT_ABORT 10 -#define _RT_NPTR 12 -#define _RT_FPTR 13 -#define _RT_BREAK 14 -#define _RT_INT 15 -#define _RT_THREAD 16 -#define _RT_LOCK 17 -#define _RT_HEAP 18 -#define _RT_OPENCON 19 -#define _RT_QWIN 20 -#define _RT_NOMAIN 21 -#define _RT_NONCONT 22 -#define _RT_INVALDISP 23 -#define _RT_ONEXIT 24 -#define _RT_PUREVIRT 25 -#define _RT_STDIOINIT 26 -#define _RT_LOWIOINIT 27 -#define _RT_HEAPINIT 28 -#define _RT_DOMAIN 120 -#define _RT_SING 121 -#define _RT_TLOSS 122 -#define _RT_CRNL 252 -#define _RT_BANNER 255 - #ifdef __i386__ struct MSVCRT___JUMP_BUFFER { unsigned long Ebp; @@ -203,7 +164,9 @@ typedef void* (*malloc_func_t)(size_t); typedef void (*free_func_t)(void*); #define MSVCRT_malloc malloc #define MSVCRT_free free +char* _setlocale(int,const char*); NTSYSAPI VOID NTAPI RtlAssert(PVOID FailedAssertion,PVOID FileName,ULONG LineNumber,PCHAR Message); extern char* __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int); + #endif /* __WINE_MSVCRT_H */ diff --git a/reactos/lib/sdk/crt/io/access.c b/reactos/lib/sdk/crt/io/access.c index 18558fdd276..ec5768c0e22 100644 --- a/reactos/lib/sdk/crt/io/access.c +++ b/reactos/lib/sdk/crt/io/access.c @@ -1,15 +1,15 @@ #include #include -#define NDEBUG -#include - #ifdef _UNICODE #define _TS S + #define sT "S" #else #define _TS s + #define sT "s" #endif +#define MK_STR(s) #s /* * @implemented @@ -17,9 +17,9 @@ int _taccess( const _TCHAR *_path, int _amode ) { DWORD Attributes = GetFileAttributes(_path); - DPRINT(MK_STR(_taccess)"('%"sT"', %x)\n", _path, _amode); + TRACE(MK_STR(_taccess)"('%"sT"', %x)\n", _path, _amode); - if (Attributes == (DWORD)-1) { + if (!_path || Attributes == INVALID_FILE_ATTRIBUTES) { _dosmaperr(GetLastError()); return -1; } @@ -33,15 +33,13 @@ int _taccess( const _TCHAR *_path, int _amode ) return 0; } - - /* * INTERNAL */ int access_dirT(const _TCHAR *_path) { DWORD Attributes = GetFileAttributes(_path); - DPRINT(MK_STR(is_dirT)"('%"sT"')\n", _path); + TRACE(MK_STR(is_dirT)"('%"sT"')\n", _path); if (Attributes == (DWORD)-1) { _dosmaperr(GetLastError()); @@ -57,3 +55,4 @@ int access_dirT(const _TCHAR *_path) return 0; } + diff --git a/reactos/lib/sdk/crt/io/chmod.c b/reactos/lib/sdk/crt/io/chmod.c index 218d4741c04..c6d612be2cb 100644 --- a/reactos/lib/sdk/crt/io/chmod.c +++ b/reactos/lib/sdk/crt/io/chmod.c @@ -12,12 +12,15 @@ #include #include -#define NDEBUG -#include - - #define mode_t int +#define MK_STR(s) #s + +#ifdef _UNICODE + #define sT "S" +#else + #define sT "s" +#endif /* * @implemented @@ -27,10 +30,10 @@ int _tchmod(const _TCHAR* filename, mode_t mode) DWORD FileAttributes = 0; BOOLEAN Set = FALSE; - DPRINT(MK_STR(_tchmod)"('%"sT"', %x)\n", filename, mode); + TRACE(MK_STR(_tchmod)"('%"sT"', %x)\n", filename, mode); FileAttributes = GetFileAttributes(filename); - if ( FileAttributes == (DWORD)-1 ) { + if ( FileAttributes == INVALID_FILE_ATTRIBUTES ) { _dosmaperr(GetLastError()); return -1; } diff --git a/reactos/lib/sdk/crt/io/chsize.c b/reactos/lib/sdk/crt/io/chsize.c index 78410c0debd..d2132d5ce4e 100644 --- a/reactos/lib/sdk/crt/io/chsize.c +++ b/reactos/lib/sdk/crt/io/chsize.c @@ -1,15 +1,12 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ #include -#define NDEBUG -#include - /* * @implemented */ int _chsize(int _fd, long size) { - DPRINT("_chsize(fd %d, size %d)\n", _fd, size); + TRACE("_chsize(fd %d, size %d)\n", _fd, size); long location = _lseek(_fd, 0, SEEK_CUR); if (location == -1) return -1; if (_lseek(_fd, size, 0) == -1) diff --git a/reactos/lib/sdk/crt/io/close.c b/reactos/lib/sdk/crt/io/close.c index 56138d4bb49..9f9af294d86 100644 --- a/reactos/lib/sdk/crt/io/close.c +++ b/reactos/lib/sdk/crt/io/close.c @@ -1,7 +1,5 @@ #include -#define NDEBUG -#include /* * @implemented @@ -12,9 +10,12 @@ int _close(int _fd) if (_fd == -1) return(-1); - if (CloseHandle((HANDLE)_get_osfhandle(_fd)) == FALSE) - return(-1); - //return + if (!CloseHandle((HANDLE)_get_osfhandle(_fd))) + { + WARN(":failed-last error (%d)\n",GetLastError()); + _dosmaperr(GetLastError()); + return -1; + } free_fd(_fd); return(0); } diff --git a/reactos/lib/sdk/crt/io/create.c b/reactos/lib/sdk/crt/io/creat.c similarity index 79% rename from reactos/lib/sdk/crt/io/create.c rename to reactos/lib/sdk/crt/io/creat.c index 8ef454219c9..1617da41df9 100644 --- a/reactos/lib/sdk/crt/io/create.c +++ b/reactos/lib/sdk/crt/io/creat.c @@ -10,8 +10,6 @@ #include -#define NDEBUG -#include /* @@ -19,6 +17,6 @@ */ int _creat(const char* filename, int mode) { - DPRINT("_creat('%s', mode %x)\n", filename, mode); + TRACE("_creat('%s', mode %x)\n", filename, mode); return _open(filename,_O_CREAT|_O_TRUNC,mode); } diff --git a/reactos/lib/sdk/crt/io/isatty.c b/reactos/lib/sdk/crt/io/isatty.c index 6e1573b8009..894e9536595 100644 --- a/reactos/lib/sdk/crt/io/isatty.c +++ b/reactos/lib/sdk/crt/io/isatty.c @@ -1,7 +1,5 @@ #include -#define NDEBUG -#include /* * @implemented diff --git a/reactos/lib/sdk/crt/io/mktemp.c b/reactos/lib/sdk/crt/io/mktemp.c index 61ee41007fc..e3e6ec273ec 100644 --- a/reactos/lib/sdk/crt/io/mktemp.c +++ b/reactos/lib/sdk/crt/io/mktemp.c @@ -15,9 +15,6 @@ #include -#define NDEBUG -#include - /* * @implemented */ @@ -27,7 +24,7 @@ char* _mktemp(char* _template) char *cp, *dp; int i, len, xcount, loopcnt; - DPRINT("_mktemp('%s')\n", _template); + TRACE("_mktemp('%s')\n", _template); len = strlen (_template); cp = _template + len; diff --git a/reactos/lib/sdk/crt/io/open.c b/reactos/lib/sdk/crt/io/open.c index 97fcd4c13ed..fb4b50813b5 100644 --- a/reactos/lib/sdk/crt/io/open.c +++ b/reactos/lib/sdk/crt/io/open.c @@ -46,10 +46,6 @@ #include #include -#define NDEBUG -#include - - FDINFO first_bucket[FDINFO_ENTRIES_PER_BUCKET]; FDINFO* __pioinfo[FDINFO_BUCKETS] = {first_bucket}; @@ -96,12 +92,12 @@ __inline BOOL is_valid_fd(int fd) if (!b){ if (fd >= 0 && fd < g_fdend) { - DPRINT1("not valid fd %i, g_fdend %i, fdinfo %x, bucket %x, fdflags %x\n", + ERR("not valid fd %i, g_fdend %i, fdinfo %x, bucket %x, fdflags %x\n", fd,g_fdend,fdinfo(fd),fdinfo_bucket(fd),fdinfo(fd)->fdflags); } else { - DPRINT1("not valid fd %i, g_fdend %i\n",fd,g_fdend); + ERR("not valid fd %i, g_fdend %i\n",fd,g_fdend); } } @@ -128,7 +124,7 @@ char split_oflags(int oflags) if (oflags & ~(_O_BINARY|_O_TEXT|_O_APPEND|_O_TRUNC| _O_EXCL|_O_CREAT|_O_RDWR|_O_WRONLY| _O_TEMPORARY|_O_NOINHERIT)) - DPRINT1(":unsupported oflags 0x%04x\n",oflags); + ERR(":unsupported oflags 0x%04x\n",oflags); return fdflags; } @@ -145,116 +141,29 @@ char __is_text_file(FILE* p) return (!((p)->_flag&_IOSTRG) && (fdinfo((p)->_file)->fdflags & FTEXT)); } -/* - * @implemented + +/********************************************************************* + * _open (MSVCRT.@) */ -int _open(const char* _path, int _oflag,...) +int CDECL _open( const char *path, int flags, ... ) { -#if !defined(NDEBUG) && defined(DBG) - va_list arg; - int pmode; -#endif - HANDLE hFile; - DWORD dwDesiredAccess = 0; - DWORD dwShareMode = 0; - DWORD dwCreationDistribution = 0; - DWORD dwFlagsAndAttributes = 0; - SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + va_list ap; -#if !defined(NDEBUG) && defined(DBG) - va_start(arg, _oflag); - pmode = va_arg(arg, int); -#endif - - - TRACE("_open('%s', %x, (%x))\n", _path, _oflag); - - - if ((_oflag & S_IREAD ) == S_IREAD) - dwShareMode = FILE_SHARE_READ; - else if ((_oflag & S_IWRITE) == S_IWRITE) { - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - } - /* - * - * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) - * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) - * - * _O_APPEND Moves file pointer to end of file before every write operation. - */ -#ifdef _OLD_BUILD_ - if ((_oflag & _O_RDWR) == _O_RDWR) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ; - else if ((_oflag & O_RDONLY) == O_RDONLY) - dwDesiredAccess |= GENERIC_READ; - else if ((_oflag & _O_WRONLY) == _O_WRONLY) - dwDesiredAccess |= GENERIC_WRITE ; -#else - if ((_oflag & _O_WRONLY) == _O_WRONLY ) - dwDesiredAccess |= GENERIC_WRITE ; - else if ((_oflag & _O_RDWR) == _O_RDWR ) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ; - else //if ((_oflag & O_RDONLY) == O_RDONLY) - dwDesiredAccess |= GENERIC_READ; -#endif - - if (( _oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) - dwCreationDistribution |= CREATE_NEW; - - else if ((_oflag & O_TRUNC ) == O_TRUNC) { - if ((_oflag & O_CREAT ) == O_CREAT) - dwCreationDistribution |= CREATE_ALWAYS; - else if ((_oflag & O_RDONLY ) != O_RDONLY) - dwCreationDistribution |= TRUNCATE_EXISTING; - } - else if ((_oflag & _O_APPEND) == _O_APPEND) - dwCreationDistribution |= OPEN_EXISTING; - else if ((_oflag & _O_CREAT) == _O_CREAT) - dwCreationDistribution |= OPEN_ALWAYS; - else - dwCreationDistribution |= OPEN_EXISTING; - - if ((_oflag & _O_RANDOM) == _O_RANDOM ) - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL) - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) { - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n"); - } - if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) { - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n"); - } - if (_oflag & _O_NOINHERIT) - sa.bInheritHandle = FALSE; - - if (dwCreationDistribution == OPEN_EXISTING && - (dwDesiredAccess & (GENERIC_WRITE|GENERIC_READ)) == GENERIC_READ) { - /* Allow always shared read for a file which is opened for read only */ - dwShareMode |= FILE_SHARE_READ; - } - - hFile = CreateFileA(_path, - dwDesiredAccess, - dwShareMode, - &sa, - dwCreationDistribution, - dwFlagsAndAttributes, - NULL); - if (hFile == (HANDLE)-1) { - _dosmaperr(GetLastError()); - return( -1); - } - DPRINT("OK\n"); - if (!(_oflag & (_O_TEXT|_O_BINARY))) { - _oflag |= _fmode; - } - return(alloc_fd(hFile, split_oflags(_oflag))); + if (flags & O_CREAT) + { + int pmode; + va_start(ap, flags); + pmode = va_arg(ap, int); + va_end(ap); + return _sopen( path, flags, SH_DENYNO, pmode ); + } + else + return _sopen( path, flags, SH_DENYNO); } + /* * INTERNAL */ @@ -299,7 +208,7 @@ static int alloc_fd_from(HANDLE hand, char flag, int fd) if (fd >= FDINFO_ENTRIES) { - DPRINT1("files exhausted!\n"); + ERR("files exhausted!\n"); return -1; } @@ -358,7 +267,7 @@ static int alloc_fd_from(HANDLE hand, char flag, int fd) alloc_init_bucket(g_fdstart); } - DPRINT("fdstart is %d, fdend is %d\n", g_fdstart, g_fdend); + TRACE("fdstart is %d, fdend is %d\n", g_fdstart, g_fdend); switch (fd) { @@ -686,44 +595,3 @@ unsigned create_io_inherit_block(STARTUPINFOA* si) } - - -/* - * @implemented - */ -int _setmode(int fd, int newmode) -{ - int prevmode; - - TRACE("_setmode(%d, %d)", fd, newmode); - - if (!is_valid_fd(fd)) - { - DPRINT1("_setmode: inval fd (%d)\n",fd); - //errno = EBADF; - return(-1); - } - - if (newmode & ~(_O_TEXT|_O_BINARY)) - { - DPRINT1("_setmode: fd (%d) mode (0x%08x) unknown\n",fd,newmode); - /* FIXME: Should we fail with EINVAL here? */ - } - - prevmode = fdinfo(fd)->fdflags & FTEXT ? _O_TEXT : _O_BINARY; - - if ((newmode & _O_TEXT) == _O_TEXT) - { - fdinfo(fd)->fdflags |= FTEXT; - } - else - { - /* FIXME: If both _O_TEXT and _O_BINARY are set, we get here. - * Should we fail with EINVAL instead? -Gunnar - */ - fdinfo(fd)->fdflags &= ~FTEXT; - } - - return(prevmode); -} - diff --git a/reactos/lib/sdk/crt/io/pipe.c b/reactos/lib/sdk/crt/io/pipe.c index 0fff3ed07b1..828b74a81f4 100644 --- a/reactos/lib/sdk/crt/io/pipe.c +++ b/reactos/lib/sdk/crt/io/pipe.c @@ -11,10 +11,6 @@ #include -#define NDEBUG -#include - - /* * @implemented */ diff --git a/reactos/lib/sdk/crt/io/read.c b/reactos/lib/sdk/crt/io/read.c index a614f73f8ed..c9b13d6f487 100644 --- a/reactos/lib/sdk/crt/io/read.c +++ b/reactos/lib/sdk/crt/io/read.c @@ -14,9 +14,6 @@ #include -#define NDEBUG -#include - /* * @implemented */ @@ -27,7 +24,7 @@ int _read(int _fd, void *_buf, unsigned int _nbyte) HANDLE hfile; int istext, error; - DPRINT("_read(fd %d, buf %x, nbyte %d)\n", _fd, _buf, _nbyte); + TRACE("_read(fd %d, buf %x, nbyte %d)\n", _fd, _buf, _nbyte); /* null read */ if(_nbyte == 0) @@ -95,6 +92,6 @@ int _read(int _fd, void *_buf, unsigned int _nbyte) /* ignore the carriage returns */ _rbyte -= cr; } - DPRINT("%d\n", _rbyte); + TRACE("%d\n", _rbyte); return _rbyte; } diff --git a/reactos/lib/sdk/crt/io/setmode.c b/reactos/lib/sdk/crt/io/setmode.c index 2a0c5baad81..06f19151a11 100644 --- a/reactos/lib/sdk/crt/io/setmode.c +++ b/reactos/lib/sdk/crt/io/setmode.c @@ -10,7 +10,45 @@ */ #include -#define NDEBUG -#include +__inline BOOL is_valid_fd(int fd); + +/* + * @implemented + */ +int _setmode(int fd, int newmode) +{ + int prevmode; + + TRACE("_setmode(%d, %d)", fd, newmode); + + if (!is_valid_fd(fd)) + { + ERR("_setmode: inval fd (%d)\n",fd); + //errno = EBADF; + return(-1); + } + + if (newmode & ~(_O_TEXT|_O_BINARY)) + { + ERR("_setmode: fd (%d) mode (0x%08x) unknown\n",fd,newmode); + /* FIXME: Should we fail with EINVAL here? */ + } + + prevmode = fdinfo(fd)->fdflags & FTEXT ? _O_TEXT : _O_BINARY; + + if ((newmode & _O_TEXT) == _O_TEXT) + { + fdinfo(fd)->fdflags |= FTEXT; + } + else + { + /* FIXME: If both _O_TEXT and _O_BINARY are set, we get here. + * Should we fail with EINVAL instead? -Gunnar + */ + fdinfo(fd)->fdflags &= ~FTEXT; + } + + return(prevmode); +} diff --git a/reactos/lib/sdk/crt/io/sopen.c b/reactos/lib/sdk/crt/io/sopen.c index 22ed00dd6a6..26593b061bc 100644 --- a/reactos/lib/sdk/crt/io/sopen.c +++ b/reactos/lib/sdk/crt/io/sopen.c @@ -13,8 +13,99 @@ /* * @implemented */ -int _sopen(const char *path, int access, int shflag, ... /*mode, permissin*/) +/********************************************************************* + * _sopen (MSVCRT.@) + */ +int CDECL _sopen( const char *path, int oflags, int shflags, ... ) { - //FIXME: vararg - return _open((path), (access)|(shflag));//, (mode)); + va_list ap; + int pmode; + DWORD access = 0, creation = 0, attrib; + DWORD sharing; + int wxflag = 0, fd; + HANDLE hand; + SECURITY_ATTRIBUTES sa; + + + TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n", + path, oflags, shflags); + + wxflag = split_oflags(oflags); + switch (oflags & (O_RDONLY | O_WRONLY | O_RDWR)) + { + case O_RDONLY: access |= GENERIC_READ; break; + case O_WRONLY: access |= GENERIC_WRITE; break; + case O_RDWR: access |= GENERIC_WRITE | GENERIC_READ; break; + } + + if (oflags & O_CREAT) + { + va_start(ap, shflags); + pmode = va_arg(ap, int); + va_end(ap); + + if(pmode & ~(S_IREAD | S_IWRITE)) + FIXME(": pmode 0x%04x ignored\n", pmode); + else + WARN(": pmode 0x%04x ignored\n", pmode); + + if (oflags & O_EXCL) + creation = CREATE_NEW; + else if (oflags & O_TRUNC) + creation = CREATE_ALWAYS; + else + creation = OPEN_ALWAYS; + } + else /* no O_CREAT */ + { + if (oflags & O_TRUNC) + creation = TRUNCATE_EXISTING; + else + creation = OPEN_EXISTING; + } + + switch( shflags ) + { + case SH_DENYRW: + sharing = 0L; + break; + case SH_DENYWR: + sharing = FILE_SHARE_READ; + break; + case SH_DENYRD: + sharing = FILE_SHARE_WRITE; + break; + case SH_DENYNO: + sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; + break; + default: + ERR( "Unhandled shflags 0x%x\n", shflags ); + return -1; + } + attrib = FILE_ATTRIBUTE_NORMAL; + + if (oflags & O_TEMPORARY) + { + attrib |= FILE_FLAG_DELETE_ON_CLOSE; + access |= DELETE; + sharing |= FILE_SHARE_DELETE; + } + + sa.nLength = sizeof( SECURITY_ATTRIBUTES ); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = (oflags & O_NOINHERIT) ? FALSE : TRUE; + + hand = CreateFileA(path, access, sharing, &sa, creation, attrib, 0); + + if (hand == INVALID_HANDLE_VALUE) { + WARN(":failed-last error (%d)\n",GetLastError()); + _dosmaperr(GetLastError()); + return -1; + } + + fd = alloc_fd(hand, wxflag); + + TRACE(":fd (%d) handle (%p)\n",fd, hand); + return fd; } + diff --git a/reactos/lib/sdk/crt/io/unlink.c b/reactos/lib/sdk/crt/io/unlink.c index d1a9b64a205..784316990b5 100644 --- a/reactos/lib/sdk/crt/io/unlink.c +++ b/reactos/lib/sdk/crt/io/unlink.c @@ -10,16 +10,12 @@ #include -#define NDEBUG -#include - - /* * @implemented */ int _unlink(const char* filename) { - DPRINT("_unlink('%s')\n", filename); + TRACE("_unlink('%s')\n", filename); if (!DeleteFileA(filename)) { _dosmaperr(GetLastError()); return -1; diff --git a/reactos/lib/sdk/crt/io/wcreate.c b/reactos/lib/sdk/crt/io/wcreat.c similarity index 79% rename from reactos/lib/sdk/crt/io/wcreate.c rename to reactos/lib/sdk/crt/io/wcreat.c index c4f7e5cc0cf..d7c695f2c51 100644 --- a/reactos/lib/sdk/crt/io/wcreate.c +++ b/reactos/lib/sdk/crt/io/wcreat.c @@ -10,8 +10,6 @@ #include -#define NDEBUG -#include /* @@ -19,6 +17,6 @@ */ int _wcreat(const wchar_t* filename, int mode) { - DPRINT("_wcreat('%S', mode %x)\n", filename, mode); + TRACE("_wcreat('%S', mode %x)\n", filename, mode); return _wopen(filename,_O_CREAT|_O_TRUNC,mode); } diff --git a/reactos/lib/sdk/crt/io/wmktemp.c b/reactos/lib/sdk/crt/io/wmktemp.c index 79b71b8f5c0..356857d9ff7 100644 --- a/reactos/lib/sdk/crt/io/wmktemp.c +++ b/reactos/lib/sdk/crt/io/wmktemp.c @@ -15,9 +15,6 @@ #include -#define NDEBUG -#include - /* * @implemented @@ -28,7 +25,7 @@ wchar_t* _wmktemp (wchar_t *_template) wchar_t *cp, *dp; int i, len, xcount, loopcnt; - DPRINT("_wmktemp('%S')\n", _template); + TRACE("_wmktemp('%S')\n", _template); len = wcslen (_template); cp = _template + len; diff --git a/reactos/lib/sdk/crt/io/wopen.c b/reactos/lib/sdk/crt/io/wopen.c index 32f9dc9d09b..60b380e241c 100644 --- a/reactos/lib/sdk/crt/io/wopen.c +++ b/reactos/lib/sdk/crt/io/wopen.c @@ -19,125 +19,53 @@ #include #include -#define NDEBUG -#include - -/* - * @implemented +/********************************************************************* + * _wopen (MSVCRT.@) */ -int _wopen(const wchar_t* _path, int _oflag, ...) +int CDECL _wopen(const wchar_t *path,int flags,...) { -#if !defined(NDEBUG) && defined(DBG) - va_list arg; - int pmode; -#endif - HANDLE hFile; - DWORD dwDesiredAccess = 0; - DWORD dwShareMode = 0; - DWORD dwCreationDistribution = 0; - DWORD dwFlagsAndAttributes = 0; - SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + const unsigned int len = strlenW(path); + char *patha = calloc(len + 1,1); + va_list ap; + int pmode; -#if !defined(NDEBUG) && defined(DBG) - va_start(arg, _oflag); - pmode = va_arg(arg, int); -#endif + va_start(ap, flags); + pmode = va_arg(ap, int); + va_end(ap); -// DPRINT("_wopen('%S', %x, (%x))\n", _path, _oflag, pmode); + if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL)) + { + int retval = _open(patha,flags,pmode); + free(patha); + return retval; + } - if ((_oflag & S_IREAD) == S_IREAD) - dwShareMode = FILE_SHARE_READ; - else if ( ( _oflag & S_IWRITE) == S_IWRITE) { - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - } - - /* - * - * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.) - * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.) - * - * _O_APPEND Moves file pointer to end of file before every write operation. - */ -#if 0 - if ((_oflag & _O_RDWR) == _O_RDWR) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA | - FILE_WRITE_DATA | FILE_READ_ATTRIBUTES | - FILE_WRITE_ATTRIBUTES; - else if ((_oflag & O_RDONLY) == O_RDONLY) - dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | - FILE_WRITE_ATTRIBUTES; - else if ((_oflag & _O_WRONLY) == _O_WRONLY) - dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA | - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES; -#else - if ((_oflag & _O_WRONLY) == _O_WRONLY) - dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA | - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES; - else if ((_oflag & _O_RDWR) == _O_RDWR) - dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA | - FILE_WRITE_DATA | FILE_READ_ATTRIBUTES | - FILE_WRITE_ATTRIBUTES; - else //if ((_oflag & O_RDONLY) == O_RDONLY) - dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | - FILE_WRITE_ATTRIBUTES; -#endif - - if ((_oflag & S_IREAD) == S_IREAD) - dwShareMode |= FILE_SHARE_READ; - - if ((_oflag & S_IWRITE) == S_IWRITE) - dwShareMode |= FILE_SHARE_WRITE; - - if ((_oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) - dwCreationDistribution |= CREATE_NEW; - - else if ((_oflag & O_TRUNC) == O_TRUNC) { - if ((_oflag & O_CREAT) == O_CREAT) - dwCreationDistribution |= CREATE_ALWAYS; - else if ((_oflag & O_RDONLY) != O_RDONLY) - dwCreationDistribution |= TRUNCATE_EXISTING; - } - else if ((_oflag & _O_APPEND) == _O_APPEND) - dwCreationDistribution |= OPEN_EXISTING; - else if ((_oflag & _O_CREAT) == _O_CREAT) - dwCreationDistribution |= OPEN_ALWAYS; - else - dwCreationDistribution |= OPEN_EXISTING; - - if ((_oflag & _O_RANDOM) == _O_RANDOM) - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL) - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - - if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - - if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - - if (_oflag & _O_NOINHERIT) - sa.bInheritHandle = FALSE; - - hFile = CreateFileW(_path, - dwDesiredAccess, - dwShareMode, - &sa, - dwCreationDistribution, - dwFlagsAndAttributes, - NULL); - if (hFile == (HANDLE)-1) { - _dosmaperr(GetLastError()); - return -1; - } - return alloc_fd(hFile,split_oflags(_oflag)); + _dosmaperr(GetLastError()); + return -1; } -/* - * @implemented +/********************************************************************* + * _wsopen (MSVCRT.@) */ -int _wsopen(const wchar_t* path, int access, int shflag,.../* int mode*/) +int CDECL _wsopen( const wchar_t* path, int oflags, int shflags, ... ) { - //FIXME: vararg - return _wopen((path), (access)|(shflag));//, (mode)); + const unsigned int len = strlenW(path); + char *patha = calloc(len + 1,1); + va_list ap; + int pmode; + + va_start(ap, shflags); + pmode = va_arg(ap, int); + va_end(ap); + + if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL)) + { + int retval = sopen(patha,oflags,shflags,pmode); + free(patha); + return retval; + } + + _dosmaperr(GetLastError()); + return -1; } diff --git a/reactos/lib/sdk/crt/io/write.c b/reactos/lib/sdk/crt/io/write.c index 49f7d94b93b..2b99cdd1a8c 100644 --- a/reactos/lib/sdk/crt/io/write.c +++ b/reactos/lib/sdk/crt/io/write.c @@ -10,8 +10,6 @@ #include -#define NDEBUG -#include #define BUFSIZE 4096 /* @@ -40,7 +38,7 @@ int _write(int _fd, const void* _buf, unsigned int _nbyte) unsigned int count; DWORD wbyte; - DPRINT("_write(fd %d, buf %x, nbyte %d)\n", _fd, _buf, _nbyte); + TRACE("_write(fd %d, buf %x, nbyte %d)\n", _fd, _buf, _nbyte); if (__fileno_getmode(_fd) & O_TEXT) { result = _nbyte; tmp = (char*) malloc(BUFSIZE); diff --git a/reactos/lib/sdk/crt/io/wunlink.c b/reactos/lib/sdk/crt/io/wunlink.c index d8a5d1f5708..2fb93ab3f02 100644 --- a/reactos/lib/sdk/crt/io/wunlink.c +++ b/reactos/lib/sdk/crt/io/wunlink.c @@ -10,15 +10,12 @@ #include -#define NDEBUG -#include - /* * @implemented */ int _wunlink(const wchar_t* filename) { - DPRINT("_wunlink('%S')\n", filename); + TRACE("_wunlink('%S')\n", filename); if (!DeleteFileW(filename)) { _dosmaperr(GetLastError()); return -1; diff --git a/reactos/lib/sdk/crt/locale/locale.c b/reactos/lib/sdk/crt/locale/locale.c index 16415bee17c..6d092f0eeb6 100644 --- a/reactos/lib/sdk/crt/locale/locale.c +++ b/reactos/lib/sdk/crt/locale/locale.c @@ -6,11 +6,8 @@ #include #include -#include - -#define NDEBUG -#include +#include "mbctype.h" // mtdll.h #define _SETLOCALE_LOCK 19 @@ -30,6 +27,29 @@ */ #define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */ #define MAX_LOCALE_LENGTH 256 + +unsigned char MSVCRT_mbctype[257]; +static int g_mbcp_is_multibyte = 0; + +/* It seems that the data about valid trail bytes is not available from kernel32 + * so we have to store is here. The format is the same as for lead bytes in CPINFO */ +struct cp_extra_info_t +{ + int cp; + BYTE TrailBytes[MAX_LEADBYTES]; +}; + +static struct cp_extra_info_t g_cpextrainfo[] = +{ + {932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}}, + {936, {0x40, 0xfe, 0, 0}}, + {949, {0x41, 0xfe, 0, 0}}, + {950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}}, + {20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */ + {0, {1, 255, 0, 0}} /* match all with FIXME */ +}; + + char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH]; LCID MSVCRT_current_lc_all_lcid; int MSVCRT___lc_codepage; @@ -354,7 +374,7 @@ char *setlocale(int category, const char *locale) if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') { - DPRINT1(":restore previous locale not implemented!\n"); + WARN(":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. @@ -449,7 +469,7 @@ char *setlocale(int category, const char *locale) if (haveCP && !haveCountry && !haveLang) { - DPRINT1(":Codepage only locale not implemented\n"); + ERR(":Codepage only locale not implemented\n"); /* FIXME: Use default lang/country and skip locale_to_LCID() * call below... */ @@ -500,7 +520,7 @@ wchar_t* _wsetlocale(int category, const wchar_t* locale) 'E','n','g','l','i','s','h','_','U','n','i','t','e','d',' ', 'S','t','a','t','e','s','.','1','2','5','2',0 }; - DPRINT1("%d %S\n", category, locale); + TRACE("%d %S\n", category, locale); return fake; } @@ -609,13 +629,127 @@ struct lconv *localeconv(void) /********************************************************************* * _setmbcp (MSVCRT.@) - * - * @unimplemented + * @implemented */ -void _setmbcp(int cp) +int CDECL _setmbcp(int cp) { -DPRINT1("_setmbcp - stub\n"); -return; + int newcp; + CPINFO cpi; + BYTE *bytes; + WORD chartypes[256]; + WORD *curr_type; + char bufA[256]; + WCHAR bufW[256]; + int charcount; + int ret; + int i; + + TRACE("_setmbcp %d\n",cp); + switch (cp) + { + case _MB_CP_ANSI: + newcp = GetACP(); + break; + case _MB_CP_OEM: + newcp = GetOEMCP(); + break; + case _MB_CP_LOCALE: + newcp = MSVCRT___lc_codepage; + break; + case _MB_CP_SBCS: + newcp = 20127; /* ASCII */ + break; + default: + newcp = cp; + break; + } + + if (!GetCPInfo(newcp, &cpi)) + { + ERR("Codepage %d not found\n", newcp); + __set_errno(EINVAL); + return -1; + } + + /* setup the _mbctype */ + memset(MSVCRT_mbctype, 0, sizeof(MSVCRT_mbctype)); + + bytes = cpi.LeadByte; + while (bytes[0] || bytes[1]) + { + for (i = bytes[0]; i <= bytes[1]; i++) + MSVCRT_mbctype[i + 1] |= _M1; + bytes += 2; + } + + if (cpi.MaxCharSize > 1) + { + /* trail bytes not available through kernel32 but stored in a structure in msvcrt */ + struct cp_extra_info_t *cpextra = g_cpextrainfo; + + g_mbcp_is_multibyte = 1; + while (TRUE) + { + if (cpextra->cp == 0 || cpextra->cp == newcp) + { + if (cpextra->cp == 0) + ERR("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp); + + bytes = cpextra->TrailBytes; + while (bytes[0] || bytes[1]) + { + for (i = bytes[0]; i <= bytes[1]; i++) + MSVCRT_mbctype[i + 1] |= _M2; + bytes += 2; + } + break; + } + cpextra++; + } + } + else + g_mbcp_is_multibyte = 0; + + /* we can't use GetStringTypeA directly because we don't have a locale - only a code page + */ + charcount = 0; + for (i = 0; i < 256; i++) + if (!(MSVCRT_mbctype[i + 1] & _M1)) + bufA[charcount++] = i; + + ret = MultiByteToWideChar(newcp, 0, bufA, charcount, bufW, charcount); + if (ret != charcount) + ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError()); + + GetStringTypeW(CT_CTYPE1, bufW, charcount, chartypes); + + curr_type = chartypes; + for (i = 0; i < 256; i++) + if (!(MSVCRT_mbctype[i + 1] & _M1)) + { + if ((*curr_type) & C1_UPPER) + MSVCRT_mbctype[i + 1] |= _SBUP; + if ((*curr_type) & C1_LOWER) + MSVCRT_mbctype[i + 1] |= _SBLOW; + curr_type++; + } + + if (newcp == 932) /* CP932 only - set _MP and _MS */ + { + /* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1 + * and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes + * it hard. As this is set only for codepage 932 we hardcode it what gives + * also faster execution. + */ + for (i = 161; i <= 165; i++) + MSVCRT_mbctype[i + 1] |= _MP; + for (i = 166; i <= 223; i++) + MSVCRT_mbctype[i + 1] |= _MS; + } + + MSVCRT___lc_collate_cp = MSVCRT___lc_codepage = newcp; + TRACE("(%d) -> %d\n", cp, MSVCRT___lc_codepage); + return 0; } @@ -626,7 +760,7 @@ return; */ void __lc_collate_cp(int cp) { -DPRINT1("__lc_collate_cp - stub\n"); +FIXME("__lc_collate_cp - stub\n"); return; } @@ -638,7 +772,7 @@ return; */ void __lc_handle(void) { -DPRINT1("__lc_handle - stub\n"); +FIXME("__lc_handle - stub\n"); return; } @@ -650,7 +784,7 @@ return; */ void __lc_codepage(void) { -DPRINT1("__lc_codepage - stub\n"); +FIXME("__lc_codepage - stub\n"); return; } @@ -660,7 +794,7 @@ return; */ void *_Gettnames(void) { - DPRINT1("(void), stub!\n"); + FIXME("(void), stub!\n"); return NULL; } @@ -669,7 +803,7 @@ void *_Gettnames(void) */ void __lconv_init(void) { - DPRINT1(" stub\n"); + FIXME(" stub\n"); } @@ -680,7 +814,7 @@ const char* _Strftime(char *out, unsigned int len, const char *fmt, const void *tm, void *foo) { /* FIXME: */ - DPRINT1("(%p %d %s %p %p) stub\n", out, len, fmt, tm, foo); + FIXME("(%p %d %s %p %p) stub\n", out, len, fmt, tm, foo); return ""; } @@ -693,7 +827,7 @@ const char* _Getdays(void) static const char *MSVCRT_days = ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:" "Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday"; /* FIXME: Use locale */ - DPRINT1("(void) semi-stub\n"); + FIXME("(void) semi-stub\n"); return MSVCRT_days; } @@ -706,7 +840,7 @@ const char* _Getmonths(void) "April:May:May:Jun:June:Jul:July:Aug:August:Sep:September:Oct:" "October:Nov:November:Dec:December"; /* FIXME: Use locale */ - DPRINT1("(void) semi-stub\n"); + FIXME("(void) semi-stub\n"); return MSVCRT_months; } @@ -717,7 +851,7 @@ int __crtLCMapStringA( LCID lcid, DWORD mapflags, const char* src, int srclen, char* dst, int dstlen, unsigned int codepage, int xflag ) { - DPRINT1("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n", + TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n", lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag); /* FIXME: A bit incorrect. But msvcrt itself just converts its * arguments to wide strings and then calls LCMapStringW @@ -725,6 +859,19 @@ int __crtLCMapStringA( return LCMapStringA(lcid,mapflags,src,srclen,dst,dstlen); } +/********************************************************************* + * __crtLCMapStringW (MSVCRT.@) + */ +int __crtLCMapStringW( + LCID lcid, DWORD mapflags, LPCWSTR src, int srclen, LPWSTR dst, + int dstlen, unsigned int codepage, int xflag +) { + TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n", + lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag); + + return LCMapStringW(lcid,mapflags,src,srclen,dst,dstlen); +} + int CDECL _getmbcp(void) { return MSVCRT___lc_codepage; diff --git a/reactos/lib/sdk/crt/math/stubs.c b/reactos/lib/sdk/crt/math/stubs.c index 9f11ba21fb9..40c726cffc2 100644 --- a/reactos/lib/sdk/crt/math/stubs.c +++ b/reactos/lib/sdk/crt/math/stubs.c @@ -1,5 +1,5 @@ +#include #include -#include double _CIsin(double x); double _CIcos(double x); @@ -135,85 +135,86 @@ double _CIfmod(double x, double 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"); + FIXME("_adj_fdiv_m32 stub\n"); } void __stdcall _adj_fdiv_m32i( int arg ) { - DPRINT1("_adj_fdiv_m32i stub\n"); + FIXME("_adj_fdiv_m32i stub\n"); } void __stdcall _adj_fdiv_m64( unsigned __int64 arg ) { - DPRINT1("_adj_fdiv_m64 stub\n"); + FIXME("_adj_fdiv_m64 stub\n"); } void _adj_fdiv_r(void) { - DPRINT1("_adj_fdiv_r stub\n"); + FIXME("_adj_fdiv_r stub\n"); } void __stdcall _adj_fdivr_m32( unsigned int arg ) { - DPRINT1("_adj_fdivr_m32i stub\n"); + FIXME("_adj_fdivr_m32i stub\n"); } void __stdcall _adj_fdivr_m32i( int arg ) { - DPRINT1("_adj_fdivr_m32i stub\n"); + FIXME("_adj_fdivr_m32i stub\n"); } void __stdcall _adj_fdivr_m64( unsigned __int64 arg ) { - DPRINT1("_adj_fdivr_m64 stub\n"); + FIXME("_adj_fdivr_m64 stub\n"); } void _adj_fpatan(void) { - DPRINT1("_adj_fpatan stub\n"); + FIXME("_adj_fpatan stub\n"); } void __stdcall _adj_fdiv_m16i( short arg ) { - DPRINT("_adj_fdiv_m16i stub\n"); + FIXME("_adj_fdiv_m16i stub\n"); } void __stdcall _adj_fdivr_m16i( short arg ) { - DPRINT("_adj_fdivr_m16i stub\n"); + FIXME("_adj_fdivr_m16i stub\n"); } void _adj_fprem(void) { - DPRINT("_adj_fprem stub\n"); + FIXME("_adj_fprem stub\n"); } void _adj_fprem1(void) { - DPRINT("_adj_fprem1 stub\n"); + FIXME("_adj_fprem1 stub\n"); } void _adj_fptan(void) { - DPRINT("_adj_fptan stub\n"); + FIXME("_adj_fptan stub\n"); } void _safe_fdiv(void) { - DPRINT("_safe_fdiv stub\n"); + FIXME("_safe_fdiv stub\n"); } void _safe_fdivr(void) { - DPRINT("_safe_fdivr stub\n"); + FIXME("_safe_fdivr stub\n"); } void _safe_fprem(void) { - DPRINT("_safe_fprem stub\n"); + FIXME("_safe_fprem stub\n"); } void _safe_fprem1(void) { - DPRINT("_safe_fprem1 stub\n"); + FIXME("_safe_fprem1 stub\n"); } + diff --git a/reactos/lib/sdk/crt/mbstring/ischira.c b/reactos/lib/sdk/crt/mbstring/ischira.c index 43ba5e5a44f..7a5b6d7d5a5 100644 --- a/reactos/lib/sdk/crt/mbstring/ischira.c +++ b/reactos/lib/sdk/crt/mbstring/ischira.c @@ -1,14 +1,15 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/ischira.c + * FILE: lib/sdk/crt/mbstring/ischira.c * PURPOSE: - * PROGRAMER: Ariadne + * PROGRAMER: * UPDATE HISTORY: - * 12/04/99: Created + * 12/04/99: Ariadne Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ -#include #include @@ -29,18 +30,29 @@ int _ismbckata( unsigned int c ) } /* - * @unimplemented + * @implemented */ unsigned int _mbctohira( unsigned int c ) { - return c; + if (c >= 0x8340 && c <= 0x837e) + return c - 0xa1; + else if (c >= 0x8380 && c <= 0x8396) + return c - 0xa2; + else + return c; } /* - * @unimplemented + * @implemented */ unsigned int _mbctokata( unsigned int c ) { - return c; + if (c >= 0x829f && c <= 0x82dd) + return c + 0xa1; + else if (c >= 0x82de && c <= 0x82f1) + return c + 0xa2; + else + return c; } + diff --git a/reactos/lib/sdk/crt/mbstring/iskana.c b/reactos/lib/sdk/crt/mbstring/iskana.c index 750466c1195..bb969c8ca9d 100644 --- a/reactos/lib/sdk/crt/mbstring/iskana.c +++ b/reactos/lib/sdk/crt/mbstring/iskana.c @@ -1,21 +1,21 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/iskana.c + * FILE: lib/sdk/crt/mbstring/iskana.c * PURPOSE: Checks for kana character - * PROGRAMER: Ariadne, Taiji Yamada + * PROGRAMER: * UPDATE HISTORY: - Modified from Taiji Yamada japanese code system utilities - * 12/04/99: Created + * 12/04/99: Ariadne, Taiji Yamada Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ -#include -#include -#include + +#include /* * @implemented */ int _ismbbkana(unsigned int c) { - return ((_mbctype+1)[(unsigned char)(c)] & (_KNJ_M|_KNJ_P)); + return (_mbctype[c & 0xff] & _MBKANA); } diff --git a/reactos/lib/sdk/crt/mbstring/iskmoji.c b/reactos/lib/sdk/crt/mbstring/iskmoji.c index a9c01ec0447..6b8afd87f16 100644 --- a/reactos/lib/sdk/crt/mbstring/iskmoji.c +++ b/reactos/lib/sdk/crt/mbstring/iskmoji.c @@ -1,3 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/iskmoji.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ + #include int _ismbbkalpha(unsigned char c) diff --git a/reactos/lib/sdk/crt/mbstring/iskpun.c b/reactos/lib/sdk/crt/mbstring/iskpun.c index 8747fb96b62..e1931f31706 100644 --- a/reactos/lib/sdk/crt/mbstring/iskpun.c +++ b/reactos/lib/sdk/crt/mbstring/iskpun.c @@ -1,18 +1,20 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/iskpun.c + * FILE: lib/sdk/crt/mbstring/iskpun.c * PURPOSE: - * PROGRAMER: Ariadne + * PROGRAMER: * UPDATE HISTORY: - * 12/04/99: Created + * 12/04/99: Ariadne Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ -#include -#include + +#include /* * @implemented */ int _ismbbkpunct( unsigned int c ) { - return ((_mbctype+1)[(unsigned char)(c)] & (_KNJ_P)); + return (_mbctype[c & 0xff] & _MKPNCT); } diff --git a/reactos/lib/sdk/crt/mbstring/islead.c b/reactos/lib/sdk/crt/mbstring/islead.c index 81a219f8b5d..c471e7cf06c 100644 --- a/reactos/lib/sdk/crt/mbstring/islead.c +++ b/reactos/lib/sdk/crt/mbstring/islead.c @@ -2,10 +2,10 @@ #include /* - * @unimplemented + * @implemented */ -int isleadbyte(int byte) +int isleadbyte(int c) { - return 0; - //return IsDBCSLeadByteEx(0,*c); + return _isctype( c, _MLEAD ); + } diff --git a/reactos/lib/sdk/crt/mbstring/islwr.c b/reactos/lib/sdk/crt/mbstring/islwr.c index b840a7f8e18..9f7a3d561b7 100644 --- a/reactos/lib/sdk/crt/mbstring/islwr.c +++ b/reactos/lib/sdk/crt/mbstring/islwr.c @@ -1,26 +1,22 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/islwr.c + * FILE: lib/sdk/crt/mbstring/ishwr.c * PURPOSE: - * PROGRAMER: Ariadne + * PROGRAMER: * UPDATE HISTORY: - * 12/04/99: Created + * 12/04/99: Ariadne Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ #include /* - * code page 952 only - * * @implemented */ int _ismbclower( unsigned int c ) { - if ((c & 0xFF00) != 0) { - if ( c >= 0x829A && c<= 0x829A ) - return 1; - } + return ((c) >= 0x8281 && (c) <= 0x829a); - return islower(c); } diff --git a/reactos/lib/sdk/crt/mbstring/ismbaln.c b/reactos/lib/sdk/crt/mbstring/ismbaln.c index ac8948ef3a8..afebd5ca2dd 100644 --- a/reactos/lib/sdk/crt/mbstring/ismbaln.c +++ b/reactos/lib/sdk/crt/mbstring/ismbaln.c @@ -1,7 +1,19 @@ -#include -#include +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/ismbaln.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ +#include + +int _ismbbkalnum( unsigned int c ); + /* * @implemented */ @@ -10,3 +22,4 @@ int _ismbbalnum(unsigned int c) return (isalnum(c) || _ismbbkalnum(c)); } + diff --git a/reactos/lib/sdk/crt/mbstring/ismbc.c b/reactos/lib/sdk/crt/mbstring/ismbc.c index 5d12e2b7151..aae943ce5a0 100644 --- a/reactos/lib/sdk/crt/mbstring/ismbc.c +++ b/reactos/lib/sdk/crt/mbstring/ismbc.c @@ -1,7 +1,38 @@ -#include +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/ismbc.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ -int _ismbbalpha(unsigned char c); -int _ismbbalnum(unsigned char c); + +#include +#include +#include + +unsigned char _mbctype[257] = { + 0, /* EOF */ + 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 , /* 1 */ + B ,P ,P ,P ,P ,P ,P ,P ,P ,P ,P ,P ,P ,P ,P ,P , /* 2 */ + D ,D ,D ,P ,D ,D ,D ,D ,D ,D ,P ,P ,P ,P ,P ,P , /* 3 */ + PT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT, /* 4 */ + AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,PT,PT,PT,PT,PT, /* 5 */ + PT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT, /* 6 */ + AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,AT,PT,PT,PT,PT,0 , /* 7 */ + T ,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT, /* 8 */ + LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT, /* 9 */ + T ,GT,GT,GT,GT,GT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT, /* A */ + KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT, /* B */ + KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT, /* C */ + KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,KT,GT,GT, /* D */ + LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT, /* E */ + LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,LT,0 ,0 ,0 , /* F */ +}; /* * @implemented @@ -23,14 +54,7 @@ int _ismbcalnum( unsigned int c ) */ int _ismbcalpha( unsigned int c ) { - if ((c & 0xFF00) != 0) { - // true multibyte character - return 0; - } - else - return _ismbbalpha(c); - - return 0; + return (_ismbcupper (c) || _ismbclower (c)); } /* @@ -38,100 +62,62 @@ int _ismbcalpha( unsigned int c ) */ int _ismbcdigit( unsigned int c ) { - if ((c & 0xFF00) != 0) { - // true multibyte character - return 0; - } - else - return 0; -// return _ismbbdigit(c); - - return 0; + return ((c) >= 0x824f && (c) <= 0x8258); } /* - * @unimplemented + * @implemented */ int _ismbcprint( unsigned int c ) { - if ((c & 0xFF00) != 0) { - // true multibyte character - return 0; - } - else - return 0; -// return _ismbbdigit(c); - - return 0; + return (_MBHMASK (c) ? _ismbclegal (c) : (isprint (c) || _ismbbkana (c))); } /* - * @unimplemented + * @implemented */ int _ismbcsymbol( unsigned int c ) { - if ((c & 0xFF00) != 0) { - // true multibyte character - return 0; - } - else - return 0; -// return _ismbbdigit(c); - - return 0; + return (c >= 0x8141 && c <= 0x817e) || (c >= 0x8180 && c <= 0x81ac); } /* - * @unimplemented + * @implemented */ int _ismbcspace( unsigned int c ) { - if ((c & 0xFF00) != 0) { - // true multibyte character - return 0; - } - else - return 0; -// return _ismbbdigit(c); - - return 0; + return ((c) == 0x8140); } /* * @implemented */ int _ismbclegal(unsigned int c) { - if ((c & 0xFF00) != 0) { - return _ismbblead(c>>8) && _ismbbtrail(c&0xFF); - } - else - return _ismbbtrail(c&0xFF); - - return 0; + return (_ismbblead (_MBGETH (c)) && _ismbbtrail (_MBGETL (c))); } /* - * @unimplemented + * @implemented */ int _ismbcl0(unsigned int c) { - return 0; + return (c >= 0x8140 && c <= 0x889e); } /* - * @unimplemented + * @implemented */ int _ismbcl1(unsigned int c) { - return 0; + return (c >= 0x889f && c <= 0x9872); } /* - * @unimplemented + * @implemented */ int _ismbcl2(unsigned int c) { - return 0; + return (c >= 0x989f && c <= 0xea9e); } /* diff --git a/reactos/lib/sdk/crt/mbstring/ismbkaln.c b/reactos/lib/sdk/crt/mbstring/ismbkaln.c index fd16c05cd97..084eb22c23e 100644 --- a/reactos/lib/sdk/crt/mbstring/ismbkaln.c +++ b/reactos/lib/sdk/crt/mbstring/ismbkaln.c @@ -1,19 +1,20 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/ismbkaln.c + * FILE: lib/sdk/crt/mbstring/ismbkaln.c * PURPOSE: - * PROGRAMER: Ariadne + * PROGRAMER: * UPDATE HISTORY: - * 12/04/99: Created + * 12/04/99: Ariadne Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ -#include -#include -#include + +#include /* * @implemented */ int _ismbbkalnum( unsigned int c ) { - return ((_mbctype+1)[(unsigned char)(c)] & (_KNJ_P)); + return (_mbctype[c & 0xff] & _MKMOJI); } diff --git a/reactos/lib/sdk/crt/mbstring/ismblead.c b/reactos/lib/sdk/crt/mbstring/ismblead.c index e453f53727d..26d52bff0be 100644 --- a/reactos/lib/sdk/crt/mbstring/ismblead.c +++ b/reactos/lib/sdk/crt/mbstring/ismblead.c @@ -1,54 +1,26 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/ismblead.c - * PURPOSE: Checks for a lead byte - * PROGRAMER: Ariadne + * FILE: lib/sdk/crt/mbstring/iskana.c + * PURPOSE: + * PROGRAMER: * UPDATE HISTORY: - * Modified from Taiji Yamada japanese code system utilities - * 12/04/99: Created + * 12/04/99: Ariadne, Taiji Yamada Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ -#include -#include -#include -#include +#include size_t _mbclen2(const unsigned int s); -unsigned char _mbctype[257] = { -/*-1*/ ___, -/*0x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, -/*1x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, -/*2x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, -/*3x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, -/*4x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2, -/*5x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2, -/*6x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2, -/*7x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,___, -/*8x*/ __2,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12, -/*9x*/ _12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12, -/*Ax*/ __2,_P2,_P2,_P2,_P2,_P2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, -/*Bx*/ _M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, -/*Cx*/ _M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, -/*Dx*/ _M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, -/*Ex*/ _12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12, -/*Fx*/ _12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,___,___,___ -}; - -//unsigned char _mbctype = _jctype; /* * @implemented */ int _ismbblead(unsigned int c) { - return ((_mbctype+1)[(unsigned char)(c)] & _KNJ_1); + return (_mbctype[c & 0xff] & _MLEAD); } -//int _ismbblead(unsigned int byte) -//{ -// -// return (int)IsDBCSLeadByte(byte) -//} /* * @implemented @@ -67,8 +39,9 @@ int _ismbslead( const unsigned char *str, const unsigned char *t) /* * @implemented */ -unsigned char *__p__mbctype(void) +const unsigned char *__p__mbctype(void) { return _mbctype; } + diff --git a/reactos/lib/sdk/crt/mbstring/ismbpun.c b/reactos/lib/sdk/crt/mbstring/ismbpun.c index f8858a7518a..571ded523a1 100644 --- a/reactos/lib/sdk/crt/mbstring/ismbpun.c +++ b/reactos/lib/sdk/crt/mbstring/ismbpun.c @@ -1,19 +1,16 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crt/?????? - * PURPOSE: Unknown - * PROGRAMER: Unknown + * FILE: lib/sdk/crt/mbstring/ismbpun.c + * PURPOSE: + * PROGRAMER: * UPDATE HISTORY: - * 25/11/05: Added license header + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ #include -#include -#include -#include - /* * @implemented @@ -21,7 +18,7 @@ int _ismbbpunct(unsigned int c) { // (0xA1 <= c <= 0xA6) - return (ispunct(c) || _ismbbkana(c)); + return (_mbctype[c & 0xff] & _MBPUNCT); } //iskana() :(0xA1 <= c <= 0xDF) diff --git a/reactos/lib/sdk/crt/mbstring/ismbtrl.c b/reactos/lib/sdk/crt/mbstring/ismbtrl.c index 41c4448113c..574733a6f57 100644 --- a/reactos/lib/sdk/crt/mbstring/ismbtrl.c +++ b/reactos/lib/sdk/crt/mbstring/ismbtrl.c @@ -8,9 +8,7 @@ * 12/04/99: Created */ -#include -#include -#include +#include size_t _mbclen2(const unsigned int s); @@ -21,14 +19,9 @@ size_t _mbclen2(const unsigned int s); */ int _ismbbtrail(unsigned int c) { - return ((_mbctype+1)[(unsigned char)(c)] & _KNJ_2); + return (_mbctype[c & 0xff] & _MTRAIL); } -//int _ismbbtrail( unsigned int b) -//{ -// return ((b >= 0x40 && b <= 0x7e ) || (b >= 0x80 && b <= 0xfc ) ); -//} - /* * @implemented diff --git a/reactos/lib/sdk/crt/mbstring/isuppr.c b/reactos/lib/sdk/crt/mbstring/isuppr.c index e32e06bc868..920363b5f79 100644 --- a/reactos/lib/sdk/crt/mbstring/isuppr.c +++ b/reactos/lib/sdk/crt/mbstring/isuppr.c @@ -1,26 +1,21 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/msvcrt/mbstring/isuppr.c + * FILE: lib/sdk/crt/mbstring/isuppr.c * PURPOSE: - * PROGRAMER: Ariadne + * PROGRAMER: * UPDATE HISTORY: - * 12/04/99: Created + * 12/04/99: Ariadne Created + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * */ #include /* - * code page 952 only - * * @implemented */ int _ismbcupper( unsigned int c ) { - if ((c & 0xFF00) != 0) { - if ( c >= 0x8260 && c<= 0x8279 ) - return 1; - } - - return isupper(c); + return ((c) >= 0x8260 && (c) <= 0x8279); } diff --git a/reactos/lib/sdk/crt/mbstring/jistojms.c b/reactos/lib/sdk/crt/mbstring/jistojms.c index bddb6caef00..a5eb3b0652a 100644 --- a/reactos/lib/sdk/crt/mbstring/jistojms.c +++ b/reactos/lib/sdk/crt/mbstring/jistojms.c @@ -1,3 +1,5 @@ + +#include #include /* diff --git a/reactos/lib/sdk/crt/mbstring/mbscspn.c b/reactos/lib/sdk/crt/mbstring/mbscspn.c index 59936778fc6..02d69d68388 100644 --- a/reactos/lib/sdk/crt/mbstring/mbscspn.c +++ b/reactos/lib/sdk/crt/mbstring/mbscspn.c @@ -1,23 +1,34 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/mbscpn.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ + +#include #include /* - * FIXME not correct - * - * @unimplemented + * @implemented */ -size_t _mbscspn(const unsigned char *s1, const unsigned char *s2) +size_t _mbscspn (const unsigned char *str1, const unsigned char *str2) { - const unsigned char *p, *spanp; - char c, sc; + int c; + unsigned char *ptr; + const unsigned char *save = str1; - for (p = s1;;) - { - c = *p++; - spanp = s2; - do { - if ((sc = *spanp++) == c) - return (size_t)(p - 1) - (size_t)s1; - } while (sc != 0); - } - /* NOTREACHED */ + while ((c = _mbsnextc (str1))) { + + if ((ptr = _mbschr (str2, c))) + break; + + str1 = _mbsinc ((unsigned char *) str1); + + } + + return str1 - save; } diff --git a/reactos/lib/sdk/crt/mbstring/mbsicmp.c b/reactos/lib/sdk/crt/mbstring/mbsicmp.c index 8777e6b9f4a..dd1d634d2ff 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsicmp.c +++ b/reactos/lib/sdk/crt/mbstring/mbsicmp.c @@ -9,7 +9,6 @@ */ #include #include -#include /* * @implemented diff --git a/reactos/lib/sdk/crt/mbstring/mbslwr.c b/reactos/lib/sdk/crt/mbstring/mbslwr.c index c5d24cb361f..d2ad5bcc3e2 100644 --- a/reactos/lib/sdk/crt/mbstring/mbslwr.c +++ b/reactos/lib/sdk/crt/mbstring/mbslwr.c @@ -1,3 +1,15 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/ismbpun.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ + +#include #include #include @@ -8,22 +20,12 @@ unsigned int _mbbtolower(unsigned int c) return c; } -// code page 952 -#define CASE_DIFF (0x8281 - 0x8260) - /* * @implemented */ unsigned int _mbctolower(unsigned int c) { - if ((c & 0xFF00) != 0) { - // true multibyte case conversion needed - if (_ismbclower(c)) - return c + CASE_DIFF; - } else { - return _mbbtolower(c); - } - return 0; + return _ismbcupper (c) ? c + 0x21 : c; } /* diff --git a/reactos/lib/sdk/crt/mbstring/mbsncat.c b/reactos/lib/sdk/crt/mbstring/mbsncat.c index d1e5ce2ec8e..a16e8351ff9 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsncat.c +++ b/reactos/lib/sdk/crt/mbstring/mbsncat.c @@ -8,34 +8,37 @@ * 12/04/99: Created */ +#include #include #include size_t _mbclen2(const unsigned int s); +unsigned char *_mbset (unsigned char *string, int c); /* * @implemented */ -unsigned char * _mbsncat(unsigned char *dst, const unsigned char *src, size_t n) +unsigned char *_mbsncat (unsigned char *dst, const unsigned char *src, size_t n) { - unsigned char *d = dst; - const unsigned char *s = src; - if (n != 0) { - d = dst + _mbslen(dst); // get the end of string - d += _mbclen2(*d); // move 1 or 2 up + int c; + unsigned char *save = dst; - do { - if ((*d++ = *s++) == 0) - { - while (--n != 0) - *d++ = 0; - break; - } - if (!_ismbblead(*s) ) - n--; - } while (n > 0); - } - return dst; + while ((c = _mbsnextc (dst))) + dst = _mbsinc (dst); + + while (n-- > 0 && (c = _mbsnextc (src))) { + + _mbset (dst, c); + + dst = _mbsinc (dst); + + src = _mbsinc ((unsigned char *) src); + + } + + *dst = '\0'; + + return save; } /* diff --git a/reactos/lib/sdk/crt/mbstring/mbsnextc.c b/reactos/lib/sdk/crt/mbstring/mbsnextc.c index ee75c6f915c..667024ae078 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsnextc.c +++ b/reactos/lib/sdk/crt/mbstring/mbsnextc.c @@ -1,4 +1,4 @@ -#include +#include #include /* diff --git a/reactos/lib/sdk/crt/mbstring/mbsnicoll.c b/reactos/lib/sdk/crt/mbstring/mbsnicoll.c index bfc67e5e1df..3e93af6a6a5 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsnicoll.c +++ b/reactos/lib/sdk/crt/mbstring/mbsnicoll.c @@ -1,3 +1,5 @@ + +#include #include /* @@ -5,7 +7,8 @@ */ int _mbsnicoll(const unsigned char *s1, const unsigned char *s2, size_t n) { - return 0; + WARN("_mbsnicoll unimplemented\n"); + return 0; } /* @@ -13,5 +16,6 @@ int _mbsnicoll(const unsigned char *s1, const unsigned char *s2, size_t n) */ int _mbsnbicoll(const unsigned char *s1, const unsigned char *s2, size_t n) { - return 0; + WARN("_mbsnbicoll unimplemented\n"); + return 0; } diff --git a/reactos/lib/sdk/crt/mbstring/mbsspn.c b/reactos/lib/sdk/crt/mbstring/mbsspn.c index 3d654feb0a7..72ee3e2a41b 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsspn.c +++ b/reactos/lib/sdk/crt/mbstring/mbsspn.c @@ -1,20 +1,34 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/ismbpun.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ + +#include #include /* - * FIXME not correct - * - * @unimplemented + * @implemented */ -size_t _mbsspn(const unsigned char *s1, const unsigned char *s2) +size_t _mbsspn (const unsigned char *str1, const unsigned char *str2) { - const unsigned char *p = s1, *spanp; - char c, sc; + int c; + unsigned char *ptr; + const unsigned char *save = str1; - cont: - c = *p++; - for (spanp = s2; (sc = *spanp++) != 0;) - if (sc == c) - goto cont; - return (size_t)(p - 1) - (size_t)s1; -// - (char *)s1); + while ((c = _mbsnextc (str1))) { + + if ((ptr = _mbschr (str2, c)) == 0) + break; + + str1 = _mbsinc ((unsigned char *) str1); + + } + + return str1 - save; } diff --git a/reactos/lib/sdk/crt/mbstring/mbsspnp.c b/reactos/lib/sdk/crt/mbstring/mbsspnp.c index 07a698ae443..36b903d1e4f 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsspnp.c +++ b/reactos/lib/sdk/crt/mbstring/mbsspnp.c @@ -1,19 +1,22 @@ +#include #include /* - * FIXME not correct - * - * @unimplemented + * @implemented */ -unsigned char * _mbsspnp(const unsigned char *s1, const unsigned char *s2) +unsigned char *_mbsspnp (const unsigned char *str1, const unsigned char *str2) { - const unsigned char *p = s1, *spanp; - char c, sc; + int c; + unsigned char *ptr; - cont: - c = *p++; - for (spanp = s2; (sc = *spanp++) != 0;) - if (sc == c) - goto cont; - return (unsigned char *)p; + while ((c = _mbsnextc (str1))) { + + if ((ptr = _mbschr (str2, c)) == 0) + return (unsigned char *) str1; + + str1 = _mbsinc ((unsigned char *) str1); + + } + + return 0; } diff --git a/reactos/lib/sdk/crt/mbstring/mbsupr.c b/reactos/lib/sdk/crt/mbstring/mbsupr.c index 8b713c561ff..9bf405c8a3d 100644 --- a/reactos/lib/sdk/crt/mbstring/mbsupr.c +++ b/reactos/lib/sdk/crt/mbstring/mbsupr.c @@ -7,6 +7,8 @@ * UPDATE HISTORY: * 12/04/99: Created */ + +#include #include #include @@ -18,39 +20,57 @@ unsigned int _mbbtoupper(unsigned int c) return c; } -// codepage 952 -#define CASE_DIFF (0x8281 - 0x8260) - /* * @implemented */ unsigned int _mbctoupper(unsigned int c) { + return _ismbclower (c) ? c - 0x21 : c; +} - if ((c & 0xFF00) != 0) { -// true multibyte case conversion needed - if ( _ismbcupper(c) ) - return c + CASE_DIFF; +unsigned char *_mbset (unsigned char *string, int c) +{ + unsigned char *save = string; - } else - return _mbbtoupper(c); + if (_MBIS16 (c)) { - return 0; + if (_MBLMASK (c) == 0) { + *string++ = '\0'; + *string++ = '\0'; + } + else { + *string++ = _MBGETH (c); + *string++ = _MBGETL (c); + } + + } + else { + + *string++ = c; + + } + + return save; } /* * @implemented */ -unsigned char * _mbsupr(unsigned char *x) +unsigned char *_mbsupr (unsigned char *string) { - unsigned char *y=x; - while (*y) { - if (!_ismbblead(*y) ) - *y = toupper(*y); - else { - *y=_mbctoupper(*(unsigned short *)y); - y++; - } - } - return x; + int c; + unsigned char *save = string; + + while ((c = _mbsnextc (string))) { + + if (_MBIS16 (c) == 0) + c = toupper (c); + + _mbset (string, c); + + string = _mbsinc (string); + + } + + return save; } diff --git a/reactos/lib/sdk/crt/misc/crtmain.c b/reactos/lib/sdk/crt/misc/crtmain.c index 24da298fa16..e69de29bb2d 100644 --- a/reactos/lib/sdk/crt/misc/crtmain.c +++ b/reactos/lib/sdk/crt/misc/crtmain.c @@ -1,92 +0,0 @@ -/* $Id$ - * - * ReactOS MSVCRT.DLL Compatibility Library - */ - -#include - -#define NDEBUG -#include - -#ifndef __GNUC__ - -/* GLOBAL VARIABLES *******************************************************/ - -int _fltused; - - -/* FUNCTIONS **************************************************************/ - -/* - * @unimplemented - */ -int -STDCALL -_except_handler3(void) -{ - return 0; -} - -/* - * @unimplemented - */ -int -STDCALL -_local_unwind2(void) -{ - return 0; -} - -#else /*__GNUC__*/ - -#endif /*__GNUC__*/ - - -/* -int __cdecl _allmul(void) -{ - return 0; -} - -int __cdecl _allshl(void) -{ - return 0; -} - -void __cdecl _chkesp(int value1, int value2) -{ -} - -int __cdecl _alloca_probe(void) -{ - return 0; -} - -int STDCALL _abnormal_termination(void) -{ - return 0; -} - -int STDCALL _setjmp(void) -{ - return 0; -} -*/ -/* -BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved); - -int STDCALL _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) -{ - BOOL result; - - //__fileno_init(); - //result = DllMain(hInst, ul_reason_for_call, lpReserved); - - result = DllMain(hInst, DLL_PROCESS_ATTACH, lpReserved); - - - return (result ? 1 : 0); -} - */ - -/* EOF */ diff --git a/reactos/lib/sdk/crt/misc/environ.c b/reactos/lib/sdk/crt/misc/environ.c index 02f83455769..845721c5cc8 100644 --- a/reactos/lib/sdk/crt/misc/environ.c +++ b/reactos/lib/sdk/crt/misc/environ.c @@ -1,6 +1,6 @@ /* $Id$ * - * dllmain.c + * environ.c * * ReactOS MSVCRT.DLL Compatibility Library */ @@ -10,9 +10,6 @@ #include #include -#define NDEBUG -#include - unsigned int _osver = 0; unsigned int _winminor = 0; @@ -44,7 +41,7 @@ int BlockEnvToEnvironA(void) char **envptr; int count = 1, len; - DPRINT("BlockEnvToEnvironA()\n"); + TRACE("BlockEnvToEnvironA()\n"); environment_strings = GetEnvironmentStringsA(); if (environment_strings == NULL) { @@ -95,7 +92,7 @@ int BlockEnvToEnvironW(void) wchar_t **envptr; int count = 1, len; - DPRINT("BlockEnvToEnvironW()\n"); + TRACE("BlockEnvToEnvironW()\n"); environment_strings = GetEnvironmentStringsW(); if (environment_strings == NULL) { diff --git a/reactos/lib/sdk/crt/misc/getargs.c b/reactos/lib/sdk/crt/misc/getargs.c index 51771e8e8cd..98647620366 100644 --- a/reactos/lib/sdk/crt/misc/getargs.c +++ b/reactos/lib/sdk/crt/misc/getargs.c @@ -362,10 +362,3 @@ wchar_t*** __p___wargv(void) return &__wargv; } - -#if 0 -int _chkstk(void) -{ - return 0; -} -#endif diff --git a/reactos/lib/sdk/crt/misc/lock.c b/reactos/lib/sdk/crt/misc/lock.c index 989be017d25..99ef59febad 100644 --- a/reactos/lib/sdk/crt/misc/lock.c +++ b/reactos/lib/sdk/crt/misc/lock.c @@ -18,9 +18,6 @@ #include -#define NDEBUG -#include -#include typedef struct { @@ -58,7 +55,7 @@ void msvcrt_init_mt_locks(void) { int i; - DPRINT( "initializing mtlocks\n" ); + TRACE( "initializing mtlocks\n" ); /* Initialize the table */ for( i=0; i < _TOTAL_LOCKS; i++ ) @@ -81,7 +78,7 @@ void msvcrt_free_mt_locks(void) { int i; - DPRINT(": uninitializing all mtlocks\n" ); + TRACE(": uninitializing all mtlocks\n" ); /* Uninitialize the table */ for( i=0; i < _TOTAL_LOCKS; i++ ) @@ -99,7 +96,7 @@ void msvcrt_free_mt_locks(void) */ void _lock( int locknum ) { - DPRINT( "(%d)\n", locknum ); + TRACE( "(%d)\n", locknum ); /* If the lock doesn't exist yet, create it */ if( lock_table[ locknum ].bInit == FALSE ) @@ -110,7 +107,7 @@ void _lock( int locknum ) /* Check again if we've got a bit of a race on lock creation */ if( lock_table[ locknum ].bInit == FALSE ) { - DPRINT( ": creating lock #%d\n", locknum ); + TRACE( ": creating lock #%d\n", locknum ); msvcrt_initialize_mlock( locknum ); } @@ -128,8 +125,9 @@ void _lock( int locknum ) */ void _unlock( int locknum ) { - DPRINT( "(%d)\n", locknum ); + TRACE( "(%d)\n", locknum ); LeaveCriticalSection( &(lock_table[ locknum ].crit) ); } + diff --git a/reactos/lib/sdk/crt/misc/stubs.c b/reactos/lib/sdk/crt/misc/stubs.c index b6a8e2a5490..fabb0d9c1cb 100644 --- a/reactos/lib/sdk/crt/misc/stubs.c +++ b/reactos/lib/sdk/crt/misc/stubs.c @@ -1,11 +1,8 @@ #include -#define NDEBUG -#include - int __STRINGTOLD( long double *value, char **endptr, const char *str, int flags ) { - DPRINT1("%p %p %s %x stub\n", value, endptr, str, flags ); + FIXME("%p %p %s %x stub\n", value, endptr, str, flags ); return 0; } @@ -20,17 +17,17 @@ void MSVCRT_I10_OUTPUT(void) void __p__amblksiz(void) { - DPRINT1("__p__amblksiz stub\n"); + FIXME("__p__amblksiz stub\n"); } void __fileinfo(void) { - DPRINT1("__fileinfo stub\n"); + FIXME("__fileinfo stub\n"); } void stub(void) { - DPRINT1("stub\n"); + FIXME("stub\n"); } /********************************************************************* @@ -38,7 +35,7 @@ void stub(void) */ int CDECL _getmaxstdio(void) { - DPRINT1("stub, always returns 512\n"); + FIXME("stub, always returns 512\n"); return 512; } @@ -52,6 +49,6 @@ int CDECL _setmaxstdio(int newmax) res = -1; else res = newmax; - DPRINT1("stub: setting new maximum for number of simultaneously open files not implemented,returning %d\n",res); + FIXME("stub: setting new maximum for number of simultaneously open files not implemented,returning %d\n",res); return res; } diff --git a/reactos/lib/sdk/crt/precomp.h b/reactos/lib/sdk/crt/precomp.h index 800909853c6..823f849a54c 100644 --- a/reactos/lib/sdk/crt/precomp.h +++ b/reactos/lib/sdk/crt/precomp.h @@ -32,11 +32,27 @@ #include #endif +#include "wine/unicode.h" + +/* kernelmode libcnt should not include Wine-debugging crap */ +#ifndef _LIBCNT_ +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); +#else +#include +#define TRACE DPRINT +#define WARN DPRINT1 +#endif + /* CRT Internal data */ #include #include #include #include +#include +#include +#include +#include #include #endif /* _CRT_PRECOMP_H */ diff --git a/reactos/lib/sdk/crt/process/_system.c b/reactos/lib/sdk/crt/process/_system.c index 99add836032..94bbe7fcda4 100644 --- a/reactos/lib/sdk/crt/process/_system.c +++ b/reactos/lib/sdk/crt/process/_system.c @@ -14,8 +14,7 @@ #include #include -#define NDEBUG -#include + /* * @implemented */ @@ -117,6 +116,6 @@ int system(const char *command) int CDECL _wsystem(const wchar_t* cmd) { - DPRINT1("_wsystem stub\n"); + FIXME("_wsystem stub\n"); return -1; } diff --git a/reactos/lib/sdk/crt/process/process.c b/reactos/lib/sdk/crt/process/process.c index 2ba21df33c4..bf5bacf2169 100644 --- a/reactos/lib/sdk/crt/process/process.c +++ b/reactos/lib/sdk/crt/process/process.c @@ -2,16 +2,15 @@ #include #include -#define NDEBUG -#include - #ifdef _UNICODE + #define sT "S" #define find_execT find_execW #define argvtosT argvtosW #define do_spawnT do_spawnW #define valisttosT valisttosW #define extT extW #else + #define sT "s" #define find_execT find_execA #define argvtosT argvtosA #define do_spawnT do_spawnA @@ -19,6 +18,7 @@ #define extT extA #endif +#define MK_STR(s) #s _TCHAR const* extT[] = { @@ -35,7 +35,7 @@ const _TCHAR* find_execT(const _TCHAR* path, _TCHAR* rpath) const _TCHAR *rd; unsigned int i, found = 0; - DPRINT(MK_STR(find_execT)"('%"sT"', %x)\n", path, rpath); + TRACE(MK_STR(find_execT)"('%"sT"', %x)\n", path, rpath); if (path == NULL) { @@ -54,7 +54,7 @@ const _TCHAR* find_execT(const _TCHAR* path, _TCHAR* rpath) { _tcscpy(rp, extT[i]); - DPRINT("trying '%"sT"'\n", rpath); + TRACE("trying '%"sT"'\n", rpath); if (_taccess(rpath, F_OK) == 0 && access_dirT(rpath) != 0) { @@ -90,7 +90,7 @@ const _TCHAR* find_execT(const _TCHAR* path, _TCHAR* rpath) { _tcscpy(rp, extT[i]); - DPRINT("trying '%"sT"'\n", rpath); + TRACE("trying '%"sT"'\n", rpath); if (_taccess(rpath, F_OK) == 0 && access_dirT(rpath) != 0) { @@ -286,7 +286,7 @@ do_spawnT(int mode, const _TCHAR* cmdname, const _TCHAR* args, const _TCHAR* env if (!bResult) { dwError = GetLastError(); - DPRINT("%x\n", dwError); + ERR("%x\n", dwError); __set_errno(dwError); return(-1); } @@ -320,7 +320,7 @@ int _tspawnl(int mode, const _TCHAR *cmdname, const _TCHAR* arg0, ...) _TCHAR* args; int ret = -1; - DPRINT(MK_STR(_tspawnl)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnl)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -341,7 +341,7 @@ int _tspawnv(int mode, const _TCHAR *cmdname, const _TCHAR* const* argv) _TCHAR* args; int ret = -1; - DPRINT(MK_STR(_tspawnv)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnv)"('%"sT"')\n", cmdname); args = argvtosT(argv, ' '); @@ -364,7 +364,7 @@ int _tspawnle(int mode, const _TCHAR *cmdname, const _TCHAR* arg0, ... /*, NULL, _TCHAR const * const* ptr; int ret = -1; - DPRINT(MK_STR(_tspawnle)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnle)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -397,7 +397,7 @@ int _tspawnve(int mode, const _TCHAR *cmdname, const _TCHAR* const* argv, const _TCHAR *envs; int ret = -1; - DPRINT(MK_STR(_tspawnve)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnve)"('%"sT"')\n", cmdname); args = argvtosT(argv, ' '); envs = argvtosT(envp, 0); @@ -421,7 +421,7 @@ int _tspawnvp(int mode, const _TCHAR* cmdname, const _TCHAR* const* argv) { _TCHAR pathname[FILENAME_MAX]; - DPRINT(MK_STR(_tspawnvp)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnvp)"('%"sT"')\n", cmdname); return _tspawnv(mode, find_execT(cmdname, pathname), argv); } @@ -436,7 +436,7 @@ int _tspawnlp(int mode, const _TCHAR* cmdname, const _TCHAR* arg0, .../*, NULL*/ int ret = -1; _TCHAR pathname[FILENAME_MAX]; - DPRINT(MK_STR(_tspawnlp)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnlp)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -461,7 +461,7 @@ int _tspawnlpe(int mode, const _TCHAR* cmdname, const _TCHAR* arg0, .../*, NULL, int ret = -1; _TCHAR pathname[FILENAME_MAX]; - DPRINT(MK_STR(_tspawnlpe)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnlpe)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -491,7 +491,7 @@ int _tspawnvpe(int mode, const _TCHAR* cmdname, const _TCHAR* const* argv, const { _TCHAR pathname[FILENAME_MAX]; - DPRINT(MK_STR(_tspawnvpe)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_tspawnvpe)"('%"sT"')\n", cmdname); return _tspawnve(mode, find_execT(cmdname, pathname), argv, envp); } @@ -505,7 +505,7 @@ int _texecl(const _TCHAR* cmdname, const _TCHAR* arg0, ...) va_list argp; int ret = -1; - DPRINT(MK_STR(_texecl)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texecl)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -523,7 +523,7 @@ int _texecl(const _TCHAR* cmdname, const _TCHAR* arg0, ...) */ int _texecv(const _TCHAR* cmdname, const _TCHAR* const* argv) { - DPRINT(MK_STR(_texecv)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texecv)"('%"sT"')\n", cmdname); return _tspawnv(P_OVERLAY, cmdname, argv); } @@ -538,7 +538,7 @@ int _texecle(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* cons _TCHAR const* const* ptr; int ret = -1; - DPRINT(MK_STR(_texecle)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texecle)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -566,7 +566,7 @@ int _texecle(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* cons */ int _texecve(const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp) { - DPRINT(MK_STR(_texecve)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texecve)"('%"sT"')\n", cmdname); return _tspawnve(P_OVERLAY, cmdname, argv, envp); } @@ -580,7 +580,7 @@ int _texeclp(const _TCHAR* cmdname, const _TCHAR* arg0, ...) int ret = -1; _TCHAR pathname[FILENAME_MAX]; - DPRINT(MK_STR(_texeclp)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texeclp)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -598,7 +598,7 @@ int _texeclp(const _TCHAR* cmdname, const _TCHAR* arg0, ...) */ int _texecvp(const _TCHAR* cmdname, const _TCHAR* const* argv) { - DPRINT(MK_STR(_texecvp)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texecvp)"('%"sT"')\n", cmdname); return _tspawnvp(P_OVERLAY, cmdname, argv); } @@ -614,7 +614,7 @@ int _texeclpe(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* con int ret = -1; _TCHAR pathname[FILENAME_MAX]; - DPRINT(MK_STR(_texeclpe)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texeclpe)"('%"sT"')\n", cmdname); va_start(argp, arg0); args = valisttosT(arg0, argp, ' '); @@ -642,7 +642,8 @@ int _texeclpe(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* con */ int _texecvpe(const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp) { - DPRINT(MK_STR(_texecvpe)"('%"sT"')\n", cmdname); + TRACE(MK_STR(_texecvpe)"('%"sT"')\n", cmdname); return _tspawnvpe(P_OVERLAY, cmdname, argv, envp); } + diff --git a/reactos/lib/sdk/crt/process/thread.c b/reactos/lib/sdk/crt/process/thread.c index 0e74ad52747..3fdab9af142 100644 --- a/reactos/lib/sdk/crt/process/thread.c +++ b/reactos/lib/sdk/crt/process/thread.c @@ -1,117 +1,115 @@ -/* - * msvcrt.dll thread functions - * - * Copyright 2000 Jon Griffiths - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include - -#include -#include - -#include - -void _amsg_exit (int errnum); -/* Index to TLS */ -DWORD MSVCRT_tls_index; - -typedef void (*_beginthread_start_routine_t)(void *); -typedef unsigned int (__stdcall *_beginthreadex_start_routine_t)(void *); - -/********************************************************************/ - -typedef struct { - _beginthread_start_routine_t start_address; - void *arglist; -} _beginthread_trampoline_t; - -/********************************************************************* - * msvcrt_get_thread_data - * - * Return the thread local storage structure. - */ -MSVCRT_thread_data *msvcrt_get_thread_data(void) -{ - MSVCRT_thread_data *ptr; - DWORD err = GetLastError(); /* need to preserve last error */ - - if (!(ptr = TlsGetValue( MSVCRT_tls_index ))) - { - if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) - _amsg_exit( _RT_THREAD ); - if (!TlsSetValue( MSVCRT_tls_index, ptr )) _amsg_exit( _RT_THREAD ); - ptr->random_seed = 1; - } - SetLastError( err ); - return ptr; -} - - -/********************************************************************* - * _beginthread_trampoline - */ -static DWORD CALLBACK _beginthread_trampoline(LPVOID arg) -{ - _beginthread_trampoline_t local_trampoline; - - /* Maybe it's just being paranoid, but freeing arg right - * away seems safer. - */ - memcpy(&local_trampoline,arg,sizeof(local_trampoline)); - free(arg); - - local_trampoline.start_address(local_trampoline.arglist); - return 0; -} - -/********************************************************************* - * _beginthread (MSVCRT.@) - */ -unsigned long _beginthread( - _beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */ - unsigned int stack_size, /* [in] Stack size for new thread or 0 */ - void *arglist) /* [in] Argument list to be passed to new thread or NULL */ -{ - _beginthread_trampoline_t* trampoline; - - DPRINT("(%p, %d, %p)\n", start_address, stack_size, arglist); - - /* Allocate the trampoline here so that it is still valid when the thread - * starts... typically after this function has returned. - * _beginthread_trampoline is responsible for freeing the trampoline - */ - trampoline=malloc(sizeof(*trampoline)); - trampoline->start_address = start_address; - trampoline->arglist = arglist; - - /* FIXME */ - return (unsigned long)CreateThread(NULL, stack_size, _beginthread_trampoline, - trampoline, 0, NULL); -} - -/********************************************************************* - * _endthread (MSVCRT.@) - */ -void CDECL _endthread(void) -{ - DPRINT("(void)\n"); - - /* FIXME */ - ExitThread(0); -} - +/* + * msvcrt.dll thread functions + * + * Copyright 2000 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include +#include + +void _amsg_exit (int errnum); +/* Index to TLS */ +DWORD MSVCRT_tls_index; + +typedef void (*_beginthread_start_routine_t)(void *); +typedef unsigned int (__stdcall *_beginthreadex_start_routine_t)(void *); + +/********************************************************************/ + +typedef struct { + _beginthread_start_routine_t start_address; + void *arglist; +} _beginthread_trampoline_t; + +/********************************************************************* + * msvcrt_get_thread_data + * + * Return the thread local storage structure. + */ +MSVCRT_thread_data *msvcrt_get_thread_data(void) +{ + MSVCRT_thread_data *ptr; + DWORD err = GetLastError(); /* need to preserve last error */ + + if (!(ptr = TlsGetValue( MSVCRT_tls_index ))) + { + if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) + _amsg_exit( _RT_THREAD ); + if (!TlsSetValue( MSVCRT_tls_index, ptr )) _amsg_exit( _RT_THREAD ); + ptr->random_seed = 1; + } + SetLastError( err ); + return ptr; +} + + +/********************************************************************* + * _beginthread_trampoline + */ +static DWORD CALLBACK _beginthread_trampoline(LPVOID arg) +{ + _beginthread_trampoline_t local_trampoline; + + /* Maybe it's just being paranoid, but freeing arg right + * away seems safer. + */ + memcpy(&local_trampoline,arg,sizeof(local_trampoline)); + free(arg); + + local_trampoline.start_address(local_trampoline.arglist); + return 0; +} + +/********************************************************************* + * _beginthread (MSVCRT.@) + */ +unsigned long _beginthread( + _beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */ + unsigned int stack_size, /* [in] Stack size for new thread or 0 */ + void *arglist) /* [in] Argument list to be passed to new thread or NULL */ +{ + _beginthread_trampoline_t* trampoline; + + TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist); + + /* Allocate the trampoline here so that it is still valid when the thread + * starts... typically after this function has returned. + * _beginthread_trampoline is responsible for freeing the trampoline + */ + trampoline=malloc(sizeof(*trampoline)); + trampoline->start_address = start_address; + trampoline->arglist = arglist; + + /* FIXME */ + return (unsigned long)CreateThread(NULL, stack_size, _beginthread_trampoline, + trampoline, 0, NULL); +} + +/********************************************************************* + * _endthread (MSVCRT.@) + */ +void CDECL _endthread(void) +{ + TRACE("(void)\n"); + + /* FIXME */ + ExitThread(0); +} + diff --git a/reactos/lib/sdk/crt/stdio/file.c b/reactos/lib/sdk/crt/stdio/file.c new file mode 100644 index 00000000000..05de7e31e78 --- /dev/null +++ b/reactos/lib/sdk/crt/stdio/file.c @@ -0,0 +1,3199 @@ +/* + * msvcrt.dll file functions + * + * Copyright 1996,1998 Marcus Meissner + * Copyright 1996 Jukka Iivonen + * Copyright 1997,2000 Uwe Bonnes + * Copyright 2000 Jon Griffiths + * Copyright 2004 Eric Pouech + * Copyright 2004 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * TODO + * Use the file flag hints O_SEQUENTIAL, O_RANDOM, O_SHORT_LIVED + */ + +#include +#include "wine/unicode.h" + +#if 0 + +/* for stat mode, permissions apply to all,owner and group */ +#define ALL_S_IREAD (MSVCRT__S_IREAD | (MSVCRT__S_IREAD >> 3) | (MSVCRT__S_IREAD >> 6)) +#define ALL_S_IWRITE (MSVCRT__S_IWRITE | (MSVCRT__S_IWRITE >> 3) | (MSVCRT__S_IWRITE >> 6)) +#define ALL_S_IEXEC (MSVCRT__S_IEXEC | (MSVCRT__S_IEXEC >> 3) | (MSVCRT__S_IEXEC >> 6)) + +/* _access() bit flags FIXME: incomplete */ +#define MSVCRT_W_OK 0x02 + +/* values for wxflag in file descriptor */ +#define WX_OPEN 0x01 +#define WX_ATEOF 0x02 +#define WX_READEOF 0x04 /* like ATEOF, but for underlying file rather than buffer */ +#define WX_DONTINHERIT 0x10 +#define WX_APPEND 0x20 +#define WX_TEXT 0x80 + +/* FIXME: this should be allocated dynamically */ +#define MSVCRT_MAX_FILES 2048 + +typedef struct { + HANDLE handle; + unsigned char wxflag; + DWORD unkn[7]; /* critical section and init flag */ +} ioinfo; + +static ioinfo MSVCRT_fdesc[MSVCRT_MAX_FILES]; + +MSVCRT_FILE MSVCRT__iob[3]; + +static int MSVCRT_fdstart = 3; /* first unallocated fd */ +static int MSVCRT_fdend = 3; /* highest allocated fd */ + +static MSVCRT_FILE* MSVCRT_fstreams[2048]; +static int MSVCRT_stream_idx; + +/* INTERNAL: process umask */ +static int MSVCRT_umask = 0; + +/* INTERNAL: Static buffer for temp file name */ +static char MSVCRT_tmpname[MAX_PATH]; + +static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e'; +static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't'; +static const unsigned int CMD = 'c' << 16 | 'm' << 8 | 'd'; +static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm'; + +#define TOUL(x) (ULONGLONG)(x) +static const ULONGLONG WCEXE = TOUL('e') << 32 | TOUL('x') << 16 | TOUL('e'); +static const ULONGLONG WCBAT = TOUL('b') << 32 | TOUL('a') << 16 | TOUL('t'); +static const ULONGLONG WCCMD = TOUL('c') << 32 | TOUL('m') << 16 | TOUL('d'); +static const ULONGLONG WCCOM = TOUL('c') << 32 | TOUL('o') << 16 | TOUL('m'); + +/* This critical section protects the tables MSVCRT_fdesc and MSVCRT_fstreams, + * and their related indexes, MSVCRT_fdstart, MSVCRT_fdend, + * and MSVCRT_stream_idx, from race conditions. + * It doesn't protect against race conditions manipulating the underlying files + * or flags; doing so would probably be better accomplished with per-file + * protection, rather than locking the whole table for every change. + */ +static CRITICAL_SECTION MSVCRT_file_cs; +#define LOCK_FILES() do { EnterCriticalSection(&MSVCRT_file_cs); } while (0) +#define UNLOCK_FILES() do { LeaveCriticalSection(&MSVCRT_file_cs); } while (0) + +static void msvcrt_stat64_to_stat(const struct MSVCRT__stat64 *buf64, struct MSVCRT__stat *buf) +{ + buf->st_dev = buf64->st_dev; + buf->st_ino = buf64->st_ino; + buf->st_mode = buf64->st_mode; + buf->st_nlink = buf64->st_nlink; + buf->st_uid = buf64->st_uid; + buf->st_gid = buf64->st_gid; + buf->st_rdev = buf64->st_rdev; + buf->st_size = buf64->st_size; + buf->st_atime = buf64->st_atime; + buf->st_mtime = buf64->st_mtime; + buf->st_ctime = buf64->st_ctime; +} + +static void msvcrt_stat64_to_stati64(const struct MSVCRT__stat64 *buf64, struct MSVCRT__stati64 *buf) +{ + buf->st_dev = buf64->st_dev; + buf->st_ino = buf64->st_ino; + buf->st_mode = buf64->st_mode; + buf->st_nlink = buf64->st_nlink; + buf->st_uid = buf64->st_uid; + buf->st_gid = buf64->st_gid; + buf->st_rdev = buf64->st_rdev; + buf->st_size = buf64->st_size; + buf->st_atime = buf64->st_atime; + buf->st_mtime = buf64->st_mtime; + buf->st_ctime = buf64->st_ctime; +} + +static inline BOOL msvcrt_is_valid_fd(int fd) +{ + return fd >= 0 && fd < MSVCRT_fdend && (MSVCRT_fdesc[fd].wxflag & WX_OPEN); +} + +/* INTERNAL: Get the HANDLE for a fd + * This doesn't lock the table, because a failure will result in + * INVALID_HANDLE_VALUE being returned, which should be handled correctly. If + * it returns a valid handle which is about to be closed, a subsequent call + * will fail, most likely in a sane way. + */ +static HANDLE msvcrt_fdtoh(int fd) +{ + if (!msvcrt_is_valid_fd(fd)) + { + WARN(":fd (%d) - no handle!\n",fd); + *MSVCRT___doserrno() = 0; + *MSVCRT__errno() = MSVCRT_EBADF; + return INVALID_HANDLE_VALUE; + } + if (MSVCRT_fdesc[fd].handle == INVALID_HANDLE_VALUE) FIXME("wtf\n"); + return MSVCRT_fdesc[fd].handle; +} + +/* INTERNAL: free a file entry fd */ +static void msvcrt_free_fd(int fd) +{ + LOCK_FILES(); + MSVCRT_fdesc[fd].handle = INVALID_HANDLE_VALUE; + MSVCRT_fdesc[fd].wxflag = 0; + TRACE(":fd (%d) freed\n",fd); + if (fd < 3) /* don't use 0,1,2 for user files */ + { + switch (fd) + { + case 0: SetStdHandle(STD_INPUT_HANDLE, NULL); break; + case 1: SetStdHandle(STD_OUTPUT_HANDLE, NULL); break; + case 2: SetStdHandle(STD_ERROR_HANDLE, NULL); break; + } + } + else + { + if (fd == MSVCRT_fdend - 1) + MSVCRT_fdend--; + if (fd < MSVCRT_fdstart) + MSVCRT_fdstart = fd; + } + UNLOCK_FILES(); +} + +/* INTERNAL: Allocate an fd slot from a Win32 HANDLE, starting from fd */ +/* caller must hold the files lock */ +static int msvcrt_alloc_fd_from(HANDLE hand, int flag, int fd) +{ + if (fd >= MSVCRT_MAX_FILES) + { + WARN(":files exhausted!\n"); + return -1; + } + MSVCRT_fdesc[fd].handle = hand; + MSVCRT_fdesc[fd].wxflag = WX_OPEN | (flag & (WX_DONTINHERIT | WX_APPEND | WX_TEXT)); + + /* locate next free slot */ + if (fd == MSVCRT_fdstart && fd == MSVCRT_fdend) + MSVCRT_fdstart = MSVCRT_fdend + 1; + else + while (MSVCRT_fdstart < MSVCRT_fdend && + MSVCRT_fdesc[MSVCRT_fdstart].handle != INVALID_HANDLE_VALUE) + MSVCRT_fdstart++; + /* update last fd in use */ + if (fd >= MSVCRT_fdend) + MSVCRT_fdend = fd + 1; + TRACE("fdstart is %d, fdend is %d\n", MSVCRT_fdstart, MSVCRT_fdend); + + switch (fd) + { + case 0: SetStdHandle(STD_INPUT_HANDLE, hand); break; + case 1: SetStdHandle(STD_OUTPUT_HANDLE, hand); break; + case 2: SetStdHandle(STD_ERROR_HANDLE, hand); break; + } + + return fd; +} + +/* INTERNAL: Allocate an fd slot from a Win32 HANDLE */ +static int msvcrt_alloc_fd(HANDLE hand, int flag) +{ + int ret; + + LOCK_FILES(); + TRACE(":handle (%p) allocating fd (%d)\n",hand,MSVCRT_fdstart); + ret = msvcrt_alloc_fd_from(hand, flag, MSVCRT_fdstart); + UNLOCK_FILES(); + return ret; +} + +/* INTERNAL: Allocate a FILE* for an fd slot */ +/* caller must hold the files lock */ +static MSVCRT_FILE* msvcrt_alloc_fp(void) +{ + unsigned int i; + + for (i = 3; i < sizeof(MSVCRT_fstreams) / sizeof(MSVCRT_fstreams[0]); i++) + { + if (!MSVCRT_fstreams[i] || MSVCRT_fstreams[i]->_flag == 0) + { + if (!MSVCRT_fstreams[i]) + { + if (!(MSVCRT_fstreams[i] = MSVCRT_calloc(sizeof(MSVCRT_FILE),1))) + return NULL; + if (i == MSVCRT_stream_idx) MSVCRT_stream_idx++; + } + return MSVCRT_fstreams[i]; + } + } + return NULL; +} + +/* INTERNAL: initialize a FILE* from an open fd */ +static int msvcrt_init_fp(MSVCRT_FILE* file, int fd, unsigned stream_flags) +{ + TRACE(":fd (%d) allocating FILE*\n",fd); + if (!msvcrt_is_valid_fd(fd)) + { + WARN(":invalid fd %d\n",fd); + *MSVCRT___doserrno() = 0; + *MSVCRT__errno() = MSVCRT_EBADF; + return -1; + } + memset(file, 0, sizeof(*file)); + file->_file = fd; + file->_flag = stream_flags; + + TRACE(":got FILE* (%p)\n",file); + return 0; +} + +/* INTERNAL: Create an inheritance data block (for spawned process) + * The inheritance block is made of: + * 00 int nb of file descriptor (NBFD) + * 04 char file flags (wxflag): repeated for each fd + * 4+NBFD HANDLE file handle: repeated for each fd + */ +unsigned msvcrt_create_io_inherit_block(WORD *size, BYTE **block) +{ + int fd; + char* wxflag_ptr; + HANDLE* handle_ptr; + + *size = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * MSVCRT_fdend; + *block = MSVCRT_calloc(*size, 1); + if (!*block) + { + *size = 0; + return FALSE; + } + wxflag_ptr = (char*)*block + sizeof(unsigned); + handle_ptr = (HANDLE*)(wxflag_ptr + MSVCRT_fdend * sizeof(char)); + + *(unsigned*)*block = MSVCRT_fdend; + for (fd = 0; fd < MSVCRT_fdend; fd++) + { + /* to be inherited, we need it to be open, and that DONTINHERIT isn't set */ + if ((MSVCRT_fdesc[fd].wxflag & (WX_OPEN | WX_DONTINHERIT)) == WX_OPEN) + { + *wxflag_ptr = MSVCRT_fdesc[fd].wxflag; + *handle_ptr = MSVCRT_fdesc[fd].handle; + } + else + { + *wxflag_ptr = 0; + *handle_ptr = INVALID_HANDLE_VALUE; + } + wxflag_ptr++; handle_ptr++; + } + return TRUE; +} + +/* INTERNAL: Set up all file descriptors, + * as well as default streams (stdin, stderr and stdout) + */ +void msvcrt_init_io(void) +{ + STARTUPINFOA si; + int i; + + InitializeCriticalSection(&MSVCRT_file_cs); + MSVCRT_file_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MSVCRT_file_cs"); + GetStartupInfoA(&si); + if (si.cbReserved2 != 0 && si.lpReserved2 != NULL) + { + char* wxflag_ptr; + HANDLE* handle_ptr; + + MSVCRT_fdend = *(unsigned*)si.lpReserved2; + + wxflag_ptr = (char*)(si.lpReserved2 + sizeof(unsigned)); + handle_ptr = (HANDLE*)(wxflag_ptr + MSVCRT_fdend * sizeof(char)); + + MSVCRT_fdend = min(MSVCRT_fdend, sizeof(MSVCRT_fdesc) / sizeof(MSVCRT_fdesc[0])); + for (i = 0; i < MSVCRT_fdend; i++) + { + if ((*wxflag_ptr & WX_OPEN) && *handle_ptr != INVALID_HANDLE_VALUE) + { + MSVCRT_fdesc[i].wxflag = *wxflag_ptr; + MSVCRT_fdesc[i].handle = *handle_ptr; + } + else + { + MSVCRT_fdesc[i].wxflag = 0; + MSVCRT_fdesc[i].handle = INVALID_HANDLE_VALUE; + } + wxflag_ptr++; handle_ptr++; + } + for (MSVCRT_fdstart = 3; MSVCRT_fdstart < MSVCRT_fdend; MSVCRT_fdstart++) + if (MSVCRT_fdesc[MSVCRT_fdstart].handle == INVALID_HANDLE_VALUE) break; + } + + if (!(MSVCRT_fdesc[0].wxflag & WX_OPEN) || MSVCRT_fdesc[0].handle == INVALID_HANDLE_VALUE) + { + DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), + GetCurrentProcess(), &MSVCRT_fdesc[0].handle, 0, TRUE, + DUPLICATE_SAME_ACCESS); + MSVCRT_fdesc[0].wxflag = WX_OPEN | WX_TEXT; + } + if (!(MSVCRT_fdesc[1].wxflag & WX_OPEN) || MSVCRT_fdesc[1].handle == INVALID_HANDLE_VALUE) + { + DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), + GetCurrentProcess(), &MSVCRT_fdesc[1].handle, 0, TRUE, + DUPLICATE_SAME_ACCESS); + MSVCRT_fdesc[1].wxflag = WX_OPEN | WX_TEXT; + } + if (!(MSVCRT_fdesc[2].wxflag & WX_OPEN) || MSVCRT_fdesc[2].handle == INVALID_HANDLE_VALUE) + { + DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), + GetCurrentProcess(), &MSVCRT_fdesc[2].handle, 0, TRUE, + DUPLICATE_SAME_ACCESS); + MSVCRT_fdesc[2].wxflag = WX_OPEN | WX_TEXT; + } + + TRACE(":handles (%p)(%p)(%p)\n",MSVCRT_fdesc[0].handle, + MSVCRT_fdesc[1].handle,MSVCRT_fdesc[2].handle); + + memset(MSVCRT__iob,0,3*sizeof(MSVCRT_FILE)); + for (i = 0; i < 3; i++) + { + /* FILE structs for stdin/out/err are static and never deleted */ + MSVCRT_fstreams[i] = &MSVCRT__iob[i]; + MSVCRT__iob[i]._file = i; + MSVCRT__iob[i]._tmpfname = NULL; + MSVCRT__iob[i]._flag = (i == 0) ? MSVCRT__IOREAD : MSVCRT__IOWRT; + } + MSVCRT_stream_idx = 3; +} + +/* INTERNAL: Flush stdio file buffer */ +static int msvcrt_flush_buffer(MSVCRT_FILE* file) +{ + if(file->_bufsiz) { + int cnt=file->_ptr-file->_base; + if(cnt>0 && MSVCRT__write(file->_file, file->_base, cnt) != cnt) { + file->_flag |= MSVCRT__IOERR; + return MSVCRT_EOF; + } + file->_ptr=file->_base; + file->_cnt=file->_bufsiz; + } + return 0; +} + +/* INTERNAL: Allocate stdio file buffer */ +static void msvcrt_alloc_buffer(MSVCRT_FILE* file) +{ + file->_base = MSVCRT_calloc(MSVCRT_BUFSIZ,1); + if(file->_base) { + file->_bufsiz = MSVCRT_BUFSIZ; + file->_flag |= MSVCRT__IOMYBUF; + } else { + file->_base = (char*)(&file->_charbuf); + /* put here 2 ??? */ + file->_bufsiz = sizeof(file->_charbuf); + } + file->_ptr = file->_base; + file->_cnt = 0; +} + +/* INTERNAL: Convert integer to base32 string (0-9a-v), 0 becomes "" */ +static void msvcrt_int_to_base32(int num, char *str) +{ + char *p; + int n = num; + int digits = 0; + + while (n != 0) + { + n >>= 5; + digits++; + } + p = str + digits; + *p = 0; + while (--p >= str) + { + *p = (num & 31) + '0'; + if (*p > '9') + *p += ('a' - '0' - 10); + num >>= 5; + } +} + +/********************************************************************* + * __p__iob(MSVCRT.@) + */ +MSVCRT_FILE * CDECL __p__iob(void) +{ + return &MSVCRT__iob[0]; +} + +/********************************************************************* + * _access (MSVCRT.@) + */ +int CDECL MSVCRT__access(const char *filename, int mode) +{ + DWORD attr = GetFileAttributesA(filename); + + TRACE("(%s,%d) %d\n",filename,mode,attr); + + if (!filename || attr == INVALID_FILE_ATTRIBUTES) + { + msvcrt_set_errno(GetLastError()); + return -1; + } + if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & MSVCRT_W_OK)) + { + msvcrt_set_errno(ERROR_ACCESS_DENIED); + return -1; + } + return 0; +} + +/********************************************************************* + * _waccess (MSVCRT.@) + */ +int CDECL _waccess(const MSVCRT_wchar_t *filename, int mode) +{ + DWORD attr = GetFileAttributesW(filename); + + TRACE("(%s,%d) %d\n",debugstr_w(filename),mode,attr); + + if (!filename || attr == INVALID_FILE_ATTRIBUTES) + { + msvcrt_set_errno(GetLastError()); + return -1; + } + if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & MSVCRT_W_OK)) + { + msvcrt_set_errno(ERROR_ACCESS_DENIED); + return -1; + } + return 0; +} + +/********************************************************************* + * _chmod (MSVCRT.@) + */ +int CDECL MSVCRT__chmod(const char *path, int flags) +{ + DWORD oldFlags = GetFileAttributesA(path); + + if (oldFlags != INVALID_FILE_ATTRIBUTES) + { + DWORD newFlags = (flags & MSVCRT__S_IWRITE)? oldFlags & ~FILE_ATTRIBUTE_READONLY: + oldFlags | FILE_ATTRIBUTE_READONLY; + + if (newFlags == oldFlags || SetFileAttributesA(path, newFlags)) + return 0; + } + msvcrt_set_errno(GetLastError()); + return -1; +} + +/********************************************************************* + * _wchmod (MSVCRT.@) + */ +int CDECL _wchmod(const MSVCRT_wchar_t *path, int flags) +{ + DWORD oldFlags = GetFileAttributesW(path); + + if (oldFlags != INVALID_FILE_ATTRIBUTES) + { + DWORD newFlags = (flags & MSVCRT__S_IWRITE)? oldFlags & ~FILE_ATTRIBUTE_READONLY: + oldFlags | FILE_ATTRIBUTE_READONLY; + + if (newFlags == oldFlags || SetFileAttributesW(path, newFlags)) + return 0; + } + msvcrt_set_errno(GetLastError()); + return -1; +} + +/********************************************************************* + * _unlink (MSVCRT.@) + */ +int CDECL MSVCRT__unlink(const char *path) +{ + TRACE("%s\n",debugstr_a(path)); + if(DeleteFileA(path)) + return 0; + TRACE("failed (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + return -1; +} + +/********************************************************************* + * _wunlink (MSVCRT.@) + */ +int CDECL _wunlink(const MSVCRT_wchar_t *path) +{ + TRACE("(%s)\n",debugstr_w(path)); + if(DeleteFileW(path)) + return 0; + TRACE("failed (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + return -1; +} + +/* _flushall calls MSVCRT_fflush which calls _flushall */ +int CDECL MSVCRT_fflush(MSVCRT_FILE* file); + +/********************************************************************* + * _flushall (MSVCRT.@) + */ +int CDECL _flushall(void) +{ + int i, num_flushed = 0; + + LOCK_FILES(); + for (i = 3; i < MSVCRT_stream_idx; i++) + if (MSVCRT_fstreams[i] && MSVCRT_fstreams[i]->_flag) + { +#if 0 + /* FIXME: flush, do not commit */ + if (_commit(i) == -1) + if (MSVCRT_fstreams[i]) + MSVCRT_fstreams[i]->_flag |= MSVCRT__IOERR; +#endif + if(MSVCRT_fstreams[i]->_flag & MSVCRT__IOWRT) { + MSVCRT_fflush(MSVCRT_fstreams[i]); + num_flushed++; + } + } + UNLOCK_FILES(); + + TRACE(":flushed (%d) handles\n",num_flushed); + return num_flushed; +} + +/********************************************************************* + * fflush (MSVCRT.@) + */ +int CDECL MSVCRT_fflush(MSVCRT_FILE* file) +{ + if(!file) { + _flushall(); + } else if(file->_flag & MSVCRT__IOWRT) { + int res=msvcrt_flush_buffer(file); + return res; + } + return 0; +} + +/********************************************************************* + * _close (MSVCRT.@) + */ +int CDECL MSVCRT__close(int fd) +{ + HANDLE hand; + int ret; + + LOCK_FILES(); + hand = msvcrt_fdtoh(fd); + TRACE(":fd (%d) handle (%p)\n",fd,hand); + if (hand == INVALID_HANDLE_VALUE) + ret = -1; + else if (!CloseHandle(hand)) + { + WARN(":failed-last error (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + ret = -1; + } + else + { + msvcrt_free_fd(fd); + ret = 0; + } + UNLOCK_FILES(); + TRACE(":ok\n"); + return ret; +} + +/********************************************************************* + * _commit (MSVCRT.@) + */ +int CDECL _commit(int fd) +{ + HANDLE hand = msvcrt_fdtoh(fd); + + TRACE(":fd (%d) handle (%p)\n",fd,hand); + if (hand == INVALID_HANDLE_VALUE) + return -1; + + if (!FlushFileBuffers(hand)) + { + if (GetLastError() == ERROR_INVALID_HANDLE) + { + /* FlushFileBuffers fails for console handles + * so we ignore this error. + */ + return 0; + } + TRACE(":failed-last error (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + return -1; + } + TRACE(":ok\n"); + return 0; +} + +/********************************************************************* + * _dup2 (MSVCRT.@) + * NOTES + * MSDN isn't clear on this point, but the remarks for _pipe + * indicate file descriptors duplicated with _dup and _dup2 are always + * inheritable. + */ +int CDECL MSVCRT__dup2(int od, int nd) +{ + int ret; + + TRACE("(od=%d, nd=%d)\n", od, nd); + LOCK_FILES(); + if (nd < MSVCRT_MAX_FILES && msvcrt_is_valid_fd(od)) + { + HANDLE handle; + + if (DuplicateHandle(GetCurrentProcess(), MSVCRT_fdesc[od].handle, + GetCurrentProcess(), &handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) + { + int wxflag = MSVCRT_fdesc[od].wxflag & ~MSVCRT__O_NOINHERIT; + + if (msvcrt_is_valid_fd(nd)) + MSVCRT__close(nd); + ret = msvcrt_alloc_fd_from(handle, wxflag, nd); + if (ret == -1) + { + CloseHandle(handle); + *MSVCRT__errno() = MSVCRT_EMFILE; + } + else + { + /* _dup2 returns 0, not nd, on success */ + ret = 0; + } + } + else + { + ret = -1; + msvcrt_set_errno(GetLastError()); + } + } + else + { + *MSVCRT__errno() = MSVCRT_EBADF; + ret = -1; + } + UNLOCK_FILES(); + return ret; +} + +/********************************************************************* + * _dup (MSVCRT.@) + */ +int CDECL MSVCRT__dup(int od) +{ + int fd, ret; + + LOCK_FILES(); + fd = MSVCRT_fdstart; + if (MSVCRT__dup2(od, fd) == 0) + ret = fd; + else + ret = -1; + UNLOCK_FILES(); + return ret; +} + +/********************************************************************* + * _eof (MSVCRT.@) + */ +int CDECL _eof(int fd) +{ + DWORD curpos,endpos; + LONG hcurpos,hendpos; + HANDLE hand = msvcrt_fdtoh(fd); + + TRACE(":fd (%d) handle (%p)\n",fd,hand); + + if (hand == INVALID_HANDLE_VALUE) + return -1; + + if (MSVCRT_fdesc[fd].wxflag & WX_ATEOF) return TRUE; + + /* Otherwise we do it the hard way */ + hcurpos = hendpos = 0; + curpos = SetFilePointer(hand, 0, &hcurpos, FILE_CURRENT); + endpos = SetFilePointer(hand, 0, &hendpos, FILE_END); + + if (curpos == endpos && hcurpos == hendpos) + { + /* FIXME: shouldn't WX_ATEOF be set here? */ + return TRUE; + } + + SetFilePointer(hand, curpos, &hcurpos, FILE_BEGIN); + return FALSE; +} + +/********************************************************************* + * _fcloseall (MSVCRT.@) + */ +int CDECL MSVCRT__fcloseall(void) +{ + int num_closed = 0, i; + + LOCK_FILES(); + for (i = 3; i < MSVCRT_stream_idx; i++) + if (MSVCRT_fstreams[i] && MSVCRT_fstreams[i]->_flag && + !MSVCRT_fclose(MSVCRT_fstreams[i])) + num_closed++; + UNLOCK_FILES(); + + TRACE(":closed (%d) handles\n",num_closed); + return num_closed; +} + +/* free everything on process exit */ +void msvcrt_free_io(void) +{ + MSVCRT__fcloseall(); + /* The Win32 _fcloseall() function explicitly doesn't close stdin, + * stdout, and stderr (unlike GNU), so we need to fclose() them here + * or they won't get flushed. + */ + MSVCRT_fclose(&MSVCRT__iob[0]); + MSVCRT_fclose(&MSVCRT__iob[1]); + MSVCRT_fclose(&MSVCRT__iob[2]); + MSVCRT_file_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&MSVCRT_file_cs); +} + +/********************************************************************* + * _lseeki64 (MSVCRT.@) + */ +__int64 CDECL MSVCRT__lseeki64(int fd, __int64 offset, int whence) +{ + HANDLE hand = msvcrt_fdtoh(fd); + LARGE_INTEGER ofs, ret; + + TRACE(":fd (%d) handle (%p)\n",fd,hand); + if (hand == INVALID_HANDLE_VALUE) + return -1; + + if (whence < 0 || whence > 2) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return -1; + } + + TRACE(":fd (%d) to %s pos %s\n", + fd,wine_dbgstr_longlong(offset), + (whence==SEEK_SET)?"SEEK_SET": + (whence==SEEK_CUR)?"SEEK_CUR": + (whence==SEEK_END)?"SEEK_END":"UNKNOWN"); + + ofs.QuadPart = offset; + if (SetFilePointerEx(hand, ofs, &ret, whence)) + { + MSVCRT_fdesc[fd].wxflag &= ~(WX_ATEOF|WX_READEOF); + /* FIXME: What if we seek _to_ EOF - is EOF set? */ + + return ret.QuadPart; + } + TRACE(":error-last error (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + return -1; +} + +/********************************************************************* + * _lseek (MSVCRT.@) + */ +LONG CDECL MSVCRT__lseek(int fd, LONG offset, int whence) +{ + return MSVCRT__lseeki64(fd, offset, whence); +} + +/********************************************************************* + * _locking (MSVCRT.@) + * + * This is untested; the underlying LockFile doesn't work yet. + */ +int CDECL MSVCRT__locking(int fd, int mode, LONG nbytes) +{ + BOOL ret; + DWORD cur_locn; + HANDLE hand = msvcrt_fdtoh(fd); + + TRACE(":fd (%d) handle (%p)\n",fd,hand); + if (hand == INVALID_HANDLE_VALUE) + return -1; + + if (mode < 0 || mode > 4) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return -1; + } + + TRACE(":fd (%d) by 0x%08x mode %s\n", + fd,nbytes,(mode==MSVCRT__LK_UNLCK)?"_LK_UNLCK": + (mode==MSVCRT__LK_LOCK)?"_LK_LOCK": + (mode==MSVCRT__LK_NBLCK)?"_LK_NBLCK": + (mode==MSVCRT__LK_RLCK)?"_LK_RLCK": + (mode==MSVCRT__LK_NBRLCK)?"_LK_NBRLCK": + "UNKNOWN"); + + if ((cur_locn = SetFilePointer(hand, 0L, NULL, SEEK_CUR)) == INVALID_SET_FILE_POINTER) + { + FIXME ("Seek failed\n"); + *MSVCRT__errno() = MSVCRT_EINVAL; /* FIXME */ + return -1; + } + if (mode == MSVCRT__LK_LOCK || mode == MSVCRT__LK_RLCK) + { + int nretry = 10; + ret = 1; /* just to satisfy gcc */ + while (nretry--) + { + ret = LockFile(hand, cur_locn, 0L, nbytes, 0L); + if (ret) break; + Sleep(1); + } + } + else if (mode == MSVCRT__LK_UNLCK) + ret = UnlockFile(hand, cur_locn, 0L, nbytes, 0L); + else + ret = LockFile(hand, cur_locn, 0L, nbytes, 0L); + /* FIXME - what about error settings? */ + return ret ? 0 : -1; +} + +/********************************************************************* + * fseek (MSVCRT.@) + */ +int CDECL MSVCRT_fseek(MSVCRT_FILE* file, long offset, int whence) +{ + /* Flush output if needed */ + if(file->_flag & MSVCRT__IOWRT) + msvcrt_flush_buffer(file); + + if(whence == SEEK_CUR && file->_flag & MSVCRT__IOREAD ) { + offset -= file->_cnt; + } + /* Discard buffered input */ + file->_cnt = 0; + file->_ptr = file->_base; + /* Reset direction of i/o */ + if(file->_flag & MSVCRT__IORW) { + file->_flag &= ~(MSVCRT__IOREAD|MSVCRT__IOWRT); + } + /* Clear end of file flag */ + file->_flag &= ~MSVCRT__IOEOF; + return (MSVCRT__lseek(file->_file,offset,whence) == -1)?-1:0; +} + +/********************************************************************* + * _chsize (MSVCRT.@) + */ +int CDECL _chsize(int fd, long size) +{ + LONG cur, pos; + HANDLE handle; + BOOL ret = FALSE; + + TRACE("(fd=%d, size=%ld)\n", fd, size); + + LOCK_FILES(); + + handle = msvcrt_fdtoh(fd); + if (handle != INVALID_HANDLE_VALUE) + { + /* save the current file pointer */ + cur = MSVCRT__lseek(fd, 0, SEEK_CUR); + if (cur >= 0) + { + pos = MSVCRT__lseek(fd, size, SEEK_SET); + if (pos >= 0) + { + ret = SetEndOfFile(handle); + if (!ret) msvcrt_set_errno(GetLastError()); + } + + /* restore the file pointer */ + MSVCRT__lseek(fd, cur, SEEK_SET); + } + } + + UNLOCK_FILES(); + return ret ? 0 : -1; +} + +/********************************************************************* + * clearerr (MSVCRT.@) + */ +void CDECL MSVCRT_clearerr(MSVCRT_FILE* file) +{ + TRACE(":file (%p) fd (%d)\n",file,file->_file); + file->_flag &= ~(MSVCRT__IOERR | MSVCRT__IOEOF); +} + +/********************************************************************* + * rewind (MSVCRT.@) + */ +void CDECL MSVCRT_rewind(MSVCRT_FILE* file) +{ + TRACE(":file (%p) fd (%d)\n",file,file->_file); + MSVCRT_fseek(file, 0L, SEEK_SET); + MSVCRT_clearerr(file); +} + +static int msvcrt_get_flags(const char* mode, int *open_flags, int* stream_flags) +{ + int plus = strchr(mode, '+') != NULL; + + switch(*mode++) + { + case 'R': case 'r': + *open_flags = plus ? MSVCRT__O_RDWR : MSVCRT__O_RDONLY; + *stream_flags = plus ? MSVCRT__IORW : MSVCRT__IOREAD; + break; + case 'W': case 'w': + *open_flags = MSVCRT__O_CREAT | MSVCRT__O_TRUNC | (plus ? MSVCRT__O_RDWR : MSVCRT__O_WRONLY); + *stream_flags = plus ? MSVCRT__IORW : MSVCRT__IOWRT; + break; + case 'A': case 'a': + *open_flags = MSVCRT__O_CREAT | MSVCRT__O_APPEND | (plus ? MSVCRT__O_RDWR : MSVCRT__O_WRONLY); + *stream_flags = plus ? MSVCRT__IORW : MSVCRT__IOWRT; + break; + default: + return -1; + } + + while (*mode) + switch (*mode++) + { + case 'B': case 'b': + *open_flags |= MSVCRT__O_BINARY; + *open_flags &= ~MSVCRT__O_TEXT; + break; + case 'T': case 't': + *open_flags |= MSVCRT__O_TEXT; + *open_flags &= ~MSVCRT__O_BINARY; + break; + case '+': + break; + default: + FIXME(":unknown flag %c not supported\n",mode[-1]); + } + return 0; +} + +/********************************************************************* + * _fdopen (MSVCRT.@) + */ +MSVCRT_FILE* CDECL MSVCRT__fdopen(int fd, const char *mode) +{ + int open_flags, stream_flags; + MSVCRT_FILE* file; + + if (msvcrt_get_flags(mode, &open_flags, &stream_flags) == -1) return NULL; + + LOCK_FILES(); + if (!(file = msvcrt_alloc_fp())) + file = NULL; + else if (msvcrt_init_fp(file, fd, stream_flags) == -1) + { + file->_flag = 0; + file = NULL; + } + else TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,mode,file); + UNLOCK_FILES(); + + return file; +} + +/********************************************************************* + * _wfdopen (MSVCRT.@) + */ +MSVCRT_FILE* CDECL MSVCRT__wfdopen(int fd, const MSVCRT_wchar_t *mode) +{ + unsigned mlen = strlenW(mode); + char *modea = MSVCRT_calloc(mlen + 1, 1); + MSVCRT_FILE* file = NULL; + int open_flags, stream_flags; + + if (modea && + WideCharToMultiByte(CP_ACP,0,mode,mlen,modea,mlen,NULL,NULL)) + { + if (msvcrt_get_flags(modea, &open_flags, &stream_flags) == -1) return NULL; + LOCK_FILES(); + if (!(file = msvcrt_alloc_fp())) + file = NULL; + else if (msvcrt_init_fp(file, fd, stream_flags) == -1) + { + file->_flag = 0; + file = NULL; + } + else + { + if (file) + MSVCRT_rewind(file); /* FIXME: is this needed ??? */ + TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,debugstr_w(mode),file); + } + UNLOCK_FILES(); + } + return file; +} + +/********************************************************************* + * _filelength (MSVCRT.@) + */ +LONG CDECL MSVCRT__filelength(int fd) +{ + LONG curPos = MSVCRT__lseek(fd, 0, SEEK_CUR); + if (curPos != -1) + { + LONG endPos = MSVCRT__lseek(fd, 0, SEEK_END); + if (endPos != -1) + { + if (endPos != curPos) + MSVCRT__lseek(fd, curPos, SEEK_SET); + return endPos; + } + } + return -1; +} + +/********************************************************************* + * _filelengthi64 (MSVCRT.@) + */ +__int64 CDECL MSVCRT__filelengthi64(int fd) +{ + __int64 curPos = MSVCRT__lseeki64(fd, 0, SEEK_CUR); + if (curPos != -1) + { + __int64 endPos = MSVCRT__lseeki64(fd, 0, SEEK_END); + if (endPos != -1) + { + if (endPos != curPos) + MSVCRT__lseeki64(fd, curPos, SEEK_SET); + return endPos; + } + } + return -1; +} + +/********************************************************************* + * _fileno (MSVCRT.@) + */ +int CDECL MSVCRT__fileno(MSVCRT_FILE* file) +{ + TRACE(":FILE* (%p) fd (%d)\n",file,file->_file); + return file->_file; +} + +/********************************************************************* + * _fstat64 (MSVCRT.@) + */ +int CDECL MSVCRT__fstat64(int fd, struct MSVCRT__stat64* buf) +{ + DWORD dw; + DWORD type; + BY_HANDLE_FILE_INFORMATION hfi; + HANDLE hand = msvcrt_fdtoh(fd); + + TRACE(":fd (%d) stat (%p)\n",fd,buf); + if (hand == INVALID_HANDLE_VALUE) + return -1; + + if (!buf) + { + WARN(":failed-NULL buf\n"); + msvcrt_set_errno(ERROR_INVALID_PARAMETER); + return -1; + } + + memset(&hfi, 0, sizeof(hfi)); + memset(buf, 0, sizeof(struct MSVCRT__stat64)); + type = GetFileType(hand); + if (type == FILE_TYPE_PIPE) + { + buf->st_dev = buf->st_rdev = fd; + buf->st_mode = S_IFIFO; + buf->st_nlink = 1; + } + else if (type == FILE_TYPE_CHAR) + { + buf->st_dev = buf->st_rdev = fd; + buf->st_mode = S_IFCHR; + buf->st_nlink = 1; + } + else /* FILE_TYPE_DISK etc. */ + { + if (!GetFileInformationByHandle(hand, &hfi)) + { + WARN(":failed-last error (%d)\n",GetLastError()); + msvcrt_set_errno(ERROR_INVALID_PARAMETER); + return -1; + } + buf->st_mode = S_IFREG | S_IREAD; + if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + buf->st_mode |= S_IWRITE; + 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; + buf->st_nlink = hfi.nNumberOfLinks; + } + TRACE(":dwFileAttributes = 0x%x, mode set to 0x%x\n",hfi.dwFileAttributes, + buf->st_mode); + return 0; +} + +/********************************************************************* + * _fstati64 (MSVCRT.@) + */ +int CDECL MSVCRT__fstati64(int fd, struct MSVCRT__stati64* buf) +{ + int ret; + struct MSVCRT__stat64 buf64; + + ret = MSVCRT__fstat64(fd, &buf64); + if (!ret) + msvcrt_stat64_to_stati64(&buf64, buf); + return ret; +} + +/********************************************************************* + * _fstat (MSVCRT.@) + */ +int CDECL MSVCRT__fstat(int fd, struct MSVCRT__stat* buf) +{ int ret; + struct MSVCRT__stat64 buf64; + + ret = MSVCRT__fstat64(fd, &buf64); + if (!ret) + msvcrt_stat64_to_stat(&buf64, buf); + return ret; +} + +/********************************************************************* + * _futime (MSVCRT.@) + */ +int CDECL _futime(int fd, struct MSVCRT__utimbuf *t) +{ + HANDLE hand = msvcrt_fdtoh(fd); + FILETIME at, wt; + + if (!t) + { + MSVCRT_time_t currTime; + MSVCRT_time(&currTime); + RtlSecondsSince1970ToTime(currTime, (LARGE_INTEGER *)&at); + wt = at; + } + else + { + RtlSecondsSince1970ToTime(t->actime, (LARGE_INTEGER *)&at); + if (t->actime == t->modtime) + wt = at; + else + RtlSecondsSince1970ToTime(t->modtime, (LARGE_INTEGER *)&wt); + } + + if (!SetFileTime(hand, NULL, &at, &wt)) + { + msvcrt_set_errno(GetLastError()); + return -1 ; + } + return 0; +} + +/********************************************************************* + * _get_osfhandle (MSVCRT.@) + */ +long CDECL _get_osfhandle(int fd) +{ + HANDLE hand = msvcrt_fdtoh(fd); + TRACE(":fd (%d) handle (%p)\n",fd,hand); + + return (long)hand; +} + +/********************************************************************* + * _isatty (MSVCRT.@) + */ +int CDECL _isatty(int fd) +{ + HANDLE hand = msvcrt_fdtoh(fd); + + TRACE(":fd (%d) handle (%p)\n",fd,hand); + if (hand == INVALID_HANDLE_VALUE) + return 0; + + return GetFileType(hand) == FILE_TYPE_CHAR? 1 : 0; +} + +/********************************************************************* + * _mktemp (MSVCRT.@) + */ +char * CDECL _mktemp(char *pattern) +{ + int numX = 0; + char *retVal = pattern; + int id; + char letter = 'a'; + + while(*pattern) + numX = (*pattern++ == 'X')? numX + 1 : 0; + if (numX < 5) + return NULL; + pattern--; + id = GetCurrentProcessId(); + numX = 6; + while(numX--) + { + int tempNum = id / 10; + *pattern-- = id - (tempNum * 10) + '0'; + id = tempNum; + } + pattern++; + do + { + *pattern = letter++; + if (GetFileAttributesA(retVal) == INVALID_FILE_ATTRIBUTES && + GetLastError() == ERROR_FILE_NOT_FOUND) + return retVal; + } while(letter <= 'z'); + return NULL; +} + +/********************************************************************* + * _wmktemp (MSVCRT.@) + */ +MSVCRT_wchar_t * CDECL _wmktemp(MSVCRT_wchar_t *pattern) +{ + int numX = 0; + MSVCRT_wchar_t *retVal = pattern; + int id; + MSVCRT_wchar_t letter = 'a'; + + while(*pattern) + numX = (*pattern++ == 'X')? numX + 1 : 0; + if (numX < 5) + return NULL; + pattern--; + id = GetCurrentProcessId(); + numX = 6; + while(numX--) + { + int tempNum = id / 10; + *pattern-- = id - (tempNum * 10) + '0'; + id = tempNum; + } + pattern++; + do + { + if (GetFileAttributesW(retVal) == INVALID_FILE_ATTRIBUTES && + GetLastError() == ERROR_FILE_NOT_FOUND) + return retVal; + *pattern = letter++; + } while(letter != '|'); + return NULL; +} + +static unsigned split_oflags(unsigned oflags) +{ + int wxflags = 0; + unsigned unsupp; /* until we support everything */ + + if (oflags & MSVCRT__O_APPEND) wxflags |= WX_APPEND; + if (oflags & MSVCRT__O_BINARY) {/* Nothing to do */} + else if (oflags & MSVCRT__O_TEXT) wxflags |= WX_TEXT; + else if (*__p__fmode() & MSVCRT__O_BINARY) {/* Nothing to do */} + else wxflags |= WX_TEXT; /* default to TEXT*/ + if (oflags & MSVCRT__O_NOINHERIT) wxflags |= WX_DONTINHERIT; + + if ((unsupp = oflags & ~( + MSVCRT__O_BINARY|MSVCRT__O_TEXT|MSVCRT__O_APPEND| + MSVCRT__O_TRUNC|MSVCRT__O_EXCL|MSVCRT__O_CREAT| + MSVCRT__O_RDWR|MSVCRT__O_WRONLY|MSVCRT__O_TEMPORARY| + MSVCRT__O_NOINHERIT| + MSVCRT__O_SEQUENTIAL|MSVCRT__O_RANDOM|MSVCRT__O_SHORT_LIVED + ))) + ERR(":unsupported oflags 0x%04x\n",unsupp); + + return wxflags; +} + +/********************************************************************* + * _pipe (MSVCRT.@) + */ +int CDECL MSVCRT__pipe(int *pfds, unsigned int psize, int textmode) +{ + int ret = -1; + SECURITY_ATTRIBUTES sa; + HANDLE readHandle, writeHandle; + + if (!pfds) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return -1; + } + + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = !(textmode & MSVCRT__O_NOINHERIT); + sa.lpSecurityDescriptor = NULL; + if (CreatePipe(&readHandle, &writeHandle, &sa, psize)) + { + unsigned int wxflags = split_oflags(textmode); + int fd; + + LOCK_FILES(); + fd = msvcrt_alloc_fd(readHandle, wxflags); + if (fd != -1) + { + pfds[0] = fd; + fd = msvcrt_alloc_fd(writeHandle, wxflags); + if (fd != -1) + { + pfds[1] = fd; + ret = 0; + } + else + { + MSVCRT__close(pfds[0]); + CloseHandle(writeHandle); + *MSVCRT__errno() = MSVCRT_EMFILE; + } + } + else + { + CloseHandle(readHandle); + CloseHandle(writeHandle); + *MSVCRT__errno() = MSVCRT_EMFILE; + } + UNLOCK_FILES(); + } + else + msvcrt_set_errno(GetLastError()); + + return ret; +} + +/********************************************************************* + * _sopen (MSVCRT.@) + */ +int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... ) +{ + va_list ap; + int pmode; + DWORD access = 0, creation = 0, attrib; + DWORD sharing; + int wxflag = 0, fd; + HANDLE hand; + SECURITY_ATTRIBUTES sa; + + + TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n", + path, oflags, shflags); + + wxflag = split_oflags(oflags); + switch (oflags & (MSVCRT__O_RDONLY | MSVCRT__O_WRONLY | MSVCRT__O_RDWR)) + { + case MSVCRT__O_RDONLY: access |= GENERIC_READ; break; + case MSVCRT__O_WRONLY: access |= GENERIC_WRITE; break; + case MSVCRT__O_RDWR: access |= GENERIC_WRITE | GENERIC_READ; break; + } + + if (oflags & MSVCRT__O_CREAT) + { + va_start(ap, shflags); + pmode = va_arg(ap, int); + va_end(ap); + + if(pmode & ~(MSVCRT__S_IREAD | MSVCRT__S_IWRITE)) + FIXME(": pmode 0x%04x ignored\n", pmode); + else + WARN(": pmode 0x%04x ignored\n", pmode); + + if (oflags & MSVCRT__O_EXCL) + creation = CREATE_NEW; + else if (oflags & MSVCRT__O_TRUNC) + creation = CREATE_ALWAYS; + else + creation = OPEN_ALWAYS; + } + else /* no MSVCRT__O_CREAT */ + { + if (oflags & MSVCRT__O_TRUNC) + creation = TRUNCATE_EXISTING; + else + creation = OPEN_EXISTING; + } + + switch( shflags ) + { + case MSVCRT__SH_DENYRW: + sharing = 0L; + break; + case MSVCRT__SH_DENYWR: + sharing = FILE_SHARE_READ; + break; + case MSVCRT__SH_DENYRD: + sharing = FILE_SHARE_WRITE; + break; + case MSVCRT__SH_DENYNO: + sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; + break; + default: + ERR( "Unhandled shflags 0x%x\n", shflags ); + return -1; + } + attrib = FILE_ATTRIBUTE_NORMAL; + + if (oflags & MSVCRT__O_TEMPORARY) + { + attrib |= FILE_FLAG_DELETE_ON_CLOSE; + access |= DELETE; + sharing |= FILE_SHARE_DELETE; + } + + sa.nLength = sizeof( SECURITY_ATTRIBUTES ); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = (oflags & MSVCRT__O_NOINHERIT) ? FALSE : TRUE; + + hand = CreateFileA(path, access, sharing, &sa, creation, attrib, 0); + + if (hand == INVALID_HANDLE_VALUE) { + WARN(":failed-last error (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + return -1; + } + + fd = msvcrt_alloc_fd(hand, wxflag); + + TRACE(":fd (%d) handle (%p)\n",fd, hand); + return fd; +} + +/********************************************************************* + * _wsopen (MSVCRT.@) + */ +int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t* path, int oflags, int shflags, ... ) +{ + const unsigned int len = strlenW(path); + char *patha = MSVCRT_calloc(len + 1,1); + va_list ap; + int pmode; + + va_start(ap, shflags); + pmode = va_arg(ap, int); + va_end(ap); + + if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL)) + { + int retval = MSVCRT__sopen(patha,oflags,shflags,pmode); + MSVCRT_free(patha); + return retval; + } + + msvcrt_set_errno(GetLastError()); + return -1; +} + +/********************************************************************* + * _open (MSVCRT.@) + */ +int CDECL MSVCRT__open( const char *path, int flags, ... ) +{ + va_list ap; + + if (flags & MSVCRT__O_CREAT) + { + int pmode; + va_start(ap, flags); + pmode = va_arg(ap, int); + va_end(ap); + return MSVCRT__sopen( path, flags, MSVCRT__SH_DENYNO, pmode ); + } + else + return MSVCRT__sopen( path, flags, MSVCRT__SH_DENYNO); +} + +/********************************************************************* + * _wopen (MSVCRT.@) + */ +int CDECL _wopen(const MSVCRT_wchar_t *path,int flags,...) +{ + const unsigned int len = strlenW(path); + char *patha = MSVCRT_calloc(len + 1,1); + va_list ap; + int pmode; + + va_start(ap, flags); + pmode = va_arg(ap, int); + va_end(ap); + + if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL)) + { + int retval = MSVCRT__open(patha,flags,pmode); + MSVCRT_free(patha); + return retval; + } + + msvcrt_set_errno(GetLastError()); + return -1; +} + +/********************************************************************* + * _creat (MSVCRT.@) + */ +int CDECL MSVCRT__creat(const char *path, int flags) +{ + int usedFlags = (flags & MSVCRT__O_TEXT)| MSVCRT__O_CREAT| MSVCRT__O_WRONLY| MSVCRT__O_TRUNC; + return MSVCRT__open(path, usedFlags); +} + +/********************************************************************* + * _wcreat (MSVCRT.@) + */ +int CDECL _wcreat(const MSVCRT_wchar_t *path, int flags) +{ + int usedFlags = (flags & MSVCRT__O_TEXT)| MSVCRT__O_CREAT| MSVCRT__O_WRONLY| MSVCRT__O_TRUNC; + return _wopen(path, usedFlags); +} + +/********************************************************************* + * _open_osfhandle (MSVCRT.@) + */ +int CDECL _open_osfhandle(long handle, int oflags) +{ + int fd; + + /* MSVCRT__O_RDONLY (0) always matches, so set the read flag + * MFC's CStdioFile clears O_RDONLY (0)! if it wants to write to the + * file, so set the write flag. It also only sets MSVCRT__O_TEXT if it wants + * text - it never sets MSVCRT__O_BINARY. + */ + /* don't let split_oflags() decide the mode if no mode is passed */ + if (!(oflags & (MSVCRT__O_BINARY | MSVCRT__O_TEXT))) + oflags |= MSVCRT__O_BINARY; + + fd = msvcrt_alloc_fd((HANDLE)handle, split_oflags(oflags)); + TRACE(":handle (%ld) fd (%d) flags 0x%08x\n", handle, fd, oflags); + return fd; +} + +/********************************************************************* + * _rmtmp (MSVCRT.@) + */ +int CDECL _rmtmp(void) +{ + int num_removed = 0, i; + + LOCK_FILES(); + for (i = 3; i < MSVCRT_stream_idx; i++) + if (MSVCRT_fstreams[i] && MSVCRT_fstreams[i]->_tmpfname) + { + MSVCRT_fclose(MSVCRT_fstreams[i]); + num_removed++; + } + UNLOCK_FILES(); + + if (num_removed) + TRACE(":removed (%d) temp files\n",num_removed); + return num_removed; +} + +/********************************************************************* + * (internal) remove_cr + * + * Translate all \r\n to \n inplace. + * return the number of \r removed + * Corner cases required by some apps: + * \r\r\n -> \r\n + * BUG: should save state across calls somehow, so CR LF that + * straddles buffer boundary gets recognized properly? + */ +static unsigned int remove_cr(char *buf, unsigned int count) +{ + unsigned int i, j; + + for (i=0, j=0; j < count; j++) + if ((buf[j] != '\r') || ((j+1) < count && buf[j+1] != '\n')) + buf[i++] = buf[j]; + + return count - i; +} + +/********************************************************************* + * (internal) read_i + */ +static int read_i(int fd, void *buf, unsigned int count) +{ + DWORD num_read; + char *bufstart = buf; + HANDLE hand = msvcrt_fdtoh(fd); + + if (MSVCRT_fdesc[fd].wxflag & WX_READEOF) { + MSVCRT_fdesc[fd].wxflag |= WX_ATEOF; + TRACE("already at EOF, returning 0\n"); + return 0; + } + /* Don't trace small reads, it gets *very* annoying */ + if (count > 4) + TRACE(":fd (%d) handle (%p) buf (%p) len (%d)\n",fd,hand,buf,count); + if (hand == INVALID_HANDLE_VALUE) + return -1; + + /* Reading single bytes in O_TEXT mode makes things slow + * So read big chunks + */ + if (ReadFile(hand, bufstart, count, &num_read, NULL)) + { + if (MSVCRT_fdesc[fd].wxflag & WX_TEXT) + { + int i; + /* in text mode, a ctrl-z signals EOF */ + for (i=0; i 4) + TRACE("(%u), %s\n",num_read,debugstr_an(buf, num_read)); + return num_read; +} + +/********************************************************************* + * _read (MSVCRT.@) + */ +int CDECL MSVCRT__read(int fd, void *buf, unsigned int count) +{ + int num_read; + num_read = read_i(fd, buf, count); + if (num_read>0 && MSVCRT_fdesc[fd].wxflag & WX_TEXT) + { + num_read -= remove_cr(buf,num_read); + } + return num_read; +} + +/********************************************************************* + * _setmode (MSVCRT.@) + */ +int CDECL _setmode(int fd,int mode) +{ + int ret = MSVCRT_fdesc[fd].wxflag & WX_TEXT ? MSVCRT__O_TEXT : MSVCRT__O_BINARY; + if (mode & (~(MSVCRT__O_TEXT|MSVCRT__O_BINARY))) + FIXME("fd (%d) mode (0x%08x) unknown\n",fd,mode); + if ((mode & MSVCRT__O_TEXT) == MSVCRT__O_TEXT) + MSVCRT_fdesc[fd].wxflag |= WX_TEXT; + else + MSVCRT_fdesc[fd].wxflag &= ~WX_TEXT; + return ret; +} + +/********************************************************************* + * _stat64 (MSVCRT.@) + */ +int CDECL MSVCRT__stat64(const char* path, struct MSVCRT__stat64 * buf) +{ + DWORD dw; + WIN32_FILE_ATTRIBUTE_DATA hfi; + unsigned short mode = ALL_S_IREAD; + int plen; + + TRACE(":file (%s) buf(%p)\n",path,buf); + + if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi)) + { + TRACE("failed (%d)\n",GetLastError()); + msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + return -1; + } + + memset(buf,0,sizeof(struct MSVCRT__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 |= (MSVCRT__S_IFDIR | ALL_S_IEXEC); + else + { + mode |= MSVCRT__S_IFREG; + /* executable? */ + if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */ + { + unsigned int ext = tolower(path[plen-1]) | (tolower(path[plen-2]) << 8) | + (tolower(path[plen-3]) << 16); + if (ext == EXE || ext == BAT || ext == CMD || ext == COM) + mode |= ALL_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; + TRACE("%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; +} + +/********************************************************************* + * _stati64 (MSVCRT.@) + */ +int CDECL MSVCRT__stati64(const char* path, struct MSVCRT__stati64 * buf) +{ + int ret; + struct MSVCRT__stat64 buf64; + + ret = MSVCRT__stat64(path, &buf64); + if (!ret) + msvcrt_stat64_to_stati64(&buf64, buf); + return ret; +} + +/********************************************************************* + * _stat (MSVCRT.@) + */ +int CDECL MSVCRT__stat(const char* path, struct MSVCRT__stat * buf) +{ int ret; + struct MSVCRT__stat64 buf64; + + ret = MSVCRT__stat64( path, &buf64); + if (!ret) + msvcrt_stat64_to_stat(&buf64, buf); + return ret; +} + +/********************************************************************* + * _wstat64 (MSVCRT.@) + */ +int CDECL MSVCRT__wstat64(const MSVCRT_wchar_t* path, struct MSVCRT__stat64 * buf) +{ + DWORD dw; + WIN32_FILE_ATTRIBUTE_DATA hfi; + unsigned short mode = ALL_S_IREAD; + int plen; + + TRACE(":file (%s) buf(%p)\n",debugstr_w(path),buf); + + if (!GetFileAttributesExW(path, GetFileExInfoStandard, &hfi)) + { + TRACE("failed (%d)\n",GetLastError()); + msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + return -1; + } + + memset(buf,0,sizeof(struct MSVCRT__stat64)); + + /* FIXME: rdev isn't drive num, despite what the docs says-what is it? */ + if (MSVCRT_iswalpha(*path)) + buf->st_dev = buf->st_rdev = toupperW(*path - 'A'); /* drive num */ + else + buf->st_dev = buf->st_rdev = _getdrive() - 1; + + plen = strlenW(path); + + /* Dir, or regular file? */ + if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || + (path[plen-1] == '\\')) + mode |= (MSVCRT__S_IFDIR | ALL_S_IEXEC); + else + { + mode |= MSVCRT__S_IFREG; + /* executable? */ + if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */ + { + ULONGLONG ext = tolowerW(path[plen-1]) | (tolowerW(path[plen-2]) << 16) | + ((ULONGLONG)tolowerW(path[plen-3]) << 32); + if (ext == WCEXE || ext == WCBAT || ext == WCCMD || ext == WCCOM) + mode |= ALL_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; + TRACE("%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; +} + +/********************************************************************* + * _wstati64 (MSVCRT.@) + */ +int CDECL MSVCRT__wstati64(const MSVCRT_wchar_t* path, struct MSVCRT__stati64 * buf) +{ + int ret; + struct MSVCRT__stat64 buf64; + + ret = MSVCRT__wstat64(path, &buf64); + if (!ret) + msvcrt_stat64_to_stati64(&buf64, buf); + return ret; +} + +/********************************************************************* + * _wstat (MSVCRT.@) + */ +int CDECL MSVCRT__wstat(const MSVCRT_wchar_t* path, struct MSVCRT__stat * buf) +{ + int ret; + struct MSVCRT__stat64 buf64; + + ret = MSVCRT__wstat64( path, &buf64 ); + if (!ret) msvcrt_stat64_to_stat(&buf64, buf); + return ret; +} + +/********************************************************************* + * _tell (MSVCRT.@) + */ +long CDECL _tell(int fd) +{ + return MSVCRT__lseek(fd, 0, SEEK_CUR); +} + +/********************************************************************* + * _telli64 (MSVCRT.@) + */ +__int64 CDECL _telli64(int fd) +{ + return MSVCRT__lseeki64(fd, 0, SEEK_CUR); +} + +/********************************************************************* + * _tempnam (MSVCRT.@) + */ +char * CDECL _tempnam(const char *dir, const char *prefix) +{ + char tmpbuf[MAX_PATH]; + const char *tmp_dir = MSVCRT_getenv("TMP"); + + if (tmp_dir) dir = tmp_dir; + + TRACE("dir (%s) prefix (%s)\n",dir,prefix); + if (GetTempFileNameA(dir,prefix,0,tmpbuf)) + { + TRACE("got name (%s)\n",tmpbuf); + DeleteFileA(tmpbuf); + return _strdup(tmpbuf); + } + TRACE("failed (%d)\n",GetLastError()); + return NULL; +} + +/********************************************************************* + * _wtempnam (MSVCRT.@) + */ +MSVCRT_wchar_t * CDECL _wtempnam(const MSVCRT_wchar_t *dir, const MSVCRT_wchar_t *prefix) +{ + MSVCRT_wchar_t tmpbuf[MAX_PATH]; + + TRACE("dir (%s) prefix (%s)\n",debugstr_w(dir),debugstr_w(prefix)); + if (GetTempFileNameW(dir,prefix,0,tmpbuf)) + { + TRACE("got name (%s)\n",debugstr_w(tmpbuf)); + DeleteFileW(tmpbuf); + return _wcsdup(tmpbuf); + } + TRACE("failed (%d)\n",GetLastError()); + return NULL; +} + +/********************************************************************* + * _umask (MSVCRT.@) + */ +int CDECL MSVCRT__umask(int umask) +{ + int old_umask = MSVCRT_umask; + TRACE("(%d)\n",umask); + MSVCRT_umask = umask; + return old_umask; +} + +/********************************************************************* + * _utime (MSVCRT.@) + */ +int CDECL _utime(const char* path, struct MSVCRT__utimbuf *t) +{ + int fd = MSVCRT__open(path, MSVCRT__O_WRONLY | MSVCRT__O_BINARY); + + if (fd > 0) + { + int retVal = _futime(fd, t); + MSVCRT__close(fd); + return retVal; + } + return -1; +} + +/********************************************************************* + * _wutime (MSVCRT.@) + */ +int CDECL _wutime(const MSVCRT_wchar_t* path, struct MSVCRT__utimbuf *t) +{ + int fd = _wopen(path, MSVCRT__O_WRONLY | MSVCRT__O_BINARY); + + if (fd > 0) + { + int retVal = _futime(fd, t); + MSVCRT__close(fd); + return retVal; + } + return -1; +} + +/********************************************************************* + * _write (MSVCRT.@) + */ +int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count) +{ + DWORD num_written; + HANDLE hand = msvcrt_fdtoh(fd); + + /* Don't trace small writes, it gets *very* annoying */ +#if 0 + if (count > 32) + TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count); +#endif + if (hand == INVALID_HANDLE_VALUE) + { + *MSVCRT__errno() = MSVCRT_EBADF; + return -1; + } + + /* If appending, go to EOF */ + if (MSVCRT_fdesc[fd].wxflag & WX_APPEND) + MSVCRT__lseek(fd, 0, FILE_END); + + if (!(MSVCRT_fdesc[fd].wxflag & WX_TEXT)) + { + if (WriteFile(hand, buf, count, &num_written, NULL) + && (num_written == count)) + return num_written; + TRACE("WriteFile (fd %d, hand %p) failed-last error (%d)\n", fd, + hand, GetLastError()); + *MSVCRT__errno() = MSVCRT_ENOSPC; + } + else + { + unsigned int i, j, nr_lf; + char *p = NULL; + const char *q; + const char *s = (const char *)buf, *buf_start = (const char *)buf; + /* find number of \n ( without preceding \r ) */ + for ( nr_lf=0,i = 0; i 1) && (s[i-1] == '\r')) nr_lf--; */ + } + } + if (nr_lf) + { + if ((q = p = MSVCRT_malloc(count + nr_lf))) + { + for (s = (const char *)buf, i = 0, j = 0; i < count; i++) + { + if (s[i]== '\n') + { + p[j++] = '\r'; + /*if ((i >1) && (s[i-1] == '\r'))j--;*/ + } + p[j++] = s[i]; + } + } + else + { + FIXME("Malloc failed\n"); + nr_lf =0; + q = buf; + } + } + else + q = buf; + + if ((WriteFile(hand, q, count+nr_lf, &num_written, NULL) == 0 ) || (num_written != count+nr_lf)) + { + TRACE("WriteFile (fd %d, hand %p) failed-last error (%d), num_written %d\n", + fd, hand, GetLastError(), num_written); + *MSVCRT__errno() = MSVCRT_ENOSPC; + if(nr_lf) + MSVCRT_free(p); + return s - buf_start; + } + else + { + if(nr_lf) + MSVCRT_free(p); + return count; + } + } + return -1; +} + +/********************************************************************* + * _putw (MSVCRT.@) + */ +int CDECL MSVCRT__putw(int val, MSVCRT_FILE* file) +{ + int len; + len = MSVCRT__write(file->_file, &val, sizeof(val)); + if (len == sizeof(val)) return val; + file->_flag |= MSVCRT__IOERR; + return MSVCRT_EOF; +} + +/********************************************************************* + * fclose (MSVCRT.@) + */ +int CDECL MSVCRT_fclose(MSVCRT_FILE* file) +{ + int r, flag; + + flag = file->_flag; + MSVCRT_free(file->_tmpfname); + file->_tmpfname = NULL; + /* flush stdio buffers */ + if(file->_flag & MSVCRT__IOWRT) + MSVCRT_fflush(file); + if(file->_flag & MSVCRT__IOMYBUF) + MSVCRT_free(file->_base); + + r=MSVCRT__close(file->_file); + + file->_flag = 0; + + return ((r == -1) || (flag & MSVCRT__IOERR) ? MSVCRT_EOF : 0); +} + +/********************************************************************* + * feof (MSVCRT.@) + */ +int CDECL MSVCRT_feof(MSVCRT_FILE* file) +{ + return file->_flag & MSVCRT__IOEOF; +} + +/********************************************************************* + * ferror (MSVCRT.@) + */ +int CDECL MSVCRT_ferror(MSVCRT_FILE* file) +{ + return file->_flag & MSVCRT__IOERR; +} + +/********************************************************************* + * _filbuf (MSVCRT.@) + */ +int CDECL MSVCRT__filbuf(MSVCRT_FILE* file) +{ + /* Allocate buffer if needed */ + if(file->_bufsiz == 0 && !(file->_flag & MSVCRT__IONBF) ) { + msvcrt_alloc_buffer(file); + } + if(!(file->_flag & MSVCRT__IOREAD)) { + if(file->_flag & MSVCRT__IORW) { + file->_flag |= MSVCRT__IOREAD; + } else { + return MSVCRT_EOF; + } + } + if(file->_flag & MSVCRT__IONBF) { + unsigned char c; + int r; + if ((r = read_i(file->_file,&c,1)) != 1) { + file->_flag |= (r == 0) ? MSVCRT__IOEOF : MSVCRT__IOERR; + return MSVCRT_EOF; + } + return c; + } else { + file->_cnt = read_i(file->_file, file->_base, file->_bufsiz); + if(file->_cnt<=0) { + file->_flag |= (file->_cnt == 0) ? MSVCRT__IOEOF : MSVCRT__IOERR; + file->_cnt = 0; + return MSVCRT_EOF; + } + file->_cnt--; + file->_ptr = file->_base+1; + return *(unsigned char *)file->_base; + } +} + +/********************************************************************* + * fgetc (MSVCRT.@) + */ +int CDECL MSVCRT_fgetc(MSVCRT_FILE* file) +{ + unsigned char *i; + unsigned int j; + do { + if (file->_cnt>0) { + file->_cnt--; + i = (unsigned char *)file->_ptr++; + j = *i; + } else + j = MSVCRT__filbuf(file); + if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT) + || ((j != '\r') || (file->_cnt && file->_ptr[0] != '\n'))) + return j; + } while(1); +} + +/********************************************************************* + * _fgetchar (MSVCRT.@) + */ +int CDECL _fgetchar(void) +{ + return MSVCRT_fgetc(MSVCRT_stdin); +} + +/********************************************************************* + * fgets (MSVCRT.@) + */ +char * CDECL MSVCRT_fgets(char *s, int size, MSVCRT_FILE* file) +{ + int cc = MSVCRT_EOF; + char * buf_start = s; + + TRACE(":file(%p) fd (%d) str (%p) len (%d)\n", + file,file->_file,s,size); + + while ((size >1) && (cc = MSVCRT_fgetc(file)) != MSVCRT_EOF && cc != '\n') + { + *s++ = (char)cc; + size --; + } + if ((cc == MSVCRT_EOF) && (s == buf_start)) /* If nothing read, return 0*/ + { + TRACE(":nothing read\n"); + return NULL; + } + if ((cc != MSVCRT_EOF) && (size > 1)) + *s++ = cc; + *s = '\0'; + TRACE(":got %s\n", debugstr_a(buf_start)); + return buf_start; +} + +/********************************************************************* + * fgetwc (MSVCRT.@) + * + * In MSVCRT__O_TEXT mode, multibyte characters are read from the file, dropping + * the CR from CR/LF combinations + */ +MSVCRT_wint_t CDECL MSVCRT_fgetwc(MSVCRT_FILE* file) +{ + char c; + + if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT)) + { + MSVCRT_wchar_t wc; + int i,j; + char *chp, *wcp; + wcp = (char *)&wc; + for(i=0; i_cnt>0) + { + file->_cnt--; + chp = file->_ptr++; + wcp[i] = *chp; + } + else + { + j = MSVCRT__filbuf(file); + if(file->_cnt<=0) + { + file->_flag |= (file->_cnt == 0) ? MSVCRT__IOEOF : MSVCRT__IOERR; + file->_cnt = 0; + return MSVCRT_WEOF; + } + wcp[i] = j; + } + } + return wc; + } + + c = MSVCRT_fgetc(file); + if ((*__p___mb_cur_max() > 1) && MSVCRT_isleadbyte(c)) + { + FIXME("Treat Multibyte characters\n"); + } + if (c == MSVCRT_EOF) + return MSVCRT_WEOF; + else + return (MSVCRT_wint_t)c; +} + +/********************************************************************* + * _getw (MSVCRT.@) + */ +int CDECL MSVCRT__getw(MSVCRT_FILE* file) +{ + char *ch; + int i, j, k; + ch = (char *)&i; + for (j=0; j_flag |= MSVCRT__IOEOF; + return EOF; + } + ch[j] = k; + } + return i; +} + +/********************************************************************* + * getwc (MSVCRT.@) + */ +MSVCRT_wint_t CDECL MSVCRT_getwc(MSVCRT_FILE* file) +{ + return MSVCRT_fgetwc(file); +} + +/********************************************************************* + * _fgetwchar (MSVCRT.@) + */ +MSVCRT_wint_t CDECL _fgetwchar(void) +{ + return MSVCRT_fgetwc(MSVCRT_stdin); +} + +/********************************************************************* + * getwchar (MSVCRT.@) + */ +MSVCRT_wint_t CDECL MSVCRT_getwchar(void) +{ + return _fgetwchar(); +} + +/********************************************************************* + * fgetws (MSVCRT.@) + */ +MSVCRT_wchar_t * CDECL MSVCRT_fgetws(MSVCRT_wchar_t *s, int size, MSVCRT_FILE* file) +{ + int cc = MSVCRT_WEOF; + MSVCRT_wchar_t * buf_start = s; + + TRACE(":file(%p) fd (%d) str (%p) len (%d)\n", + file,file->_file,s,size); + + while ((size >1) && (cc = MSVCRT_fgetwc(file)) != MSVCRT_WEOF && cc != '\n') + { + *s++ = (char)cc; + size --; + } + if ((cc == MSVCRT_WEOF) && (s == buf_start)) /* If nothing read, return 0*/ + { + TRACE(":nothing read\n"); + return NULL; + } + if ((cc != MSVCRT_WEOF) && (size > 1)) + *s++ = cc; + *s = 0; + TRACE(":got %s\n", debugstr_w(buf_start)); + return buf_start; +} + +/********************************************************************* + * fwrite (MSVCRT.@) + */ +MSVCRT_size_t CDECL MSVCRT_fwrite(const void *ptr, MSVCRT_size_t size, MSVCRT_size_t nmemb, MSVCRT_FILE* file) +{ + MSVCRT_size_t wrcnt=size * nmemb; + int written = 0; + if (size == 0) + return 0; + if(file->_cnt) { + int pcnt=(file->_cnt>wrcnt)? wrcnt: file->_cnt; + memcpy(file->_ptr, ptr, pcnt); + file->_cnt -= pcnt; + file->_ptr += pcnt; + written = pcnt; + wrcnt -= pcnt; + ptr = (const char*)ptr + pcnt; + } else if(!(file->_flag & MSVCRT__IOWRT)) { + if(file->_flag & MSVCRT__IORW) { + file->_flag |= MSVCRT__IOWRT; + } else + return 0; + } + if(wrcnt) { + /* Flush buffer */ + int res=msvcrt_flush_buffer(file); + if(!res) { + int pwritten = MSVCRT__write(file->_file, ptr, wrcnt); + if (pwritten <= 0) + { + file->_flag |= MSVCRT__IOERR; + pwritten=0; + } + written += pwritten; + } + } + return written / size; +} + +/********************************************************************* + * fputwc (MSVCRT.@) + */ +MSVCRT_wint_t CDECL MSVCRT_fputwc(MSVCRT_wint_t wc, MSVCRT_FILE* file) +{ + MSVCRT_wchar_t mwc=wc; + if (MSVCRT_fwrite( &mwc, sizeof(mwc), 1, file) != 1) + return MSVCRT_WEOF; + return wc; +} + +/********************************************************************* + * _fputwchar (MSVCRT.@) + */ +MSVCRT_wint_t CDECL _fputwchar(MSVCRT_wint_t wc) +{ + return MSVCRT_fputwc(wc, MSVCRT_stdout); +} + +/********************************************************************* + * _fsopen (MSVCRT.@) + */ +MSVCRT_FILE * CDECL MSVCRT__fsopen(const char *path, const char *mode, int share) +{ + MSVCRT_FILE* file; + int open_flags, stream_flags, fd; + + TRACE("(%s,%s)\n",path,mode); + + /* map mode string to open() flags. "man fopen" for possibilities. */ + if (msvcrt_get_flags(mode, &open_flags, &stream_flags) == -1) + return NULL; + + LOCK_FILES(); + fd = MSVCRT__sopen(path, open_flags, share, MSVCRT__S_IREAD | MSVCRT__S_IWRITE); + if (fd < 0) + file = NULL; + else if ((file = msvcrt_alloc_fp()) && msvcrt_init_fp(file, fd, stream_flags) + != -1) + TRACE(":fd (%d) mode (%s) FILE* (%p)\n",fd,mode,file); + else if (file) + { + file->_flag = 0; + file = NULL; + } + + TRACE(":got (%p)\n",file); + if (fd >= 0 && !file) + MSVCRT__close(fd); + UNLOCK_FILES(); + return file; +} + +/********************************************************************* + * _wfsopen (MSVCRT.@) + */ +MSVCRT_FILE * CDECL MSVCRT__wfsopen(const MSVCRT_wchar_t *path, const MSVCRT_wchar_t *mode, int share) +{ + const unsigned int plen = strlenW(path), mlen = strlenW(mode); + char *patha = MSVCRT_calloc(plen + 1, 1); + char *modea = MSVCRT_calloc(mlen + 1, 1); + + TRACE("(%s,%s)\n",debugstr_w(path),debugstr_w(mode)); + + if (patha && modea && + WideCharToMultiByte(CP_ACP,0,path,plen,patha,plen,NULL,NULL) && + WideCharToMultiByte(CP_ACP,0,mode,mlen,modea,mlen,NULL,NULL)) + { + MSVCRT_FILE *retval = MSVCRT__fsopen(patha,modea,share); + MSVCRT_free(patha); + MSVCRT_free(modea); + return retval; + } + + msvcrt_set_errno(GetLastError()); + return NULL; +} + +/********************************************************************* + * fopen (MSVCRT.@) + */ +MSVCRT_FILE * CDECL MSVCRT_fopen(const char *path, const char *mode) +{ + return MSVCRT__fsopen( path, mode, MSVCRT__SH_DENYNO ); +} + +/********************************************************************* + * _wfopen (MSVCRT.@) + */ +MSVCRT_FILE * CDECL MSVCRT__wfopen(const MSVCRT_wchar_t *path, const MSVCRT_wchar_t *mode) +{ + return MSVCRT__wfsopen( path, mode, MSVCRT__SH_DENYNO ); +} + +/* MSVCRT_fputc calls MSVCRT__flsbuf which calls MSVCRT_fputc */ +int CDECL MSVCRT__flsbuf(int c, MSVCRT_FILE* file); + +/********************************************************************* + * fputc (MSVCRT.@) + */ +int CDECL MSVCRT_fputc(int c, MSVCRT_FILE* file) +{ + if(file->_cnt>0) { + *file->_ptr++=c; + file->_cnt--; + if (c == '\n') + { + int res = msvcrt_flush_buffer(file); + return res ? res : c; + } + else + return c; + } else { + return MSVCRT__flsbuf(c, file); + } +} + +/********************************************************************* + * _flsbuf (MSVCRT.@) + */ +int CDECL MSVCRT__flsbuf(int c, MSVCRT_FILE* file) +{ + /* Flush output buffer */ + if(file->_bufsiz == 0 && !(file->_flag & MSVCRT__IONBF)) { + msvcrt_alloc_buffer(file); + } + if(!(file->_flag & MSVCRT__IOWRT)) { + if(file->_flag & MSVCRT__IORW) { + file->_flag |= MSVCRT__IOWRT; + } else { + return MSVCRT_EOF; + } + } + if(file->_bufsiz) { + int res=msvcrt_flush_buffer(file); + return res?res : MSVCRT_fputc(c, file); + } else { + unsigned char cc=c; + int len; + len = MSVCRT__write(file->_file, &cc, 1); + if (len == 1) return c; + file->_flag |= MSVCRT__IOERR; + return MSVCRT_EOF; + } +} + +/********************************************************************* + * _fputchar (MSVCRT.@) + */ +int CDECL _fputchar(int c) +{ + return MSVCRT_fputc(c, MSVCRT_stdout); +} + +/********************************************************************* + * fread (MSVCRT.@) + */ +MSVCRT_size_t CDECL MSVCRT_fread(void *ptr, MSVCRT_size_t size, MSVCRT_size_t nmemb, MSVCRT_FILE* file) +{ MSVCRT_size_t rcnt=size * nmemb; + MSVCRT_size_t read=0; + int pread=0; + + if(!rcnt) + return 0; + + /* first buffered data */ + if(file->_cnt>0) { + int pcnt= (rcnt>file->_cnt)? file->_cnt:rcnt; + memcpy(ptr, file->_ptr, pcnt); + file->_cnt -= pcnt; + file->_ptr += pcnt; + if (MSVCRT_fdesc[file->_file].wxflag & WX_TEXT) + pcnt -= remove_cr(ptr,pcnt); + read += pcnt ; + rcnt -= pcnt ; + ptr = (char*)ptr + pcnt; + } else if(!(file->_flag & MSVCRT__IOREAD )) { + if(file->_flag & MSVCRT__IORW) { + file->_flag |= MSVCRT__IOREAD; + } else + return 0; + } + while(rcnt>0) + { + int i; + /* Fill the buffer on small reads. + * TODO: Use a better buffering strategy. + */ + if (!file->_cnt && size*nmemb <= MSVCRT_BUFSIZ/2 && !(file->_flag & MSVCRT__IONBF)) { + if (file->_bufsiz == 0) { + msvcrt_alloc_buffer(file); + } + file->_cnt = MSVCRT__read(file->_file, file->_base, file->_bufsiz); + file->_ptr = file->_base; + i = (file->_cnt_cnt : rcnt; + /* If the buffer fill reaches eof but fread wouldn't, clear eof. */ + if (i > 0 && i < file->_cnt) { + MSVCRT_fdesc[file->_file].wxflag &= ~WX_ATEOF; + file->_flag &= ~MSVCRT__IOEOF; + } + if (i > 0) { + memcpy(ptr, file->_ptr, i); + file->_cnt -= i; + file->_ptr += i; + } + } else { + i = MSVCRT__read(file->_file,ptr, rcnt); + } + pread += i; + rcnt -= i; + ptr = (char *)ptr+i; + /* expose feof condition in the flags + * MFC tests file->_flag for feof, and doesn't call feof()) + */ + if ( MSVCRT_fdesc[file->_file].wxflag & WX_ATEOF) + file->_flag |= MSVCRT__IOEOF; + else if (i == -1) + { + file->_flag |= MSVCRT__IOERR; + pread = 0; + rcnt = 0; + } + if (i < 1) break; + } + read+=pread; + return read / size; +} + +/********************************************************************* + * freopen (MSVCRT.@) + * + */ +MSVCRT_FILE* CDECL MSVCRT_freopen(const char *path, const char *mode,MSVCRT_FILE* file) +{ + int open_flags, stream_flags, fd; + + TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n",path,mode,file,file->_file); + + LOCK_FILES(); + if (!file || ((fd = file->_file) < 0) || fd > MSVCRT_fdend) + file = NULL; + else + { + MSVCRT_fclose(file); + /* map mode string to open() flags. "man fopen" for possibilities. */ + if (msvcrt_get_flags(mode, &open_flags, &stream_flags) == -1) + file = NULL; + else + { + fd = MSVCRT__open(path, open_flags, MSVCRT__S_IREAD | MSVCRT__S_IWRITE); + if (fd < 0) + file = NULL; + else if (msvcrt_init_fp(file, fd, stream_flags) == -1) + { + file->_flag = 0; + WARN(":failed-last error (%d)\n",GetLastError()); + msvcrt_set_errno(GetLastError()); + file = NULL; + } + } + } + UNLOCK_FILES(); + return file; +} + +/********************************************************************* + * fsetpos (MSVCRT.@) + */ +int CDECL MSVCRT_fsetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos) +{ + /* Note that all this has been lifted 'as is' from fseek */ + if(file->_flag & MSVCRT__IOWRT) + msvcrt_flush_buffer(file); + + /* Discard buffered input */ + file->_cnt = 0; + file->_ptr = file->_base; + + /* Reset direction of i/o */ + if(file->_flag & MSVCRT__IORW) { + file->_flag &= ~(MSVCRT__IOREAD|MSVCRT__IOWRT); + } + + return (MSVCRT__lseeki64(file->_file,*pos,SEEK_SET) == -1) ? -1 : 0; +} + +/********************************************************************* + * ftell (MSVCRT.@) + */ +LONG CDECL MSVCRT_ftell(MSVCRT_FILE* file) +{ + int off=0; + long pos; + if(file->_bufsiz) { + if( file->_flag & MSVCRT__IOWRT ) { + off = file->_ptr - file->_base; + } else { + off = -file->_cnt; + } + } + pos = _tell(file->_file); + if(pos == -1) return pos; + return off + pos; +} + +/********************************************************************* + * fgetpos (MSVCRT.@) + */ +int CDECL MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos) +{ + /* This code has been lifted form the MSVCRT_ftell function */ + int off=0; + + *pos = MSVCRT__lseeki64(file->_file,0,SEEK_CUR); + + if (*pos == -1) return -1; + + if(file->_bufsiz) { + if( file->_flag & MSVCRT__IOWRT ) { + off = file->_ptr - file->_base; + } else { + off = -file->_cnt; + } + } + *pos += off; + + return 0; +} + +/********************************************************************* + * fputs (MSVCRT.@) + */ +int CDECL MSVCRT_fputs(const char *s, MSVCRT_FILE* file) +{ + size_t i, len = strlen(s); + if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT)) + return MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF; + for (i=0; i_file].wxflag & WX_TEXT)) + return MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF; + for (i=0; i_bufsiz) { + MSVCRT_free(file->_base); + file->_bufsiz = 0; + file->_cnt = 0; + } + if(mode == MSVCRT__IOFBF) { + file->_flag &= ~MSVCRT__IONBF; + file->_base = file->_ptr = buf; + if(buf) { + file->_bufsiz = size; + } + } else { + file->_flag |= MSVCRT__IONBF; + } + return 0; +} + +/********************************************************************* + * setbuf (MSVCRT.@) + */ +void CDECL MSVCRT_setbuf(MSVCRT_FILE* file, char *buf) +{ + MSVCRT_setvbuf(file, buf, buf ? MSVCRT__IOFBF : MSVCRT__IONBF, MSVCRT_BUFSIZ); +} + +/********************************************************************* + * tmpnam (MSVCRT.@) + */ +char * CDECL MSVCRT_tmpnam(char *s) +{ + static int unique; + char tmpstr[16]; + char *p; + int count; + if (s == 0) + s = MSVCRT_tmpname; + msvcrt_int_to_base32(GetCurrentProcessId(), tmpstr); + p = s + sprintf(s, "\\s%s.", tmpstr); + for (count = 0; count < MSVCRT_TMP_MAX; count++) + { + msvcrt_int_to_base32(unique++, tmpstr); + strcpy(p, tmpstr); + if (GetFileAttributesA(s) == INVALID_FILE_ATTRIBUTES && + GetLastError() == ERROR_FILE_NOT_FOUND) + break; + } + return s; +} + +/********************************************************************* + * tmpfile (MSVCRT.@) + */ +MSVCRT_FILE* CDECL MSVCRT_tmpfile(void) +{ + char *filename = MSVCRT_tmpnam(NULL); + int fd; + MSVCRT_FILE* file = NULL; + + LOCK_FILES(); + fd = MSVCRT__open(filename, MSVCRT__O_CREAT | MSVCRT__O_BINARY | MSVCRT__O_RDWR | MSVCRT__O_TEMPORARY); + if (fd != -1 && (file = msvcrt_alloc_fp())) + { + if (msvcrt_init_fp(file, fd, MSVCRT__O_RDWR) == -1) + { + file->_flag = 0; + file = NULL; + } + else file->_tmpfname = _strdup(filename); + } + UNLOCK_FILES(); + return file; +} + +/********************************************************************* + * vfprintf (MSVCRT.@) + */ +int CDECL MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, va_list valist) +{ + char buf[2048], *mem = buf; + int written, resize = sizeof(buf), retval; + /* There are two conventions for vsnprintf failing: + * Return -1 if we truncated, or + * Return the number of bytes that would have been written + * The code below handles both cases + */ + while ((written = MSVCRT_vsnprintf(mem, resize, format, valist)) == -1 || + written > resize) + { + resize = (written == -1 ? resize * 2 : written + 1); + if (mem != buf) + MSVCRT_free (mem); + if (!(mem = MSVCRT_malloc(resize))) + return MSVCRT_EOF; + } + retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file); + if (mem != buf) + MSVCRT_free (mem); + return retval; +} + +/********************************************************************* + * vfwprintf (MSVCRT.@) + * FIXME: + * Is final char included in written (then resize is too big) or not + * (then we must test for equality too)? + */ +int CDECL MSVCRT_vfwprintf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, va_list valist) +{ + MSVCRT_wchar_t buf[2048], *mem = buf; + int written, resize = sizeof(buf) / sizeof(MSVCRT_wchar_t), retval; + /* See vfprintf comments */ + while ((written = MSVCRT_vsnwprintf(mem, resize, format, valist)) == -1 || + written > resize) + { + resize = (written == -1 ? resize * 2 : written + sizeof(MSVCRT_wchar_t)); + if (mem != buf) + MSVCRT_free (mem); + if (!(mem = MSVCRT_malloc(resize*sizeof(*mem)))) + return MSVCRT_EOF; + } + retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file); + if (mem != buf) + MSVCRT_free (mem); + return retval; +} + +/********************************************************************* + * vprintf (MSVCRT.@) + */ +int CDECL MSVCRT_vprintf(const char *format, va_list valist) +{ + return MSVCRT_vfprintf(MSVCRT_stdout,format,valist); +} + +/********************************************************************* + * vwprintf (MSVCRT.@) + */ +int CDECL MSVCRT_vwprintf(const MSVCRT_wchar_t *format, va_list valist) +{ + return MSVCRT_vfwprintf(MSVCRT_stdout,format,valist); +} + +/********************************************************************* + * fprintf (MSVCRT.@) + */ +int CDECL MSVCRT_fprintf(MSVCRT_FILE* file, const char *format, ...) +{ + va_list valist; + int res; + va_start(valist, format); + res = MSVCRT_vfprintf(file, format, valist); + va_end(valist); + return res; +} + +/********************************************************************* + * fwprintf (MSVCRT.@) + */ +int CDECL MSVCRT_fwprintf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, ...) +{ + va_list valist; + int res; + va_start(valist, format); + res = MSVCRT_vfwprintf(file, format, valist); + va_end(valist); + return res; +} + +/********************************************************************* + * printf (MSVCRT.@) + */ +int CDECL MSVCRT_printf(const char *format, ...) +{ + va_list valist; + int res; + va_start(valist, format); + res = MSVCRT_vfprintf(MSVCRT_stdout, format, valist); + va_end(valist); + return res; +} + +/********************************************************************* + * ungetc (MSVCRT.@) + */ +int CDECL MSVCRT_ungetc(int c, MSVCRT_FILE * file) +{ + if (c == MSVCRT_EOF) + return MSVCRT_EOF; + if(file->_bufsiz == 0 && !(file->_flag & MSVCRT__IONBF)) { + msvcrt_alloc_buffer(file); + file->_ptr++; + } + if(file->_ptr>file->_base) { + file->_ptr--; + *file->_ptr=c; + file->_cnt++; + MSVCRT_clearerr(file); + return c; + } + return MSVCRT_EOF; +} + +/********************************************************************* + * ungetwc (MSVCRT.@) + */ +MSVCRT_wint_t CDECL MSVCRT_ungetwc(MSVCRT_wint_t wc, MSVCRT_FILE * file) +{ + MSVCRT_wchar_t mwc = wc; + char * pp = (char *)&mwc; + int i; + for(i=sizeof(MSVCRT_wchar_t)-1;i>=0;i--) { + if(pp[i] != MSVCRT_ungetc(pp[i],file)) + return MSVCRT_WEOF; + } + return mwc; +} + +/********************************************************************* + * wprintf (MSVCRT.@) + */ +int CDECL MSVCRT_wprintf(const MSVCRT_wchar_t *format, ...) +{ + va_list valist; + int res; + va_start(valist, format); + res = MSVCRT_vwprintf(format, valist); + va_end(valist); + return res; +} + +/********************************************************************* + * _getmaxstdio (MSVCRT.@) + */ +int CDECL _getmaxstdio(void) +{ + FIXME("stub, always returns 512\n"); + return 512; +} + +/********************************************************************* + * _setmaxstdio_ (MSVCRT.@) + */ +int CDECL _setmaxstdio(int newmax) +{ + int res; + if( newmax > 2048) + res = -1; + else + res = newmax; + FIXME("stub: setting new maximum for number of simultaneously open files not implemented,returning %d\n",res); + return res; +} + +/********************************************************************* + * __pioinfo (MSVCRT.@) + * FIXME: see MSVCRT_MAX_FILES define. + */ +ioinfo * MSVCRT___pioinfo[] = { /* array of pointers to ioinfo arrays [64] */ + &MSVCRT_fdesc[0 * 64], &MSVCRT_fdesc[1 * 64], &MSVCRT_fdesc[2 * 64], + &MSVCRT_fdesc[3 * 64], &MSVCRT_fdesc[4 * 64], &MSVCRT_fdesc[5 * 64], + &MSVCRT_fdesc[6 * 64], &MSVCRT_fdesc[7 * 64], &MSVCRT_fdesc[8 * 64], + &MSVCRT_fdesc[9 * 64], &MSVCRT_fdesc[10 * 64], &MSVCRT_fdesc[11 * 64], + &MSVCRT_fdesc[12 * 64], &MSVCRT_fdesc[13 * 64], &MSVCRT_fdesc[14 * 64], + &MSVCRT_fdesc[15 * 64], &MSVCRT_fdesc[16 * 64], &MSVCRT_fdesc[17 * 64], + &MSVCRT_fdesc[18 * 64], &MSVCRT_fdesc[19 * 64], &MSVCRT_fdesc[20 * 64], + &MSVCRT_fdesc[21 * 64], &MSVCRT_fdesc[22 * 64], &MSVCRT_fdesc[23 * 64], + &MSVCRT_fdesc[24 * 64], &MSVCRT_fdesc[25 * 64], &MSVCRT_fdesc[26 * 64], + &MSVCRT_fdesc[27 * 64], &MSVCRT_fdesc[28 * 64], &MSVCRT_fdesc[29 * 64], + &MSVCRT_fdesc[30 * 64], &MSVCRT_fdesc[31 * 64] +} ; + +/********************************************************************* + * __badioinfo (MSVCRT.@) + */ +ioinfo MSVCRT___badioinfo = { INVALID_HANDLE_VALUE, WX_TEXT }; +#endif diff --git a/reactos/lib/sdk/crt/stdio/fwrite.c b/reactos/lib/sdk/crt/stdio/fwrite.c index 917f6738f79..486902e1d06 100644 --- a/reactos/lib/sdk/crt/stdio/fwrite.c +++ b/reactos/lib/sdk/crt/stdio/fwrite.c @@ -1,9 +1,5 @@ #include -#define NDEBUG -#include - - /* * @implemented */ diff --git a/reactos/lib/sdk/crt/stdio/popen.c b/reactos/lib/sdk/crt/stdio/popen.c index c8bfdba652b..07a4aa3094b 100644 --- a/reactos/lib/sdk/crt/stdio/popen.c +++ b/reactos/lib/sdk/crt/stdio/popen.c @@ -11,10 +11,13 @@ #include #include -#define NDEBUG -#include - +#ifdef _UNICODE + #define sT "S" +#else + #define sT "s" +#endif +#define MK_STR(s) #s /* * @implemented */ @@ -132,3 +135,4 @@ int _pclose (FILE *pp) #endif + diff --git a/reactos/lib/sdk/crt/stdio/remove.c b/reactos/lib/sdk/crt/stdio/remove.c index bf599275c1d..17b472d6d47 100644 --- a/reactos/lib/sdk/crt/stdio/remove.c +++ b/reactos/lib/sdk/crt/stdio/remove.c @@ -1,8 +1,13 @@ #include #include -#define NDEBUG -#include +#ifdef _UNICODE + #define sT "S" +#else + #define sT "s" +#endif + +#define MK_STR(s) #s /* * @implemented @@ -10,10 +15,11 @@ int _tremove(const _TCHAR *fn) { int result = 0; - DPRINT(MK_STR(_tremove)"('%"sT"')\n", fn); + TRACE(MK_STR(_tremove)"('%"sT"')\n", fn); if (!DeleteFile(fn)) result = -1; - DPRINT("%d\n", result); + TRACE("%d\n", result); return result; } + diff --git a/reactos/lib/sdk/crt/stdlib/errno.c b/reactos/lib/sdk/crt/stdlib/errno.c index c8f9cd62dd7..633267eddd1 100644 --- a/reactos/lib/sdk/crt/stdlib/errno.c +++ b/reactos/lib/sdk/crt/stdlib/errno.c @@ -1,4 +1,9 @@ -/* $Id$ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/crt/errno.c + * PURPOSE: Unknown + * PROGRAMER: Unknown * */ #include diff --git a/reactos/lib/sdk/crt/stdlib/getenv.c b/reactos/lib/sdk/crt/stdlib/getenv.c index 52886125f2f..0427351a6e7 100644 --- a/reactos/lib/sdk/crt/stdlib/getenv.c +++ b/reactos/lib/sdk/crt/stdlib/getenv.c @@ -9,10 +9,6 @@ */ #include - -#define NDEBUG -#include - #undef environ /* diff --git a/reactos/lib/sdk/crt/stdlib/mbstowcs.c b/reactos/lib/sdk/crt/stdlib/mbstowcs.c index 9fb89754893..a71f865447f 100644 --- a/reactos/lib/sdk/crt/stdlib/mbstowcs.c +++ b/reactos/lib/sdk/crt/stdlib/mbstowcs.c @@ -1,120 +1,28 @@ #include -#if 1 + /* - * @unimplemented + * @implemented */ -size_t mbstowcs(wchar_t* wcstr, const char* mbstr, size_t count) +size_t mbstowcs (wchar_t *widechar, const char *multibyte, size_t number) { - size_t size; - int i; + int bytes; + int n = 0; - printf("\nmbstowcs(%p, %p, %d) called.\n\n", wcstr, mbstr, count); + while (n < number) { - if (count <= 0 || !mbstr) - return 0; + if ((bytes = mbtowc (widechar, multibyte, MB_LEN_MAX)) < 0) + return -1; - if (!*mbstr) - return 0; + if (bytes == 0) { + *widechar = (wchar_t) '\0'; + return n; + } - - if (wcstr == NULL) { - // return required size for the converted string - return strlen(mbstr); // TODO: fixme + widechar++; + multibyte += bytes; + n++; } - for (size = 0, i = 0; i < count; size++) { - int result; -////int mbtowc( wchar_t *wchar, const char *mbchar, size_t count ) -//// result = mbtowc(wcstr + size, mbstr + i, count - i); -// result = mbtowc(wcstr + size, mbstr + i, 1); - -///////////////////////////////////////// - if (mbstr[i] == 0) { - result = 0; - } else { - wcstr[size] = mbstr[i]; - result = 1; - } -///////////////////////////////////////// - if (result == -1) { - return -1; - } else if (result == 0) { - wcstr[size] = L'\0'; - break; - } else { - i += result; - } - - } - return size; + return n; } - -#else -#if 1 - -//int mbtowc(wchar_t *dst, const char *str, size_t n) -size_t mbstowcs(wchar_t* wcstr, const char* mbstr, size_t count) -{ - size_t len; - - if (count <= 0 || !mbstr) - return 0; - len = MultiByteToWideChar(CP_ACP, 0, mbstr, count, wcstr, (wcstr == NULL) ? 0 : count); - - if (!len) { - DWORD err = GetLastError(); - switch (err) { - case ERROR_INSUFFICIENT_BUFFER: - break; - case ERROR_INVALID_FLAGS: - break; - case ERROR_INVALID_PARAMETER: - break; - case ERROR_NO_UNICODE_TRANSLATION: - break; - default: - return 1; - } - return -1; - } - /* return the number of bytes from src that have been used */ - if (!*mbstr) - return 0; -// if (count >= 2 && isleadbyte(*mbstr) && mbstr[1]) -// return 2; - return len; -} - -#else - -size_t mbstowcs(wchar_t* wcstr, const char* mbstr, size_t count) -{ - size_t size; - int i; - - if (wcstr == NULL) { - // return required size for the converted string - return strlen(mbstr); // TODO: fixme - } - for (size = 0, i = 0; i < count; size++) { - int result; - -//int mbtowc( wchar_t *wchar, const char *mbchar, size_t count ) -// result = mbtowc(wcstr + size, mbstr + i, count - i); - result = mbtowc(wcstr + size, mbstr + i, 1); - if (result == -1) { - return -1; - } else if (result == 0) { - wcstr[size] = L'\0'; - break; - } else { - i += result; - } - - } - return (size_t)size; -} - -#endif -#endif diff --git a/reactos/lib/sdk/crt/stdlib/mbtowc.c b/reactos/lib/sdk/crt/stdlib/mbtowc.c index 83cc5c62239..6830367dfc8 100644 --- a/reactos/lib/sdk/crt/stdlib/mbtowc.c +++ b/reactos/lib/sdk/crt/stdlib/mbtowc.c @@ -10,53 +10,36 @@ #include -#if 1 /* * @implemented */ -int mbtowc(wchar_t *dst, const char *str, size_t n) + +int mbtowc (wchar_t *charptr, const char *address, size_t number) { -// printf("\t\t\tmbtowc(%p, %p, %d) called.\n", dst, str, n); + int bytes; - if (n <= 0 || !str) - return 0; + if (address == 0) + return 0; - *dst = *str; + if ((bytes = mblen (address, number)) < 0) + return bytes; - if (!*str) - return 0; - return 1; -} - -#else - -int mbtowc(wchar_t *dst, const char *str, size_t n) -{ - if (n <= 0 || !str) - return 0; - if (!MultiByteToWideChar(CP_ACP, 0, str, n, dst, (dst == NULL) ? 0 : 1)) { - DWORD err = GetLastError(); - switch (err) { - case ERROR_INSUFFICIENT_BUFFER: - break; - case ERROR_INVALID_FLAGS: - break; - case ERROR_INVALID_PARAMETER: - break; - case ERROR_NO_UNICODE_TRANSLATION: - break; - default: - return 1; - } - return -1; + if (charptr) { + switch (bytes) { + case 0: + if (number > 0) + *charptr = (wchar_t) '\0'; + break; + case 1: + *charptr = (wchar_t) ((unsigned char) address[0]); + break; + case 2: + *charptr = (wchar_t) (((unsigned char) address[0] << 8) + | (unsigned char) address[1]); + break; + } } - /* return the number of bytes from src that have been used */ - if (!*str) - return 0; - if (n >= 2 && isleadbyte(*str) && str[1]) - return 2; - return 1; -} -#endif + return bytes; +} diff --git a/reactos/lib/sdk/crt/stdlib/putenv.c b/reactos/lib/sdk/crt/stdlib/putenv.c index f131605786f..ac90205e408 100644 --- a/reactos/lib/sdk/crt/stdlib/putenv.c +++ b/reactos/lib/sdk/crt/stdlib/putenv.c @@ -9,9 +9,6 @@ */ #include -#define NDEBUG -#include - /* misc/environ.c */ int SetEnv(const wchar_t *option); diff --git a/reactos/lib/sdk/crt/stdlib/senv.c b/reactos/lib/sdk/crt/stdlib/senv.c index c3379d39fb2..aa324efea92 100644 --- a/reactos/lib/sdk/crt/stdlib/senv.c +++ b/reactos/lib/sdk/crt/stdlib/senv.c @@ -13,8 +13,13 @@ #include #include -#define NDEBUG -#include +#ifdef _UNICODE + #define sT "S" +#else + #define sT "s" +#endif + +#define MK_STR(s) #s /* @@ -27,7 +32,7 @@ void _tsearchenv(const _TCHAR* file,const _TCHAR* var,_TCHAR* path) _TCHAR* y; _TCHAR* FilePart; - DPRINT(MK_STR(_tsearchenv)"()\n"); + TRACE(MK_STR(_tsearchenv)"()\n"); x = _tcschr(env,'='); if ( x != NULL ) { diff --git a/reactos/lib/sdk/crt/stdlib/wputenv.c b/reactos/lib/sdk/crt/stdlib/wputenv.c index a811b99454c..9203d17b97c 100644 --- a/reactos/lib/sdk/crt/stdlib/wputenv.c +++ b/reactos/lib/sdk/crt/stdlib/wputenv.c @@ -1,7 +1,5 @@ #include -#define NDEBUG -#include /* misc/environ.c */ int SetEnv(const wchar_t *option); diff --git a/reactos/lib/sdk/crt/string/scanf.c b/reactos/lib/sdk/crt/string/scanf.c index d3269c95eb8..1612eeb33c4 100644 --- a/reactos/lib/sdk/crt/string/scanf.c +++ b/reactos/lib/sdk/crt/string/scanf.c @@ -28,10 +28,10 @@ #include #include -#define NDEBUG -#include - -#define WARN DPRINT1 +// HACK for LIBCNT +#ifndef debugstr_a +#define debugstr_a +#endif extern FILE _iob[]; diff --git a/reactos/lib/sdk/crt/string/wcstom.c b/reactos/lib/sdk/crt/string/wcstom.c index 0c74f97c15e..001714a2852 100644 --- a/reactos/lib/sdk/crt/string/wcstom.c +++ b/reactos/lib/sdk/crt/string/wcstom.c @@ -1,20 +1,39 @@ -#include +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/msvcrt/mbstring/wcstom.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ + +#include +#include /* - * @unimplemented + * @implemented */ -size_t wcstombs (char* mbsDest, const wchar_t* wsConvert, size_t size) +size_t wcstombs (char *string, const wchar_t *widechar, size_t count) { - return 0; -} + int n, bytes; + int cnt = 0; -/* - * @unimplemented - */ -int wctomb (char* mbDest, wchar_t wc) -{ - return 0; + for (n = 0; n < count; n++) { + + if ((bytes = wctomb (string, *widechar)) < 0) + return -1; + + if (*string == 0) + return cnt; + + widechar++; + string += bytes; + cnt += bytes; + } + + return cnt; } - diff --git a/reactos/lib/sdk/crt/string/wctomb.c b/reactos/lib/sdk/crt/string/wctomb.c index ed17f498fbf..367d80f3a26 100644 --- a/reactos/lib/sdk/crt/string/wctomb.c +++ b/reactos/lib/sdk/crt/string/wctomb.c @@ -1,145 +1,47 @@ -/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/sdk/crt/mbstring/wctomb.c + * PURPOSE: + * PROGRAMER: + * UPDATE HISTORY: + * 05/30/08: Samuel Serapion adapted from PROJECT C Library + * + */ #include - -int -STDCALL -WideCharToMultiByte( - UINT CodePage, - DWORD dwFlags, - LPCWSTR lpWideCharStr, - int cchWideChar, - LPSTR lpMultiByteStr, - int cchMultiByte, - LPCSTR lpDefaultChar, - LPBOOL lpUsedDefaultChar); - +#include /* - * @unimplemented + * @implemented */ -int wctomb(char* dst, wchar_t ch) +int wctomb (char *string, wchar_t widechar) { -#if 0 - return WideCharToMultiByte(CP_ACP, 0, &ch, 1, dst, 6, NULL, NULL); -#else - if (dst == NULL) { - return 1; - } else if (0 != (ch & 0xff00)) { - return -1; + int c1, c2; + + if (string == 0) + return 0; + + if (widechar & 0xff00) { + + c1 = (widechar >> 8) & 0xff; + c2 = (widechar & 0xff); + + if (_ismbblead (c1) == 0 || _ismbbtrail (c2) == 0) + return -1; + + *string++ = (char) c1; + *string = (char) c2; + + return 2; + + } + else { + + *string = (char) widechar & 0xff; + + return 1; + } - *dst = ch; - return 1; -#endif } - -#if 0 - -#ifndef EILSEQ -#define EILSEQ EINVAL -#endif - -static const wchar_t encoding_mask[] = -{ - /* This reflects the sources *nix origin where type wchar_t - was 32 bits wide. Since our type wchar_t is only 16 bits - wide all this module will need to be reviewed. - Simplest option may well be to forward this modules work - on to the kernel which already has support for this. - */ - ~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff - //~0x0000-07ff, ~0x0000-ffff, ~0x001f-ffff, ~0x03ff-ffff -}; - -static const unsigned char encoding_byte[] = -{ - 0xc0, 0xe0, 0xf0, 0xf8, 0xfc -}; - -/* The state is for this UTF8 encoding not used. */ -//static mbstate_t internal; -//extern mbstate_t __no_r_state; /* Defined in mbtowc.c. */ - -size_t __wcrtomb(char *s, wchar_t wc); - -/* Convert WCHAR into its multibyte character representation, - putting this in S and returning its length. - - Attention: this function should NEVER be intentionally used. - The interface is completely stupid. The state is shared between - all conversion functions. You should use instead the restartable - version `wcrtomb'. */ - -int wctomb(char *s, wchar_t wchar) -{ - /* If S is NULL the function has to return null or not null - depending on the encoding having a state depending encoding or - not. This is nonsense because any multibyte encoding has a - state. The ISO C amendment 1 corrects this while introducing the - restartable functions. We simply say here all encodings have a - state. */ - if (s == NULL) { - return 1; - } - return __wcrtomb(s, wchar); -} - -size_t __wcrtomb(char *s, wchar_t wc) -{ - char fake[1]; - size_t written = 0; - - if (s == NULL) { - s = fake; - wc = L'\0'; - } - /* Store the UTF8 representation of WC. */ - //if (wc < 0 || wc > 0x7fffffff) { - if (wc < 0 || wc > 0x7fff) { - /* This is no correct ISO 10646 character. */ - __set_errno (EILSEQ); - return (size_t) -1; - } - if (wc < 0x80) { - /* It's a one byte sequence. */ - if (s != NULL) { - *s = (char)wc; - } - return 1; - } - for (written = 2; written < 6; ++written) { - if ((wc & encoding_mask[written - 2]) == 0) { - break; - } - } - if (s != NULL) { - size_t cnt = written; - s[0] = encoding_byte[cnt - 2]; - --cnt; - do { - s[cnt] = 0x80 | (wc & 0x3f); - wc >>= 6; - } while (--cnt > 0); - s[0] |= wc; - } - return written; -} - -#endif diff --git a/reactos/lib/sdk/crt/sys_stat/fstati64.c b/reactos/lib/sdk/crt/sys_stat/fstati64.c index 0c904f80942..4a5b47ff292 100644 --- a/reactos/lib/sdk/crt/sys_stat/fstati64.c +++ b/reactos/lib/sdk/crt/sys_stat/fstati64.c @@ -11,8 +11,6 @@ #include #include -#define NDEBUG -#include /* * @implemented @@ -83,6 +81,6 @@ int _fstati64(int fd, struct _stati64* statbuf) int _fstat64(int fd, struct __stat64* buf) { - DPRINT1("stub\n"); + FIXME("stub\n"); return -1; } diff --git a/reactos/lib/sdk/crt/sys_stat/stat.c b/reactos/lib/sdk/crt/sys_stat/stat.c index 1f13804fbbb..1dae23e7521 100644 --- a/reactos/lib/sdk/crt/sys_stat/stat.c +++ b/reactos/lib/sdk/crt/sys_stat/stat.c @@ -12,9 +12,6 @@ #include #include -#define NDEBUG -#include - /* 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)) @@ -139,7 +136,7 @@ int CDECL _stat64(const char* path, struct __stat64 * buf) if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi)) { - DPRINT1("failed (%d)\n",GetLastError()); + ERR("failed (%d)\n",GetLastError()); *_errno() = ERROR_FILE_NOT_FOUND; return -1; } @@ -186,10 +183,11 @@ int CDECL _stat64(const char* path, struct __stat64 * buf) 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, + TRACE("%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; } + diff --git a/reactos/lib/sdk/crt/time/ctime.c b/reactos/lib/sdk/crt/time/ctime.c index 6848a88fb14..822003b9fc4 100644 --- a/reactos/lib/sdk/crt/time/ctime.c +++ b/reactos/lib/sdk/crt/time/ctime.c @@ -46,6 +46,7 @@ #define CPP_CONST #endif +#undef P #define P(s) s #define alloc_size_t size_t #define qsort_size_t size_t diff --git a/reactos/lib/sdk/crt/wine/heap.c b/reactos/lib/sdk/crt/wine/heap.c index f72c46fbb4d..d183ebc3273 100644 --- a/reactos/lib/sdk/crt/wine/heap.c +++ b/reactos/lib/sdk/crt/wine/heap.c @@ -23,13 +23,6 @@ #include -#include -#include -#include - -#define NDEBUG -#include - /* MT */ #define LOCK_HEAP _mlock( _HEAP_LOCK ) #define UNLOCK_HEAP _munlock( _HEAP_LOCK ) @@ -55,7 +48,7 @@ static size_t MSVCRT_sbh_threshold = 0; void* MSVCRT_operator_new(unsigned long size) { void *retval = malloc(size); - DPRINT("(%ld) returning %p\n", size, retval); + TRACE("(%ld) returning %p\n", size, retval); LOCK_HEAP; if(!retval && MSVCRT_new_handler) (*MSVCRT_new_handler)(size); @@ -68,7 +61,7 @@ void* MSVCRT_operator_new(unsigned long size) */ void MSVCRT_operator_delete(void *mem) { - DPRINT("(%p)\n", mem); + TRACE("(%p)\n", mem); free(mem); } @@ -108,7 +101,7 @@ MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func) */ MSVCRT_new_handler_func MSVCRT_set_new_handler(void *func) { - DPRINT("(%p)\n",func); + TRACE("(%p)\n",func); MSVCRT__set_new_handler(NULL); return NULL; } @@ -158,7 +151,7 @@ int CDECL _set_sbh_threshold(size_t threshold) */ int _heapadd(void* mem, size_t size) { - DPRINT("(%p,%d) unsupported in Win32\n", mem,size); + TRACE("(%p,%d) unsupported in Win32\n", mem,size); *_errno() = ENOSYS; return -1; }