Skip to content
This repository has been archived by the owner on Dec 8, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed Jul 30, 2019
1 parent aec5e2d commit b84814e
Show file tree
Hide file tree
Showing 11 changed files with 285 additions and 7 deletions.
3 changes: 2 additions & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,9 @@ If VC-LTL is referenced correctly, it will be output at the time of generation:
* Improve, the `_ATL_XP_TARGETING` and `_USING_V110_SDK71_` macros in Vista mode are adjusted from error to warning.


### 4.0.2.7 - Improved Support (July 27, 2019 14:00)
### 4.0.2.8 - Improved Support (July 30, 2019 14:00)
* Fix Bug, Windows XP mode can't find `__wcsrtombs_utf8` symbol (Thunks To 水边).
* Fix [Bug 56](https://github.com/Chuyu-Team/VC-LTL/issues/56), solve (w)printf, std::(w)cout, etc. can not output text other than ASCII.
* New Fea, add `_CRT_STDIO_ISO_WIDE_SPECIFIERS` macro and `legacy_stdio_definitions.lib` support (Thanks to BigBrother).
* New Fea, add `_initialize_invalid_parameter_handler`, `_initialize_denormal_control` and `_get_startup_thread_locale_mode (Vista mode only)` support。
* New Fea, add 14.22.27905 toolset support.
Expand Down
3 changes: 2 additions & 1 deletion ReadMe.osc.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,9 @@ nmake /f Test.mak
* 改进体验,Vista模式将`_ATL_XP_TARGETING`以及`_USING_V110_SDK71_`宏从错误降级到警告。


### 4.0.2.7 - 改进支持(2019-07-27 14:00)
### 4.0.2.8 - 改进支持(2019-07-30 14:00)
* 解决Bug,Windows XP模式找不到 `__wcsrtombs_utf8` 符号问题(感谢 水边)。
* 解决[Bug 56](https://github.com/Chuyu-Team/VC-LTL/issues/56),解决(w)printf、std::(w)cout等无法输出中文问题。
* 新增Fea,添加 `_CRT_STDIO_ISO_WIDE_SPECIFIERS` 宏以及 `legacy_stdio_definitions.lib` 支持(感谢 大胸)。
* 新增Fea,添加`_initialize_invalid_parameter_handler``_initialize_denormal_control``_get_startup_thread_locale_mode(仅Vista模式)`支持。
* 新增Fea,添加 14.22.27905 工具集支持。
Expand Down
Binary file modified src/Shared-Resource.h
Binary file not shown.
Binary file modified src/msvcrt_forward.def
Binary file not shown.
151 changes: 151 additions & 0 deletions src/ucrt/fputwc_thunks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <Windows.h>
#include <corecrt_wstdio.h>
#include <stdio.h>
#include <corecrt_internal_stdio.h>

extern "C" __declspec(dllimport) extern _iobuf _iob[_IOB_ENTRIES];


namespace VC_LTL_Thunks
{
extern "C" __declspec(dllimport) wint_t __cdecl fputwc(
_In_ wchar_t _Character,
_Inout_ FILE* _Stream);

extern "C" __declspec(dllimport) size_t __cdecl fwrite(
_In_reads_bytes_(_ElementSize * _ElementCount) void const* _Buffer,
_In_ size_t _ElementSize,
_In_ size_t _ElementCount,
_Inout_ FILE* _Stream
);

extern "C" __declspec(dllimport) int __cdecl fputc(
_In_ int _Character,
_Inout_ FILE* _Stream
);
}

extern "C" wint_t __cdecl fputwc(
wchar_t _Character,
FILE* _Stream)
{
if ((_Character & (~0x7F))
&&(_Stream == /*stdout*/&_iob[1] || _Stream == /*stderr*/&_iob[2]))
{
_lock_file(_Stream);
auto Success = __acrt_stdio_begin_temporary_buffering_nolock(_Stream);
wint_t result = VC_LTL_Thunks::fputwc(_Character, _Stream);
__acrt_stdio_end_temporary_buffering_nolock(Success, _Stream);
_unlock_file(_Stream);

return result;
}

return VC_LTL_Thunks::fputwc(_Character, _Stream);
}

extern "C" wint_t __cdecl putwc(
wchar_t _Character,
FILE* _Stream
)
{
return fputwc(_Character, _Stream);
}

extern "C" wint_t __cdecl _fputwchar(
wchar_t _Character
)
{
return fputwc(_Character,/*stdout*/&_iob[1]);
}

extern "C" size_t __cdecl fwrite(
void const* const buffer,
size_t const size,
size_t const count,
FILE* const stream
)
{
if (stream == /*stdout*/&_iob[1] || stream == /*stderr*/&_iob[2])
{
_lock_file(stream);
auto Success = __acrt_stdio_begin_temporary_buffering_nolock(stream);
wint_t result = VC_LTL_Thunks::fwrite(buffer, size, count, stream);
__acrt_stdio_end_temporary_buffering_nolock(Success, stream);
_unlock_file(stream);

return result;
}
else
{
return VC_LTL_Thunks::fwrite(buffer, size, count, stream);
}
}

extern "C" int __cdecl fputc(int const c, FILE* const stream)
{
if ((c & 0x80)
&&(stream == /*stdout*/&_iob[1] || stream == /*stderr*/&_iob[2]))
{
_lock_file(stream);
static bool stdout_buffer_used = false;
static bool stderr_buffer_used = false;

static char stdout_buffer[2];

static char stderr_buffer[2];


bool* buffer_used;
char* buffer;
if (stream == /*stdout*/&_iob[1])
{
buffer_used = &stdout_buffer_used;
buffer = stdout_buffer;
}
else
{
buffer_used = &stderr_buffer_used;
buffer = stderr_buffer;
}

if (*buffer_used)
{
buffer[1] = c;
auto Success = __acrt_stdio_begin_temporary_buffering_nolock(stream);
auto result = VC_LTL_Thunks::fwrite(buffer, 1, 2, stream);
__acrt_stdio_end_temporary_buffering_nolock(Success, stream);
_unlock_file(stream);

*buffer_used = false;


return result ? c : EOF;
}
else if (isleadbyte(c))
{
*buffer_used = true;
buffer[0] = c;
return c;
}
}

return VC_LTL_Thunks::fputc(c, stream);
}



extern "C" int __cdecl putc(
int _Character,
FILE* _Stream
)
{
return fputc(_Character, _Stream);
}

extern "C" int __cdecl _fputchar(
int _Character
)
{
return fputc(_Character, /*stdout*/&_iob[1]);
}
11 changes: 7 additions & 4 deletions src/ucrt/internal/initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ extern "C" {

//extern _onexit_table_t __acrt_atexit_table;
extern _onexit_table_t __acrt_at_quick_exit_table;
//extern void* __acrt_stdout_buffer;
//extern void* __acrt_stderr_buffer;
extern void* __acrt_stdout_buffer;
extern void* __acrt_stderr_buffer;


#if 0
Expand Down Expand Up @@ -180,6 +180,7 @@ static bool __cdecl uninitialize_allocated_memory(bool const /* terminating */)

return true;
}
#endif

// C4505: unreferenced local function
#pragma warning( suppress: 4505 )
Expand All @@ -191,15 +192,17 @@ static bool __cdecl uninitialize_allocated_io_buffers(bool const /* terminating
_free_crt(__acrt_stderr_buffer);
__acrt_stderr_buffer = nullptr;

#if 0 //msvcrt.dl»áÊÍ·ÅËûÃÇ
_free_crt(__argv);
__argv = nullptr;

_free_crt(__wargv);
__wargv = nullptr;

#endif
return true;
}

#if 0
static bool __cdecl report_memory_leaks(bool const /* terminating */)
{
#ifdef _DEBUG
Expand Down Expand Up @@ -267,7 +270,7 @@ static __acrt_initializer const __acrt_initializers[] =
//{ nullptr, report_memory_leaks },
// Enclaves only require initializers for supported features.
#ifndef _UCRT_ENCLAVE_BUILD
//{ nullptr, uninitialize_allocated_io_buffers },
{ nullptr, uninitialize_allocated_io_buffers },
#endif
//{ nullptr, uninitialize_allocated_memory },
// Enclaves only require initializers for supported features.
Expand Down
79 changes: 79 additions & 0 deletions src/ucrt/sftbuf_thunks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <corecrt_internal_stdio.h>

// Buffer pointers for stdout and stderr
extern "C" void* __acrt_stdout_buffer = nullptr;
extern "C" void* __acrt_stderr_buffer = nullptr;

extern "C" __declspec(dllimport) extern _iobuf _iob[_IOB_ENTRIES];

extern "C" bool __cdecl __acrt_stdio_begin_temporary_buffering_nolock(
FILE* const public_stream
)
{
// Do nothing if the stream is not backed by a TTY device
if (!_isatty(_fileno(public_stream)))
return false;


void** buffer;
if (public_stream == /*stdout*/&_iob[1])
buffer = &__acrt_stdout_buffer;
else if (public_stream == /*stderr*/&_iob[2])
buffer = &__acrt_stderr_buffer;
else
return false;

//_IOBUFFER_SETVBUF |
if (public_stream->_flags & 0x10C)
return false;

public_stream->_flags |= 0x1102u;

if (*buffer == nullptr)
{
auto tmp = malloc(_INTERNAL_BUFSIZ);

if (tmp == nullptr)
{
// If we failed to allocate a buffer, use the small character buffer:
public_stream->_base = reinterpret_cast<char*>(&public_stream->_charbuf);
public_stream->_ptr = reinterpret_cast<char*>(&public_stream->_charbuf);
public_stream->_cnt = 2;
public_stream->_bufsiz = 2;
return true;
}

*buffer = tmp;
}

// Otherwise, we have a new buffer, so set it up for use:
public_stream->_base = reinterpret_cast<char*>(*buffer);
public_stream->_ptr = reinterpret_cast<char*>(*buffer);
public_stream->_cnt = _INTERNAL_BUFSIZ;
public_stream->_bufsiz = _INTERNAL_BUFSIZ;
return true;
}


// If the stream currently has a temporary buffer that was set via a call to
// __acrt_stdio_begin_temporary_buffering_nolock(), and if the flag value is
// 1, this function flushes the stream and disables buffering of the stream.
extern "C" void __cdecl __acrt_stdio_end_temporary_buffering_nolock(
bool const flag,
FILE* const public_stream
)
{
if (!flag)
return;

if (public_stream->_flags & 0x1000)
{
//_flush(public_stream);,凑合用 fflush 吧,虽然会多进一次临界区但是影响不大。
fflush(public_stream);

public_stream->_flags &= 0xFFFFEEFF;
public_stream->_bufsiz = 0;
public_stream->_ptr = 0;
public_stream->_base = 0;
}
}
2 changes: 1 addition & 1 deletion src/ucrt/stdio/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static int __cdecl common_vfprintf(

return __acrt_lock_stream_and_call(stream, [&]() -> int
{
//__acrt_stdio_temporary_buffering_guard const buffering(stream);
__acrt_stdio_temporary_buffering_guard const buffering(stream);

//_LocaleUpdate locale_update(locale);
processor_type processor(
Expand Down
Loading

0 comments on commit b84814e

Please sign in to comment.