From 6ecabf7cae3145931889eed5466b51740eddd1c7 Mon Sep 17 00:00:00 2001
From: Piotr Caban <piotr@codeweavers.com>
Date: Wed, 27 Apr 2011 20:09:00 +0200
Subject: [PATCH] msvcrt: Added _set_printf_count_output and
 _get_printf_count_output implementation.

---
 dlls/msvcr100/msvcr100.c    |  3 ++-
 dlls/msvcr100/msvcr100.spec |  4 ++--
 dlls/msvcr80/Makefile.in    |  2 ++
 dlls/msvcr80/msvcr80.c      |  2 ++
 dlls/msvcr80/msvcr80.spec   |  4 ++--
 dlls/msvcr90/msvcr90.c      |  2 ++
 dlls/msvcr90/msvcr90.spec   |  4 ++--
 dlls/msvcrt/msvcrt.spec     |  2 ++
 dlls/msvcrt/printf.h        | 10 +++++++++-
 dlls/msvcrt/wcs.c           | 16 ++++++++++++++++
 include/msvcrt/stdio.h      |  2 ++
 11 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.c b/dlls/msvcr100/msvcr100.c
index 274d4c75d99..5ea84d114dd 100644
--- a/dlls/msvcr100/msvcr100.c
+++ b/dlls/msvcr100/msvcr100.c
@@ -20,7 +20,7 @@
 
 #include <stdarg.h>
 
-#include "stdlib.h"
+#include "stdio.h"
 #include "windef.h"
 #include "winbase.h"
 
@@ -37,6 +37,7 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
 
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls(hdll);
+        _set_printf_count_output(0);
     }
     return TRUE;
 }
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 4a724bc70b1..8ef8eac3723 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -686,7 +686,7 @@
 @ cdecl _get_osfhandle(long) msvcrt._get_osfhandle
 @ cdecl _get_output_format() msvcrt._get_output_format
 @ stub _get_pgmptr
-@ stub _get_printf_count_output
+@ cdecl _get_printf_count_output() msvcrt._get_printf_count_output
 @ stub _get_purecall_handler
 @ cdecl _get_terminate() msvcrt._get_terminate
 @ stub _get_timezone
@@ -1077,7 +1077,7 @@
 @ cdecl _set_invalid_parameter_handler(ptr) msvcrt._set_invalid_parameter_handler
 @ stub _set_malloc_crt_max_wait
 @ stub _set_output_format
-@ stub _set_printf_count_output
+@ cdecl _set_printf_count_output(long) msvcrt._set_printf_count_output
 @ cdecl _set_purecall_handler(ptr) msvcrt._set_purecall_handler
 @ cdecl _seterrormode(long) msvcrt._seterrormode
 @ cdecl -arch=i386,x86_64 -norelay _setjmp(ptr) msvcrt._setjmp
diff --git a/dlls/msvcr80/Makefile.in b/dlls/msvcr80/Makefile.in
index 17f3f66c745..760f1bf13df 100644
--- a/dlls/msvcr80/Makefile.in
+++ b/dlls/msvcr80/Makefile.in
@@ -1,5 +1,7 @@
 MODULE    = msvcr80.dll
 IMPORTS   = msvcrt
+MODCFLAGS = @BUILTINFLAG@
+EXTRAINCL = -I$(top_srcdir)/include/msvcrt
 
 C_SRCS = \
 	msvcr80.c
diff --git a/dlls/msvcr80/msvcr80.c b/dlls/msvcr80/msvcr80.c
index 3f81dcb216d..3953e0e1952 100644
--- a/dlls/msvcr80/msvcr80.c
+++ b/dlls/msvcr80/msvcr80.c
@@ -20,6 +20,7 @@
 
 #include <stdarg.h>
 
+#include "stdio.h"
 #include "windef.h"
 #include "winbase.h"
 
@@ -32,6 +33,7 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
 
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls(hdll);
+        _set_printf_count_output(0);
     }
     return TRUE;
 }
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 3f5bd041a93..05e179ac941 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -530,7 +530,7 @@
 @ stub _get_osver
 @ cdecl _get_output_format() msvcrt._get_output_format
 @ stub _get_pgmptr
-@ stub _get_printf_count_output
+@ cdecl _get_printf_count_output() msvcrt._get_printf_count_output
 @ stub _get_purecall_handler
 @ cdecl _get_sbh_threshold() msvcrt._get_sbh_threshold
 @ cdecl _get_terminate() msvcrt._get_terminate
@@ -930,7 +930,7 @@
 @ cdecl _set_invalid_parameter_handler(ptr) msvcrt._set_invalid_parameter_handler
 @ stub _set_malloc_crt_max_wait
 @ stub _set_output_format
-@ stub _set_printf_count_output
+@ cdecl _set_printf_count_output(long) msvcrt._set_printf_count_output
 @ cdecl _set_purecall_handler(ptr) msvcrt._set_purecall_handler
 @ cdecl _set_sbh_threshold(long) msvcrt._set_sbh_threshold
 @ cdecl _seterrormode(long) msvcrt._seterrormode
diff --git a/dlls/msvcr90/msvcr90.c b/dlls/msvcr90/msvcr90.c
index fe563e37771..fd24f11494b 100644
--- a/dlls/msvcr90/msvcr90.c
+++ b/dlls/msvcr90/msvcr90.c
@@ -22,6 +22,7 @@
 #include <stdarg.h>
 
 #include "stdlib.h"
+#include "stdio.h"
 #include "errno.h"
 #include "malloc.h"
 #include "windef.h"
@@ -101,6 +102,7 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
 
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls(hdll);
+        _set_printf_count_output(0);
     }
     return TRUE;
 }
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index c7efd3a6f09..9bc984fe86d 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -520,7 +520,7 @@
 @ cdecl _get_osfhandle(long) msvcrt._get_osfhandle
 @ cdecl _get_output_format() msvcrt._get_output_format
 @ stub _get_pgmptr
-@ stub _get_printf_count_output
+@ cdecl _get_printf_count_output() msvcrt._get_printf_count_output
 @ stub _get_purecall_handler
 @ cdecl _get_sbh_threshold() msvcrt._get_sbh_threshold
 @ cdecl _get_terminate() msvcrt._get_terminate
@@ -916,7 +916,7 @@
 @ cdecl _set_invalid_parameter_handler(ptr) msvcrt._set_invalid_parameter_handler
 @ stub _set_malloc_crt_max_wait
 @ stub _set_output_format
-@ stub _set_printf_count_output
+@ cdecl _set_printf_count_output(long) msvcrt._set_printf_count_output
 @ cdecl _set_purecall_handler(ptr) msvcrt._set_purecall_handler
 @ cdecl _set_sbh_threshold(long) msvcrt._set_sbh_threshold
 @ cdecl _seterrormode(long) msvcrt._seterrormode
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 94064fe0d27..8baa37e6ecd 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1491,3 +1491,5 @@
 @ cdecl -arch=i386 _statusfp2(ptr ptr)
 @ cdecl _wcstod_l(wstr ptr) MSVCRT__wcstod_l
 @ cdecl _wdupenv_s(ptr ptr str)
+@ cdecl _get_printf_count_output()
+@ cdecl _set_printf_count_output(long)
diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h
index 019875679f6..64d159eb5c8 100644
--- a/dlls/msvcrt/printf.h
+++ b/dlls/msvcrt/printf.h
@@ -491,7 +491,15 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
             i = FUNC_NAME(pf_output_format_str)(pf_puts, puts_ctx, buf, -1, &flags, locale);
 #endif
         } else if(flags.Format == 'n') {
-            int *used = pf_args(args_ctx, pos, VT_PTR, &valist).get_ptr;
+            int *used;
+
+            if(!n_format_enabled) {
+                MSVCRT_INVALID_PMT("\'n\' format specifier disabled");
+                *MSVCRT__errno() = MSVCRT_EINVAL;
+                return -1;
+            }
+
+            used = pf_args(args_ctx, pos, VT_PTR, &valist).get_ptr;
             *used = written;
             i = 0;
         } else if(flags.Format && strchr("diouxX", flags.Format)) {
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index 5a7a43cfb93..527bcffd445 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -33,11 +33,27 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
 
+static BOOL n_format_enabled = TRUE;
+
 #include "printf.h"
 #define PRINTF_WIDE
 #include "printf.h"
 #undef PRINTF_WIDE
 
+/* _get_printf_count_output - not exported in native msvcrt */
+int CDECL _get_printf_count_output( void )
+{
+    return n_format_enabled ? 1 : 0;
+}
+
+/* _set_printf_count_output - not exported in native msvcrt */
+int CDECL _set_printf_count_output( int enable )
+{
+    BOOL old = n_format_enabled;
+    n_format_enabled = (enable ? TRUE : FALSE);
+    return old ? 1 : 0;
+}
+
 /*********************************************************************
  *		_wcsdup (MSVCRT.@)
  */
diff --git a/include/msvcrt/stdio.h b/include/msvcrt/stdio.h
index c167110c08b..4e43635b51e 100644
--- a/include/msvcrt/stdio.h
+++ b/include/msvcrt/stdio.h
@@ -108,12 +108,14 @@ int    __cdecl _flsbuf(int,FILE*);
 int    __cdecl _flushall(void);
 int    __cdecl _fputchar(int);
 FILE*  __cdecl _fsopen(const char*,const char*,int);
+int    __cdecl _get_printf_count_output(void);
 int    __cdecl _getmaxstdio(void);
 int    __cdecl _getw(FILE*);
 int    __cdecl _pclose(FILE*);
 FILE*  __cdecl _popen(const char*,const char*);
 int    __cdecl _putw(int,FILE*);
 int    __cdecl _rmtmp(void);
+int    __cdecl _set_printf_count_output(int);
 int    __cdecl _setmaxstdio(int);
 int    __cdecl _snprintf(char*,size_t,const char*,...);
 int    __cdecl _snprintf_s(char*,size_t,size_t,const char*,...);
-- 
GitLab