Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169//// mktemp.cpp//// Copyright (c) Microsoft Corporation. All rights reserved.//// Defines _tmktemp() and _tmktemp_s(), which create unique file names.//#include <corecrt_internal_lowio.h>#include <corecrt_internal_securecrt.h>#include <mbctype.h>#include <process.h>#include <stddef.h>#include <stdio.h>
// These functions test whether we should continue scanning for X's.static bool common_mktemp_s_continue(char const* const string, char const* const current) throw(){ return !_ismbstrail( reinterpret_cast<unsigned char const*>(string), reinterpret_cast<unsigned char const*>(current));}
static bool common_mktemp_s_continue(wchar_t const* const, wchar_t const* const) throw(){ return true;}
// Creates a unique file name given a template string of the form "fnamXXXXXX".// The "XXXXXX" sequence is replaced by a letter and the five-digit thread// identifier.//// The template string is modified in-place. Returns 0 on success; returns an// errno error code on failure.template <typename Character>_Success_(return == 0)static errno_t __cdecl common_mktemp_s( _Inout_updates_z_(buffer_size_in_chars) Character* const template_string, size_t const buffer_size_in_chars ) throw(){ typedef __crt_char_traits<Character> traits;
_VALIDATE_RETURN_ERRCODE(template_string != nullptr && buffer_size_in_chars > 0, EINVAL);
size_t const template_string_length = traits::tcsnlen(template_string, buffer_size_in_chars); if (template_string_length >= buffer_size_in_chars) { _RESET_STRING(template_string, buffer_size_in_chars); _RETURN_DEST_NOT_NULL_TERMINATED(template_string, buffer_size_in_chars); } _FILL_STRING(template_string, buffer_size_in_chars, template_string_length + 1);
if(template_string_length < 6 || buffer_size_in_chars <= template_string_length) { _RESET_STRING(template_string, buffer_size_in_chars); _VALIDATE_RETURN_ERRCODE(("Incorrect Input for mktemp", 0), EINVAL); }
// The Win32 thread identifier is unique across all threads in all processes. // Note, however, that unlike *NIX process identifiers, which are not reused // until all values up to 32K have been used, Win32 thread identifiers are // frequenty reused and usually have small numbers. unsigned number = GetCurrentThreadId();
// 'string' points to the null-terminator: Character* string = template_string + template_string_length;
size_t template_length = 0;
// Replace the last five 'X' characters with the number: while (--string >= template_string && common_mktemp_s_continue(template_string, string) && *string == 'X' && template_length < 5) { ++template_length; *string = static_cast<Character>((number % 10) + '0'); number /= 10; }
// Too few X's? if (*string != 'X' || template_length < 5) { _RESET_STRING(template_string, buffer_size_in_chars); _VALIDATE_RETURN_ERRCODE(("Incorrect Input for mktemp", 0), EINVAL); }
// Finally, add the letter: Character letter = 'a';
*string = letter++;
errno_t const saved_errno = errno; errno = 0;
// Test each letter, from a-z, until we find a name that is not yet used: while (traits::taccess_s(template_string, 0) == 0) { if (letter == 'z' + 1) { _RESET_STRING(template_string, buffer_size_in_chars); errno = EEXIST; return errno; }
*string = letter++; errno = 0; }
// Restore the old value of errno and return success: errno = saved_errno; return 0;}
extern "C" errno_t __cdecl _mktemp_s( char* const template_string, size_t const buffer_size_in_chars ){ return common_mktemp_s(template_string, buffer_size_in_chars);}
extern "C" errno_t __cdecl _wmktemp_s( wchar_t* const template_string, size_t const buffer_size_in_chars ){ return common_mktemp_s(template_string, buffer_size_in_chars);}
// Creates a unique file name given a template string of the form "fnamXXXXXX".// The "XXXXXX" sequence is replaced by a letter and the five-digit thread// identifier. The template string is modified in-place.//// On success, returns the pointer to the modified template string. On failure,// nullptr is returned (e.g. if the template string is malformed or there are no// more unique names).template <typename Character>static Character* __cdecl common_mktemp( Character* const template_string ) throw(){ typedef __crt_char_traits<Character> traits;
_VALIDATE_RETURN(template_string != nullptr, EINVAL, nullptr);
errno_t const result = common_mktemp_s( template_string, static_cast<size_t>(traits::tcslen(template_string) + 1));
return result == 0 ? template_string : nullptr;}
extern "C" char* __cdecl _mktemp(char* const template_string){ return common_mktemp(template_string);}
extern "C" wchar_t* __cdecl _wmktemp(wchar_t* const template_string){ return common_mktemp(template_string);}