From 9b6c93f6f2b151f5b619e0365257135860d3d048 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 22 Dec 2015 17:43:20 +0100 Subject: [PATCH] msvcrt: Add tmpnam_s implementation. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- .../api-ms-win-crt-stdio-l1-1-0.spec | 2 +- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/file.c | 72 +++++++++++++++++----- dlls/msvcrt/msvcrt.h | 1 + dlls/msvcrt/msvcrt.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 11 files changed, 66 insertions(+), 25 deletions(-) diff --git a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec index 30570da208a..5e0c3c9b6bf 100644 --- a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec +++ b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec @@ -154,6 +154,6 @@ @ cdecl tmpfile() ucrtbase.tmpfile @ cdecl tmpfile_s(ptr) ucrtbase.tmpfile_s @ cdecl tmpnam(ptr) ucrtbase.tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) ucrtbase.tmpnam_s @ cdecl ungetc(long ptr) ucrtbase.ungetc @ cdecl ungetwc(long ptr) ucrtbase.ungetwc diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 666432a9f68..7fd53eac006 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1833,7 +1833,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ cdecl towlower(long) MSVCRT_towlower diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index ca7ed6f2c76..8c5e69402cd 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -2192,7 +2192,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ cdecl towlower(long) MSVCRT_towlower diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 6fe21c8ee3c..56f213b6fcc 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2411,7 +2411,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ stub towctrans diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index c104a7bb589..dd62c6a89b1 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -2073,7 +2073,7 @@ @ cdecl tmpfile() msvcr120.tmpfile @ cdecl tmpfile_s(ptr) msvcr120.tmpfile_s @ cdecl tmpnam(ptr) msvcr120.tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) msvcr120.tmpnam_s @ cdecl tolower(long) msvcr120.tolower @ cdecl toupper(long) msvcr120.toupper @ stub towctrans diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 7b50534371f..479051b771f 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1514,7 +1514,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ cdecl towlower(long) MSVCRT_towlower diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 6afb092ca88..01800c84b79 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1486,7 +1486,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ cdecl towlower(long) MSVCRT_towlower diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 22bb9253c4c..a708c6795de 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -128,6 +128,7 @@ static int MSVCRT_umask = 0; /* INTERNAL: static data for tmpnam and _wtmpname functions */ static int tmpnam_unique; +static int tmpnam_s_unique; static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e'; static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't'; @@ -4780,15 +4781,65 @@ void CDECL MSVCRT_setbuf(MSVCRT_FILE* file, char *buf) MSVCRT_setvbuf(file, buf, buf ? MSVCRT__IOFBF : MSVCRT__IONBF, MSVCRT_BUFSIZ); } +static int tmpnam_helper(char *s, MSVCRT_size_t size, int *tmpnam_unique, int tmp_max) +{ + char tmpstr[8]; + char *p = s; + int digits; + + if (!MSVCRT_CHECK_PMT(s != NULL)) return MSVCRT_EINVAL; + + if (size < 3) { + if (size) *s = 0; + *MSVCRT__errno() = MSVCRT_ERANGE; + return MSVCRT_ERANGE; + } + *p++ = '\\'; + *p++ = 's'; + size -= 2; + digits = msvcrt_int_to_base32(GetCurrentProcessId(), tmpstr); + if (digits+1 > size) { + *s = 0; + *MSVCRT__errno() = MSVCRT_ERANGE; + return MSVCRT_ERANGE; + } + memcpy(p, tmpstr, digits*sizeof(tmpstr[0])); + p += digits; + *p++ = '.'; + size -= digits+1; + + while(1) { + while ((digits = *tmpnam_unique)+1 < tmp_max) { + if (InterlockedCompareExchange(tmpnam_unique, digits+1, digits) == digits) + break; + } + + digits = msvcrt_int_to_base32(digits, tmpstr); + if (digits+1 > size) { + *s = 0; + *MSVCRT__errno() = MSVCRT_ERANGE; + return MSVCRT_ERANGE; + } + memcpy(p, tmpstr, digits*sizeof(tmpstr[0])); + p[digits] = 0; + + if (GetFileAttributesA(s) == INVALID_FILE_ATTRIBUTES && + GetLastError() == ERROR_FILE_NOT_FOUND) + break; + } + return 0; +} + +int CDECL MSVCRT_tmpnam_s(char *s, MSVCRT_size_t size) +{ + return tmpnam_helper(s, size, &tmpnam_s_unique, MSVCRT_TMP_MAX_S); +} + /********************************************************************* * tmpnam (MSVCRT.@) */ char * CDECL MSVCRT_tmpnam(char *s) { - char tmpstr[16]; - char *p; - int count, size; - if (!s) { thread_data_t *data = msvcrt_get_thread_data(); @@ -4798,18 +4849,7 @@ char * CDECL MSVCRT_tmpnam(char *s) s = data->tmpnam_buffer; } - msvcrt_int_to_base32(GetCurrentProcessId(), tmpstr); - p = s + sprintf(s, "\\s%s.", tmpstr); - for (count = 0; count < MSVCRT_TMP_MAX; count++) - { - size = msvcrt_int_to_base32(tmpnam_unique++, tmpstr); - memcpy(p, tmpstr, size); - p[size] = '\0'; - if (GetFileAttributesA(s) == INVALID_FILE_ATTRIBUTES && - GetLastError() == ERROR_FILE_NOT_FOUND) - break; - } - return s; + return tmpnam_helper(s, -1, &tmpnam_unique, MSVCRT_TMP_MAX) ? NULL : s; } /********************************************************************* diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 77f612e543e..e30e6754af9 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -663,6 +663,7 @@ struct MSVCRT__stat64 { #define MSVCRT_WEOF (MSVCRT_wint_t)(0xFFFF) #define MSVCRT_EOF (-1) #define MSVCRT_TMP_MAX 0x7fff +#define MSVCRT_TMP_MAX_S 0x7fffffff #define MSVCRT_RAND_MAX 0x7fff #define MSVCRT_BUFSIZ 512 diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index bffd860ae56..e2c3e6225a6 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1457,7 +1457,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -# stub tmpnam_s(ptr long) +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ cdecl towlower(long) MSVCRT_towlower diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 87c881267f4..604cc782c3c 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2539,7 +2539,7 @@ @ cdecl tmpfile() MSVCRT_tmpfile @ cdecl tmpfile_s(ptr) MSVCRT_tmpfile_s @ cdecl tmpnam(ptr) MSVCRT_tmpnam -@ stub tmpnam_s +@ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper @ stub towctrans -- 2.11.4.GIT