diff options
Diffstat (limited to '')
-rw-r--r-- | sdk/dx8sdk/Include/strsafe.h | 6611 |
1 files changed, 0 insertions, 6611 deletions
diff --git a/sdk/dx8sdk/Include/strsafe.h b/sdk/dx8sdk/Include/strsafe.h deleted file mode 100644 index 061b3c4d..00000000 --- a/sdk/dx8sdk/Include/strsafe.h +++ /dev/null @@ -1,6611 +0,0 @@ -/****************************************************************** -* * -* strsafe.h -- This module defines safer C library string * -* routine replacements. These are meant to make C * -* a bit more safe in reference to security and * -* robustness * -* * -* Copyright (c) Microsoft Corp. All rights reserved. * -* * -******************************************************************/ -#ifndef _STRSAFE_H_INCLUDED_ -#define _STRSAFE_H_INCLUDED_ -#pragma once - -#include <stdio.h> // for _vsnprintf, _vsnwprintf, getc, getwc -#include <string.h> // for memset -#include <stdarg.h> // for va_start, etc. - - -#ifndef _SIZE_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 size_t; -#else -typedef __w64 unsigned int size_t; -#endif // !_WIN64 -#define _SIZE_T_DEFINED -#endif // !_SIZE_T_DEFINED - -#if !defined(_WCHAR_T_DEFINED) && !defined(_NATIVE_WCHAR_T_DEFINED) -typedef unsigned short wchar_t; -#define _WCHAR_T_DEFINED -#endif - -#ifndef _HRESULT_DEFINED -#define _HRESULT_DEFINED -typedef long HRESULT; -#endif // !_HRESULT_DEFINED - -#ifndef SUCCEEDED -#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) -#endif - -#ifndef FAILED -#define FAILED(hr) ((HRESULT)(hr) < 0) -#endif - -#ifndef S_OK -#define S_OK ((HRESULT)0x00000000L) -#endif - -#ifdef __cplusplus -#define _STRSAFE_EXTERN_C extern "C" -#else -#define _STRSAFE_EXTERN_C extern -#endif - -// If you do not want to use these functions inline (and instead want to link w/ strsafe.lib), then -// #define STRSAFE_LIB before including this header file. -#if defined(STRSAFE_LIB) -#define STRSAFEAPI _STRSAFE_EXTERN_C HRESULT __stdcall -#pragma comment(lib, "strsafe.lib") -#elif defined(STRSAFE_LIB_IMPL) -#define STRSAFEAPI _STRSAFE_EXTERN_C HRESULT __stdcall -#else -#define STRSAFEAPI __inline HRESULT __stdcall -#define STRSAFE_INLINE -#endif - -// Some functions always run inline because they use stdin and we want to avoid building multiple -// versions of strsafe lib depending on if you use msvcrt, libcmt, etc. -#define STRSAFE_INLINE_API __inline HRESULT __stdcall - -// The user can request no "Cb" or no "Cch" fuctions, but not both! -#if defined(STRSAFE_NO_CB_FUNCTIONS) && defined(STRSAFE_NO_CCH_FUNCTIONS) -#error cannot specify both STRSAFE_NO_CB_FUNCTIONS and STRSAFE_NO_CCH_FUNCTIONS !! -#endif - -// This should only be defined when we are building strsafe.lib -#ifdef STRSAFE_LIB_IMPL -#define STRSAFE_INLINE -#endif - - -// If both strsafe.h and ntstrsafe.h are included, only use definitions from one. -#ifndef _NTSTRSAFE_H_INCLUDED_ - -#define STRSAFE_MAX_CCH 2147483647 // max # of characters we support (same as INT_MAX) - -// Flags for controling the Ex functions -// -// STRSAFE_FILL_BYTE(0xFF) 0x000000FF // bottom byte specifies fill pattern -#define STRSAFE_IGNORE_NULLS 0x00000100 // treat null as TEXT("") -- don't fault on NULL buffers -#define STRSAFE_FILL_BEHIND_NULL 0x00000200 // fill in extra space behind the null terminator -#define STRSAFE_FILL_ON_FAILURE 0x00000400 // on failure, overwrite pszDest with fill pattern and null terminate it -#define STRSAFE_NULL_ON_FAILURE 0x00000800 // on failure, set *pszDest = TEXT('\0') -#define STRSAFE_NO_TRUNCATION 0x00001000 // instead of returning a truncated result, copy/append nothing to pszDest and null terminate it - -#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) - -// helper macro to set the fill character and specify buffer filling -#define STRSAFE_FILL_BYTE(x) ((unsigned long)((x & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) -#define STRSAFE_FAILURE_BYTE(x) ((unsigned long)((x & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) - -#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)(dwFlags & 0x000000FF)) - -#endif // _NTSTRSAFE_H_INCLUDED_ - -// STRSAFE error return codes -// -#define STRSAFE_E_INSUFFICIENT_BUFFER ((HRESULT)0x8007007AL) // 0x7A = 122L = ERROR_INSUFFICIENT_BUFFER -#define STRSAFE_E_INVALID_PARAMETER ((HRESULT)0x80070057L) // 0x57 = 87L = ERROR_INVALID_PARAMETER -#define STRSAFE_E_END_OF_FILE ((HRESULT)0x80070026L) // 0x26 = 38L = ERROR_HANDLE_EOF - -// prototypes for the worker functions -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc); -STRSAFEAPI StringCopyWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); -STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCopyExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc); -STRSAFEAPI StringCopyNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc); -STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCopyNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc); -STRSAFEAPI StringCatWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); -STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend); -STRSAFEAPI StringCatNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend); -STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList); -STRSAFEAPI StringVPrintfWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList); -STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList); -STRSAFEAPI StringVPrintfExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList); -STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch); -STRSAFEAPI StringLengthWorkerW(const wchar_t* psz, size_t cchMax, size_t* pcch); -#endif // STRSAFE_INLINE - -#ifndef STRSAFE_LIB_IMPL -// these functions are always inline -STRSAFE_INLINE_API StringGetsExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFE_INLINE_API StringGetsExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#endif - -#ifdef _NTSTRSAFE_H_INCLUDED_ -#pragma warning(push) -#pragma warning(disable : 4995) -#endif // _NTSTRSAFE_H_INCLUDED_ - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCopy( - OUT LPTSTR pszDest, - IN size_t cchDest, - IN LPCTSTR pszSrc - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcpy'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is not a replacement for strncpy. That function will pad the - destination string with extra null termination characters if the count is - greater than the length of the source string, and it will fail to null - terminate the destination string if the source string length is greater - than or equal to the count. You can not blindly use this instead of strncpy: - it is common for code to use it to "patch" strings and you would introduce - errors if the code started null terminating in the middle of the string. - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was copied without truncation and null terminated, - otherwise it will return a failure code. In failure cases as much of - pszSrc will be copied to pszDest as possible, and pszDest will be null - terminated. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(src) + 1) to hold all of the - source including the null terminator - - pszSrc - source string which must be null terminated - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCopyEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc); -STRSAFEAPI StringCchCopyW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); -#ifdef UNICODE -#define StringCchCopy StringCchCopyW -#else -#define StringCchCopy StringCchCopyA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyWorkerA(pszDest, cchDest, pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCchCopyW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyWorkerW(pszDest, cchDest, pszSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCopy( - OUT LPTSTR pszDest, - IN size_t cbDest, - IN LPCTSTR pszSrc - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcpy'. - The size of the destination buffer (in bytes) is a parameter and this - function will not write past the end of this buffer and it will ALWAYS - null terminate the destination buffer (unless it is zero length). - - This routine is not a replacement for strncpy. That function will pad the - destination string with extra null termination characters if the count is - greater than the length of the source string, and it will fail to null - terminate the destination string if the source string length is greater - than or equal to the count. You can not blindly use this instead of strncpy: - it is common for code to use it to "patch" strings and you would introduce - errors if the code started null terminating in the middle of the string. - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was copied without truncation and null terminated, - otherwise it will return a failure code. In failure cases as much of pszSrc - will be copied to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to - hold all of the source including the null terminator - - pszSrc - source string which must be null terminated - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCbCopyEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCbCopyA(char* pszDest, size_t cbDest, const char* pszSrc); -STRSAFEAPI StringCbCopyW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc); -#ifdef UNICODE -#define StringCbCopy StringCbCopyW -#else -#define StringCbCopy StringCbCopyA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCopyA(char* pszDest, size_t cbDest, const char* pszSrc) -{ - HRESULT hr; - size_t cchDest; - - // convert to count of characters - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyWorkerA(pszDest, cchDest, pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCbCopyW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc) -{ - HRESULT hr; - size_t cchDest; - - // convert to count of characters - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyWorkerW(pszDest, cchDest, pszSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCopyEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - IN LPCTSTR pszSrc OPTIONAL, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcpy' with - some additional parameters. In addition to functionality provided by - StringCchCopy, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(pszSrc) + 1) to hold all of - the source including the null terminator - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcpy - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCopyExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCopyEx StringCchCopyExW -#else -#define StringCchCopyEx StringCchCopyExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCopyExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCopyEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - IN LPCTSTR pszSrc OPTIONAL, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcbRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcpy' with - some additional parameters. In addition to functionality provided by - StringCbCopy, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to - hold all of the source including the null terminator - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcbRemaining - pcbRemaining is non-null,the function will return the - number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcpy - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCopyExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -STRSAFEAPI StringCbCopyExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbCopyEx StringCbCopyExW -#else -#define StringCbCopyEx StringCbCopyExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCopyExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbCopyExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCopyN( - OUT LPTSTR pszDest, - IN size_t cchDest, - IN LPCTSTR pszSrc, - IN size_t cchSrc - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncpy'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is meant as a replacement for strncpy, but it does behave - differently. This function will not pad the destination buffer with extra - null termination characters if cchSrc is greater than the length of pszSrc. - - This function returns a hresult, and not a pointer. It returns - S_OK if the entire string or the first cchSrc characters were copied - without truncation and the resultant destination string was null terminated, - otherwise it will return a failure code. In failure cases as much of pszSrc - will be copied to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(src) + 1) to hold all of the - source including the null terminator - - pszSrc - source string - - cchSrc - maximum number of characters to copy from source string, - not including the null terminator. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCopyNEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc); -STRSAFEAPI StringCchCopyNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc); -#ifdef UNICODE -#define StringCchCopyN StringCchCopyNW -#else -#define StringCchCopyN StringCchCopyNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc); - } - - return hr; -} - -STRSAFEAPI StringCchCopyNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCopyN( - OUT LPTSTR pszDest, - IN size_t cbDest, - IN LPCTSTR pszSrc, - IN size_t cbSrc - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncpy'. - The size of the destination buffer (in bytes) is a parameter and this - function will not write past the end of this buffer and it will ALWAYS - null terminate the destination buffer (unless it is zero length). - - This routine is meant as a replacement for strncpy, but it does behave - differently. This function will not pad the destination buffer with extra - null termination characters if cbSrc is greater than the size of pszSrc. - - This function returns a hresult, and not a pointer. It returns - S_OK if the entire string or the first cbSrc characters were - copied without truncation and the resultant destination string was null - terminated, otherwise it will return a failure code. In failure cases as - much of pszSrc will be copied to pszDest as possible, and pszDest will be - null terminated. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to - hold all of the source including the null terminator - - pszSrc - source string - - cbSrc - maximum number of bytes to copy from source string, - not including the null terminator. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCbCopyEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCbCopyNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc); -STRSAFEAPI StringCbCopyNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc); -#ifdef UNICODE -#define StringCbCopyN StringCbCopyNW -#else -#define StringCbCopyN StringCbCopyNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCopyNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc) -{ - HRESULT hr; - size_t cchDest; - size_t cchSrc; - - // convert to count of characters - cchDest = cbDest / sizeof(char); - cchSrc = cbSrc / sizeof(char); - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc); - } - - return hr; -} - -STRSAFEAPI StringCbCopyNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc) -{ - HRESULT hr; - size_t cchDest; - size_t cchSrc; - - // convert to count of characters - cchDest = cbDest / sizeof(wchar_t); - cchSrc = cbSrc / sizeof(wchar_t); - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCopyNEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - IN LPCTSTR pszSrc OPTIONAL, - IN size_t cchSrc, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncpy' with - some additional parameters. In addition to functionality provided by - StringCchCopyN, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination - string including the null terminator. The flags parameter allows - additional controls. - - This routine is meant as a replacement for strncpy, but it does behave - differently. This function will not pad the destination buffer with extra - null termination characters if cchSrc is greater than the length of pszSrc. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(pszSrc) + 1) to hold all of - the source including the null terminator - - pszSrc - source string - - cchSrc - maximum number of characters to copy from the source - string - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcpy - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCopyNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCopyNEx StringCchCopyNExW -#else -#define StringCchCopyNEx StringCchCopyNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCopyNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCopyNEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - IN LPCTSTR pszSrc OPTIONAL, - IN size_t cbSrc, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcbRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncpy' with - some additional parameters. In addition to functionality provided by - StringCbCopyN, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - - This routine is meant as a replacement for strncpy, but it does behave - differently. This function will not pad the destination buffer with extra - null termination characters if cbSrc is greater than the size of pszSrc. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to - hold all of the source including the null terminator - - pszSrc - source string - - cbSrc - maximum number of bytes to copy from source string - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcbRemaining - pcbRemaining is non-null,the function will return the - number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcpy - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCopyNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -STRSAFEAPI StringCbCopyNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbCopyNEx StringCbCopyNExW -#else -#define StringCbCopyNEx StringCbCopyNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCopyNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchSrc; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - cchSrc = cbSrc / sizeof(char); - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbCopyNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchSrc; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - cchSrc = cbSrc / sizeof(wchar_t); - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCat( - IN OUT LPTSTR pszDest, - IN size_t cchDest, - IN LPCTSTR pszSrc - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat'. - The size of the destination buffer (in characters) is a parameter and this - function will not write past the end of this buffer and it will ALWAYS - null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was concatenated without truncation and null terminated, - otherwise it will return a failure code. In failure cases as much of pszSrc - will be appended to pszDest as possible, and pszDest will be null - terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(pszDest) + _tcslen(pszSrc) + 1) - to hold all of the combine string plus the null - terminator - - pszSrc - source string which must be null terminated - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCatEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc); -STRSAFEAPI StringCchCatW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc); -#ifdef UNICODE -#define StringCchCat StringCchCatW -#else -#define StringCchCat StringCchCatA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerA(pszDest, cchDest, pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCchCatW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerW(pszDest, cchDest, pszSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCat( - IN OUT LPTSTR pszDest, - IN size_t cbDest, - IN LPCTSTR pszSrc - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat'. - The size of the destination buffer (in bytes) is a parameter and this - function will not write past the end of this buffer and it will ALWAYS - null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was concatenated without truncation and null terminated, - otherwise it will return a failure code. In failure cases as much of pszSrc - will be appended to pszDest as possible, and pszDest will be null - terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be = ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator - - pszSrc - source string which must be null terminated - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCbCatEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc); -STRSAFEAPI StringCbCatW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc); -#ifdef UNICODE -#define StringCbCat StringCbCatW -#else -#define StringCbCat StringCbCatA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerA(pszDest, cchDest, pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCbCatW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerW(pszDest, cchDest, pszSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCatEx( - IN OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - IN LPCTSTR pszSrc OPTIONAL, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat' with - some additional parameters. In addition to functionality provided by - StringCchCat, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters - length must be (_tcslen(pszDest) + _tcslen(pszSrc) + 1) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcat - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error - occurs, the destination buffer is modified to contain - a truncated version of the ideal result and is null - terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCatExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCatEx StringCchCatExW -#else -#define StringCchCatEx StringCchCatExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCatExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCatEx( - IN OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - IN LPCTSTR pszSrc OPTIONAL, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcbRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat' with - some additional parameters. In addition to functionality provided by - StringCbCat, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcbRemaining - if pcbRemaining is non-null, the function will return - the number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcat - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated - and the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error - occurs, the destination buffer is modified to contain - a truncated version of the ideal result and is null - terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -STRSAFEAPI StringCbCatExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbCatEx StringCbCatExW -#else -#define StringCbCatEx StringCbCatExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbCatExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCatN( - IN OUT LPTSTR pszDest, - IN size_t cchDest, - IN LPCTSTR pszSrc, - IN size_t cchMaxAppend - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat'. - The size of the destination buffer (in characters) is a parameter as well as - the maximum number of characters to append, excluding the null terminator. - This function will not write past the end of the destination buffer and it will - ALWAYS null terminate pszDest (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if all of pszSrc or the first cchMaxAppend characters were appended - to the destination string and it was null terminated, otherwise it will - return a failure code. In failure cases as much of pszSrc will be appended - to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters. - length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cchMaxAppend - maximum number of characters to append - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCatNEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if all of pszSrc or the first cchMaxAppend characters - were concatenated to pszDest and the resultant dest - string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error - occurs, the destination buffer is modified to contain - a truncated version of the ideal result and is null - terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend); -STRSAFEAPI StringCchCatNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend); -#ifdef UNICODE -#define StringCchCatN StringCchCatNW -#else -#define StringCchCatN StringCchCatNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCchCatNW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCatN( - IN OUT LPTSTR pszDest, - IN size_t cbDest, - IN LPCTSTR pszSrc, - IN size_t cbMaxAppend - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat'. - The size of the destination buffer (in bytes) is a parameter as well as - the maximum number of bytes to append, excluding the null terminator. - This function will not write past the end of the destination buffer and it will - ALWAYS null terminate pszDest (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if all of pszSrc or the first cbMaxAppend bytes were appended - to the destination string and it was null terminated, otherwise it will - return a failure code. In failure cases as much of pszSrc will be appended - to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cbMaxAppend - maximum number of bytes to append - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCbCatNEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if all of pszSrc or the first cbMaxAppend bytes were - concatenated to pszDest and the resultant dest string - was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error - occurs, the destination buffer is modified to contain - a truncated version of the ideal result and is null - terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend); -STRSAFEAPI StringCbCatNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend); -#ifdef UNICODE -#define StringCbCatN StringCbCatNW -#else -#define StringCbCatN StringCbCatNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(char); - - hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCbCatNW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(wchar_t); - - hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchCatNEx( - IN OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - IN LPCTSTR pszSrc OPTIONAL, - IN size_t cchMaxAppend, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat', with - some additional parameters. In addition to functionality provided by - StringCchCatN, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters. - length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cchMaxAppend - maximum number of characters to append - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if all of pszSrc or the first cchMaxAppend characters - were concatenated to pszDest and the resultant dest - string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error - occurs, the destination buffer is modified to contain - a truncated version of the ideal result and is null - terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCatNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCatNEx StringCchCatNExW -#else -#define StringCchCatNEx StringCchCatNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCatNExW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbCatNEx( - IN OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - IN LPCTSTR pszSrc OPTIONAL, - IN size_t cbMaxAppend, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat', with - some additional parameters. In addition to functionality provided by - StringCbCatN, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cbMaxAppend - maximum number of bytes to append - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcbRemaining - if pcbRemaining is non-null, the function will return the - number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if all of pszSrc or the first cbMaxAppend bytes were - concatenated to pszDest and the resultant dest string - was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error - occurs, the destination buffer is modified to contain - a truncated version of the ideal result and is null - terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -STRSAFEAPI StringCbCatNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbCatNEx StringCbCatNExW -#else -#define StringCbCatNEx StringCbCatNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(char); - - hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbCatNExW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszSrc, size_t cbMaxAppend, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(wchar_t); - - hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchVPrintf( - OUT LPTSTR pszDest, - IN size_t cchDest, - IN LPCTSTR pszFormat, - IN va_list argList - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'vsprintf'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was printed without truncation and null terminated, - otherwise it will return a failure code. In failure cases it will return - a truncated version of the ideal result. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters - length must be sufficient to hold the resulting formatted - string, including the null terminator. - - pszFormat - format string which must be null terminated - - argList - va_list from the variable arguments according to the - stdarg.h convention - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL. See StringCchVPrintfEx if you - require the handling of NULL values. - -Return Value: - - S_OK - if there was sufficient space in the dest buffer for - the resultant string and it was null terminated. - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList); -STRSAFEAPI StringCchVPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList); -#ifdef UNICODE -#define StringCchVPrintf StringCchVPrintfW -#else -#define StringCchVPrintf StringCchVPrintfA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); - } - - return hr; -} - -STRSAFEAPI StringCchVPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbVPrintf( - OUT LPTSTR pszDest, - IN size_t cbDest, - IN LPCTSTR pszFormat, - IN va_list argList - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'vsprintf'. - The size of the destination buffer (in bytes) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was printed without truncation and null terminated, - otherwise it will return a failure code. In failure cases it will return - a truncated version of the ideal result. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes - length must be sufficient to hold the resulting formatted - string, including the null terminator. - - pszFormat - format string which must be null terminated - - argList - va_list from the variable arguments according to the - stdarg.h convention - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL. See StringCbVPrintfEx if you - require the handling of NULL values. - - -Return Value: - - S_OK - if there was sufficient space in the dest buffer for - the resultant string and it was null terminated. - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList); -STRSAFEAPI StringCbVPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, va_list argList); -#ifdef UNICODE -#define StringCbVPrintf StringCbVPrintfW -#else -#define StringCbVPrintf StringCbVPrintfA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); - } - - return hr; -} - -STRSAFEAPI StringCbVPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, va_list argList) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchPrintf( - OUT LPTSTR pszDest, - IN size_t cchDest, - IN LPCTSTR pszFormat, - ... - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'sprintf'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was printed without truncation and null terminated, - otherwise it will return a failure code. In failure cases it will return - a truncated version of the ideal result. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters - length must be sufficient to hold the resulting formatted - string, including the null terminator. - - pszFormat - format string which must be null terminated - - ... - additional parameters to be formatted according to - the format string - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL. See StringCchPrintfEx if you - require the handling of NULL values. - -Return Value: - - S_OK - if there was sufficient space in the dest buffer for - the resultant string and it was null terminated. - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...); -STRSAFEAPI StringCchPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, ...); -#ifdef UNICODE -#define StringCchPrintf StringCchPrintfW -#else -#define StringCchPrintf StringCchPrintfA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - va_list argList; - - va_start(argList, pszFormat); - - hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); - - va_end(argList); - } - - return hr; -} - -STRSAFEAPI StringCchPrintfW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, ...) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - va_list argList; - - va_start(argList, pszFormat); - - hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); - - va_end(argList); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbPrintf( - OUT LPTSTR pszDest, - IN size_t cbDest, - IN LPCTSTR pszFormat, - ... - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'sprintf'. - The size of the destination buffer (in bytes) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns - S_OK if the string was printed without truncation and null terminated, - otherwise it will return a failure code. In failure cases it will return - a truncated version of the ideal result. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes - length must be sufficient to hold the resulting formatted - string, including the null terminator. - - pszFormat - format string which must be null terminated - - ... - additional parameters to be formatted according to - the format string - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL. See StringCbPrintfEx if you - require the handling of NULL values. - - -Return Value: - - S_OK - if there was sufficient space in the dest buffer for - the resultant string and it was null terminated. - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...); -STRSAFEAPI StringCbPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, ...); -#ifdef UNICODE -#define StringCbPrintf StringCbPrintfW -#else -#define StringCbPrintf StringCbPrintfA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - va_list argList; - - va_start(argList, pszFormat); - - hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList); - - va_end(argList); - } - - return hr; -} - -STRSAFEAPI StringCbPrintfW(wchar_t* pszDest, size_t cbDest, const wchar_t* pszFormat, ...) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - va_list argList; - - va_start(argList, pszFormat); - - hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList); - - va_end(argList); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchPrintfEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags, - IN LPCTSTR pszFormat OPTIONAL, - ... - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'sprintf' with - some additional parameters. In addition to functionality provided by - StringCchPrintf, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be sufficient to contain the resulting - formatted string plus the null terminator. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function printed any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return - the number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - - pszFormat - format string which must be null terminated - - ... - additional parameters to be formatted according to - the format string - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS - flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and - pszFormat may be NULL. An error may still be returned even though NULLS - are ignored due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...); -STRSAFEAPI StringCchPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...); -#ifdef UNICODE -#define StringCchPrintfEx StringCchPrintfExW -#else -#define StringCchPrintfEx StringCchPrintfExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - va_list argList; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - va_start(argList, pszFormat); - - hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); - - va_end(argList); - } - - return hr; -} - -STRSAFEAPI StringCchPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - va_list argList; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - va_start(argList, pszFormat); - - hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); - - va_end(argList); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbPrintfEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcbRemaining OPTIONAL, - IN DWORD dwFlags, - IN LPCTSTR pszFormat OPTIONAL, - ... - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'sprintf' with - some additional parameters. In addition to functionality provided by - StringCbPrintf, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - length must be sufficient to contain the resulting - formatted string plus the null terminator. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function printed any data, the result will point to the - null termination character - - pcbRemaining - if pcbRemaining is non-null, the function will return - the number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - - pszFormat - format string which must be null terminated - - ... - additional parameters to be formatted according to - the format string - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS - flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and - pszFormat may be NULL. An error may still be returned even though NULLS - are ignored due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...); -STRSAFEAPI StringCbPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...); -#ifdef UNICODE -#define StringCbPrintfEx StringCbPrintfExW -#else -#define StringCbPrintfEx StringCbPrintfExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - va_list argList; - - va_start(argList, pszFormat); - - hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); - - va_end(argList); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, ...) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - va_list argList; - - va_start(argList, pszFormat); - - hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); - - va_end(argList); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchVPrintfEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags, - IN LPCTSTR pszFormat OPTIONAL, - IN va_list argList - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'vsprintf' with - some additional parameters. In addition to functionality provided by - StringCchVPrintf, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be sufficient to contain the resulting - formatted string plus the null terminator. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function printed any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return - the number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - - pszFormat - format string which must be null terminated - - argList - va_list from the variable arguments according to the - stdarg.h convention - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS - flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and - pszFormat may be NULL. An error may still be returned even though NULLS - are ignored due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList); -STRSAFEAPI StringCchVPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList); -#ifdef UNICODE -#define StringCchVPrintfEx StringCchVPrintfExW -#else -#define StringCchVPrintfEx StringCchVPrintfExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); - } - - return hr; -} - -STRSAFEAPI StringCchVPrintfExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbVPrintfEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcbRemaining OPTIONAL, - IN DWORD dwFlags, - IN LPCTSTR pszFormat OPTIONAL, - IN va_list argList - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'vsprintf' with - some additional parameters. In addition to functionality provided by - StringCbVPrintf, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - length must be sufficient to contain the resulting - formatted string plus the null terminator. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return - a pointer to the end of the destination string. If the - function printed any data, the result will point to the - null termination character - - pcbRemaining - if pcbRemaining is non-null, the function will return - the number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - - pszFormat - format string which must be null terminated - - argList - va_list from the variable arguments according to the - stdarg.h convention - -Notes: - Behavior is undefined if destination, format strings or any arguments - strings overlap. - - pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS - flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and - pszFormat may be NULL. An error may still be returned even though NULLS - are ignored due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and - the resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the print - operation failed due to insufficient space. When this - error occurs, the destination buffer is modified to - contain a truncated version of the ideal result and is - null terminated. This is useful for situations where - truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList); -STRSAFEAPI StringCbVPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList); -#ifdef UNICODE -#define StringCbVPrintfEx StringCbVPrintfExW -#else -#define StringCbVPrintfEx StringCbVPrintfExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbVPrintfExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchGets( - OUT LPTSTR pszDest, - IN size_t cchDest - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is not a replacement for fgets. That function does not replace - newline characters with a null terminator. - - This function returns a hresult, and not a pointer. It returns - S_OK if any characters were read from stdin and copied to pszDest and - pszDest was null terminated, otherwise it will return a failure code. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - -Notes: - pszDest should not be NULL. See StringCchGetsEx if you require the handling - of NULL values. - - cchDest must be > 1 for this function to succeed. - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant - dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_END_OF_FILE / - HRESULT_CODE(hr) == ERROR_HANDLE_EOF - - this return value indicates an error or end-of-file - condition, use feof or ferror to determine which one has - occured. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was - insufficient space in the destination buffer to copy any - data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#ifndef STRSAFE_LIB_IMPL -STRSAFE_INLINE_API StringCchGetsA(char* pszDest, size_t cchDest); -STRSAFE_INLINE_API StringCchGetsW(wchar_t* pszDest, size_t cchDest); -#ifdef UNICODE -#define StringCchGets StringCchGetsW -#else -#define StringCchGets StringCchGetsA -#endif // !UNICODE - -STRSAFE_INLINE_API StringCchGetsA(char* pszDest, size_t cchDest) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, NULL, NULL, 0); - } - - return hr; -} - -STRSAFE_INLINE_API StringCchGetsW(wchar_t* pszDest, size_t cchDest) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, NULL, NULL, 0); - } - - return hr; -} -#endif // !STRSAFE_NO_CCH_FUNCTIONS -#endif // !STRSAFE_LIB_IMPL - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbGets( - OUT LPTSTR pszDest, - IN size_t cbDest - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets'. - The size of the destination buffer (in bytes) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is not a replacement for fgets. That function does not replace - newline characters with a null terminator. - - This function returns a hresult, and not a pointer. It returns - S_OK if any characters were read from stdin and copied to pszDest - and pszDest was null terminated, otherwise it will return a failure code. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - -Notes: - pszDest should not be NULL. See StringCbGetsEx if you require the handling - of NULL values. - - cbDest must be > sizeof(TCHAR) for this function to succeed. - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant - dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_END_OF_FILE / - HRESULT_CODE(hr) == ERROR_HANDLE_EOF - - this return value indicates an error or end-of-file - condition, use feof or ferror to determine which one has - occured. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was - insufficient space in the destination buffer to copy any - data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#ifndef STRSAFE_LIB_IMPL -STRSAFE_INLINE_API StringCbGetsA(char* pszDest, size_t cbDest); -STRSAFE_INLINE_API StringCbGetsW(wchar_t* pszDest, size_t cbDest); -#ifdef UNICODE -#define StringCbGets StringCbGetsW -#else -#define StringCbGets StringCbGetsA -#endif // !UNICODE - -STRSAFE_INLINE_API StringCbGetsA(char* pszDest, size_t cbDest) -{ - HRESULT hr; - size_t cchDest; - - // convert to count of characters - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, NULL, NULL, 0); - } - - return hr; -} - -STRSAFE_INLINE_API StringCbGetsW(wchar_t* pszDest, size_t cbDest) -{ - HRESULT hr; - size_t cchDest; - - // convert to count of characters - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, NULL, NULL, 0); - } - - return hr; -} -#endif // !STRSAFE_NO_CB_FUNCTIONS -#endif // !STRSAFE_LIB_IMPL - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchGetsEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cchDest, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcchRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets' with - some additional parameters. In addition to functionality provided by - StringCchGets, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. - -Notes: - pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified. - If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be - returned even though NULLS are ignored - - cchDest must be > 1 for this function to succeed. - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant - dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_END_OF_FILE / - HRESULT_CODE(hr) == ERROR_HANDLE_EOF - - this return value indicates an error or end-of-file - condition, use feof or ferror to determine which one has - occured. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was - insufficient space in the destination buffer to copy any - data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#ifndef STRSAFE_LIB_IMPL -STRSAFE_INLINE_API StringCchGetsExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFE_INLINE_API StringCchGetsExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchGetsEx StringCchGetsExW -#else -#define StringCchGetsEx StringCchGetsExA -#endif // !UNICODE - -STRSAFE_INLINE_API StringCchGetsExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFE_INLINE_API StringCchGetsExW(wchar_t* pszDest, size_t cchDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(wchar_t) since cchDest < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - cbDest = cchDest * sizeof(wchar_t); - - hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // !STRSAFE_NO_CCH_FUNCTIONS -#endif // !STRSAFE_LIB_IMPL - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbGetsEx( - OUT LPTSTR pszDest OPTIONAL, - IN size_t cbDest, - OUT LPTSTR* ppszDestEnd OPTIONAL, - OUT size_t* pcbRemaining OPTIONAL, - IN DWORD dwFlags - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets' with - some additional parameters. In addition to functionality provided by - StringCbGets, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcbRemaining - if pbRemaining is non-null, the function will return the - number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. - -Notes: - pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified. - If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be - returned even though NULLS are ignored - - cbDest must be > sizeof(TCHAR) for this function to succeed - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant - dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - STRSAFE_E_END_OF_FILE / - HRESULT_CODE(hr) == ERROR_HANDLE_EOF - - this return value indicates an error or end-of-file - condition, use feof or ferror to determine which one has - occured. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was - insufficient space in the destination buffer to copy any - data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#ifndef STRSAFE_LIB_IMPL -STRSAFE_INLINE_API StringCbGetsExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pbRemaining, unsigned long dwFlags); -STRSAFE_INLINE_API StringCbGetsExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbGetsEx StringCbGetsExW -#else -#define StringCbGetsEx StringCbGetsExA -#endif // !UNICODE - -STRSAFE_INLINE_API StringCbGetsExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringGetsExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || - (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || - (hr == STRSAFE_E_END_OF_FILE)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFE_INLINE_API StringCbGetsExW(wchar_t* pszDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(wchar_t); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringGetsExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || - (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || - (hr == STRSAFE_E_END_OF_FILE)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); - } - } - - return hr; -} -#endif // !STRSAFE_NO_CB_FUNCTIONS -#endif // !STRSAFE_LIB_IMPL - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI -StringCchLength( - IN LPCTSTR psz, - IN size_t cchMax, - OUT size_t* pcch OPTIONAL - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strlen'. - It is used to make sure a string is not larger than a given length, and - it optionally returns the current length in characters not including - the null terminator. - - This function returns a hresult, and not a pointer. It returns - S_OK if the string is non-null and the length including the null - terminator is less than or equal to cchMax characters. - -Arguments: - - psz - string to check the length of - - cchMax - maximum number of characters including the null terminator - that psz is allowed to contain - - pcch - if the function succeeds and pcch is non-null, the current length - in characters of psz excluding the null terminator will be returned. - This out parameter is equivalent to the return value of strlen(psz) - -Notes: - psz can be null but the function will fail - - cchMax should be greater than zero or the function will fail - -Return Value: - - S_OK - psz is non-null and the length including the null - terminator is less than or equal to cchMax characters - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch); -STRSAFEAPI StringCchLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch); -#ifdef UNICODE -#define StringCchLength StringCchLengthW -#else -#define StringCchLength StringCchLengthA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr; - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerA(psz, cchMax, pcch); - } - - return hr; -} - -STRSAFEAPI StringCchLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr; - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerW(psz, cchMax, pcch); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI -StringCbLength( - IN LPCTSTR psz, - IN size_t cbMax, - OUT size_t* pcb OPTIONAL - ); - -Routine Description: - - This routine is a safer version of the C built-in function 'strlen'. - It is used to make sure a string is not larger than a given length, and - it optionally returns the current length in bytes not including - the null terminator. - - This function returns a hresult, and not a pointer. It returns - S_OK if the string is non-null and the length including the null - terminator is less than or equal to cbMax bytes. - -Arguments: - - psz - string to check the length of - - cbMax - maximum number of bytes including the null terminator - that psz is allowed to contain - - pcb - if the function succeeds and pcb is non-null, the current length - in bytes of psz excluding the null terminator will be returned. - This out parameter is equivalent to the return value of strlen(psz) * sizeof(TCHAR) - -Notes: - psz can be null but the function will fail - - cbMax should be greater than or equal to sizeof(TCHAR) or the function will fail - -Return Value: - - S_OK - psz is non-null and the length including the null - terminator is less than or equal to cbMax bytes - - failure - you can use the macro HRESULT_CODE() to get a win32 - error code for all hresult failure cases - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCbLengthA(const char* psz, size_t cchMax, size_t* pcch); -STRSAFEAPI StringCbLengthW(const wchar_t* psz, size_t cchMax, size_t* pcch); -#ifdef UNICODE -#define StringCbLength StringCbLengthW -#else -#define StringCbLength StringCbLengthA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbLengthA(const char* psz, size_t cbMax, size_t* pcb) -{ - HRESULT hr; - size_t cchMax; - size_t cch = 0; - - cchMax = cbMax / sizeof(char); - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerA(psz, cchMax, &cch); - } - - if (SUCCEEDED(hr) && pcb) - { - // safe to multiply cch * sizeof(char) since cch < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcb = cch * sizeof(char); - } - - return hr; -} - -STRSAFEAPI StringCbLengthW(const wchar_t* psz, size_t cbMax, size_t* pcb) -{ - HRESULT hr; - size_t cchMax; - size_t cch = 0; - - cchMax = cbMax / sizeof(wchar_t); - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerW(psz, cchMax, &cch); - } - - if (SUCCEEDED(hr) && pcb) - { - // safe to multiply cch * sizeof(wchar_t) since cch < STRSAFE_MAX_CCH and sizeof(wchar_t) is 2 - *pcb = cch * sizeof(wchar_t); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -// these are the worker functions that actually do the work -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && (*pszSrc != '\0')) - { - *pszDest++ = *pszSrc++; - cchDest--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= '\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && (*pszSrc != L'\0')) - { - *pszDest++ = *pszSrc++; - cchDest--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= L'\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && (*pszSrc != '\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = '\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCopyExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - wchar_t* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || - // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = L""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && (*pszSrc != L'\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = L'\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && cchSrc && (*pszSrc != '\0')) - { - *pszDest++= *pszSrc++; - cchDest--; - cchSrc--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= '\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && cchSrc && (*pszSrc != L'\0')) - { - *pszDest++= *pszSrc++; - cchDest--; - cchSrc--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= L'\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && cchSrc && (*pszSrc != '\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - cchSrc--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = '\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCopyNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - wchar_t* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || - // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = L""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && cchSrc && (*pszSrc != L'\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - cchSrc--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = L'\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyWorkerA(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCatWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyWorkerW(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchDestCurrent; - - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyExWorkerA(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)), - pszSrc, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerA() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else - if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - wchar_t* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || - // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchDestCurrent; - - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = L""; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyExWorkerW(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)), - pszSrc, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerW() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyNWorkerA(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc, - cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCatNWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyNWorkerW(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc, - cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - size_t cchDestCurrent = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyNExWorkerA(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)), - pszSrc, - cchMaxAppend, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerA() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatNExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, const wchar_t* pszSrc, size_t cchMaxAppend, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - wchar_t* pszDestEnd = pszDest; - size_t cchRemaining = 0; - size_t cchDestCurrent = 0; - - - // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || - // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = L""; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyNExWorkerW(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)), - pszSrc, - cchMaxAppend, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerW() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - int iRet; - size_t cchMax; - - // leave the last space for the null terminator - cchMax = cchDest - 1; - - iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList); - // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); - - if ((iRet < 0) || (((size_t)iRet) > cchMax)) - { - // need to null terminate the string - pszDest += cchMax; - *pszDest = '\0'; - - // we have truncated pszDest - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else if (((size_t)iRet) == cchMax) - { - // need to null terminate the string - pszDest += cchMax; - *pszDest = '\0'; - } - } - - return hr; -} - -STRSAFEAPI StringVPrintfWorkerW(wchar_t* pszDest, size_t cchDest, const wchar_t* pszFormat, va_list argList) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - int iRet; - size_t cchMax; - - // leave the last space for the null terminator - cchMax = cchDest - 1; - - iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList); - // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); - - if ((iRet < 0) || (((size_t)iRet) > cchMax)) - { - // need to null terminate the string - pszDest += cchMax; - *pszDest = L'\0'; - - // we have truncated pszDest - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else if (((size_t)iRet) == cchMax) - { - // need to null terminate the string - pszDest += cchMax; - *pszDest = L'\0'; - } - } - - return hr; -} - -STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszFormat == NULL) - { - pszFormat = ""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually a non-empty format string - if (*pszFormat != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - int iRet; - size_t cchMax; - - // leave the last space for the null terminator - cchMax = cchDest - 1; - - iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList); - // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); - - if ((iRet < 0) || (((size_t)iRet) > cchMax)) - { - // we have truncated pszDest - pszDestEnd = pszDest + cchMax; - cchRemaining = 1; - - // need to null terminate the string - *pszDestEnd = '\0'; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else if (((size_t)iRet) == cchMax) - { - // string fit perfectly - pszDestEnd = pszDest + cchMax; - cchRemaining = 1; - - // need to null terminate the string - *pszDestEnd = '\0'; - } - else if (((size_t)iRet) < cchMax) - { - // there is extra room - pszDestEnd = pszDest + iRet; - cchRemaining = cchDest - iRet; - - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); - } - } - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringVPrintfExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const wchar_t* pszFormat, va_list argList) -{ - HRESULT hr = S_OK; - wchar_t* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(wchar_t)) || - // cbDest == (cchDest * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszFormat == NULL) - { - pszFormat = L""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually a non-empty format string - if (*pszFormat != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - int iRet; - size_t cchMax; - - // leave the last space for the null terminator - cchMax = cchDest - 1; - - iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList); - // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); - - if ((iRet < 0) || (((size_t)iRet) > cchMax)) - { - // we have truncated pszDest - pszDestEnd = pszDest + cchMax; - cchRemaining = 1; - - // need to null terminate the string - *pszDestEnd = L'\0'; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else if (((size_t)iRet) == cchMax) - { - // string fit perfectly - pszDestEnd = pszDest + cchMax; - cchRemaining = 1; - - // need to null terminate the string - *pszDestEnd = L'\0'; - } - else if (((size_t)iRet) < cchMax) - { - // there is extra room - pszDestEnd = pszDest + iRet; - cchRemaining = cchDest - iRet; - - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - } - } - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr = S_OK; - size_t cchMaxPrev = cchMax; - - while (cchMax && (*psz != '\0')) - { - psz++; - cchMax--; - } - - if (cchMax == 0) - { - // the string is longer than cchMax - hr = STRSAFE_E_INVALID_PARAMETER; - } - - if (SUCCEEDED(hr) && pcch) - { - *pcch = cchMaxPrev - cchMax; - } - - return hr; -} - -STRSAFEAPI StringLengthWorkerW(const wchar_t* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr = S_OK; - size_t cchMaxPrev = cchMax; - - while (cchMax && (*psz != L'\0')) - { - psz++; - cchMax--; - } - - if (cchMax == 0) - { - // the string is longer than cchMax - hr = STRSAFE_E_INVALID_PARAMETER; - } - - if (SUCCEEDED(hr) && pcch) - { - *pcch = cchMaxPrev - cchMax; - } - - return hr; -} -#endif // STRSAFE_INLINE - -#ifndef STRSAFE_LIB_IMPL -STRSAFE_INLINE_API StringGetsExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest <= 1) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - if (cchDest == 1) - { - *pszDestEnd = '\0'; - } - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else - { - char ch; - - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while ((cchRemaining > 1) && (ch = (char)getc(stdin)) != '\n') - { - if (ch == EOF) - { - if (pszDestEnd == pszDest) - { - // we failed to read anything from stdin - hr = STRSAFE_E_END_OF_FILE; - } - break; - } - - *pszDestEnd = ch; - - pszDestEnd++; - cchRemaining--; - } - - if (cchRemaining > 0) - { - // there is extra room - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); - } - } - - *pszDestEnd = '\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || - (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || - (hr == STRSAFE_E_END_OF_FILE)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFE_INLINE_API StringGetsExWorkerW(wchar_t* pszDest, size_t cchDest, size_t cbDest, wchar_t** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - wchar_t* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest <= 1) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - if (cchDest == 1) - { - *pszDestEnd = L'\0'; - } - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - else - { - wchar_t ch; - - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while ((cchRemaining > 1) && (ch = (wchar_t)getwc(stdin)) != L'\n') - { - if (ch == EOF) - { - if (pszDestEnd == pszDest) - { - // we failed to read anything from stdin - hr = STRSAFE_E_END_OF_FILE; - } - break; - } - - *pszDestEnd = ch; - - pszDestEnd++; - cchRemaining--; - } - - if (cchRemaining > 0) - { - // there is extra room - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t))); - } - } - - *pszDestEnd = L'\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || - (hr == STRSAFE_E_INSUFFICIENT_BUFFER) || - (hr == STRSAFE_E_END_OF_FILE)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} -#endif // !STRSAFE_LIB_IMPL - - -// Do not call these functions, they are worker functions for internal use within this file -#ifdef DEPRECATE_SUPPORTED -#pragma deprecated(StringCopyWorkerA) -#pragma deprecated(StringCopyWorkerW) -#pragma deprecated(StringCopyExWorkerA) -#pragma deprecated(StringCopyExWorkerW) -#pragma deprecated(StringCatWorkerA) -#pragma deprecated(StringCatWorkerW) -#pragma deprecated(StringCatExWorkerA) -#pragma deprecated(StringCatExWorkerW) -#pragma deprecated(StringCatNWorkerA) -#pragma deprecated(StringCatNWorkerW) -#pragma deprecated(StringCatNExWorkerA) -#pragma deprecated(StringCatNExWorkerW) -#pragma deprecated(StringVPrintfWorkerA) -#pragma deprecated(StringVPrintfWorkerW) -#pragma deprecated(StringVPrintfExWorkerA) -#pragma deprecated(StringVPrintfExWorkerW) -#pragma deprecated(StringLengthWorkerA) -#pragma deprecated(StringLengthWorkerW) -#else -#define StringCopyWorkerA StringCopyWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; -#define StringCopyWorkerW StringCopyWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; -#define StringCopyExWorkerA StringCopyExWorkerA_instead_use_StringCchCopyA_or_StringCchCopyExA; -#define StringCopyExWorkerW StringCopyExWorkerW_instead_use_StringCchCopyW_or_StringCchCopyExW; -#define StringCatWorkerA StringCatWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; -#define StringCatWorkerW StringCatWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; -#define StringCatExWorkerA StringCatExWorkerA_instead_use_StringCchCatA_or_StringCchCatExA; -#define StringCatExWorkerW StringCatExWorkerW_instead_use_StringCchCatW_or_StringCchCatExW; -#define StringCatNWorkerA StringCatNWorkerA_instead_use_StringCchCatNA_or_StrincCbCatNA; -#define StringCatNWorkerW StringCatNWorkerW_instead_use_StringCchCatNW_or_StringCbCatNW; -#define StringCatNExWorkerA StringCatNExWorkerA_instead_use_StringCchCatNExA_or_StringCbCatNExA; -#define StringCatNExWorkerW StringCatNExWorkerW_instead_use_StringCchCatNExW_or_StringCbCatNExW; -#define StringVPrintfWorkerA StringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; -#define StringVPrintfWorkerW StringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; -#define StringVPrintfExWorkerA StringVPrintfExWorkerA_instead_use_StringCchVPrintfA_or_StringCchVPrintfExA; -#define StringVPrintfExWorkerW StringVPrintfExWorkerW_instead_use_StringCchVPrintfW_or_StringCchVPrintfExW; -#define StringLengthWorkerA StringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA; -#define StringLengthWorkerW StringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW; -#endif // !DEPRECATE_SUPPORTED - - -#ifndef STRSAFE_NO_DEPRECATE -// Deprecate all of the unsafe functions to generate compiletime errors. If you do not want -// this then you can #define STRSAFE_NO_DEPRECATE before including this file. -#ifdef DEPRECATE_SUPPORTED - -// First all the names that are a/w variants (or shouldn't be #defined by now anyway). -#pragma deprecated(lstrcpyA) -#pragma deprecated(lstrcpyW) -#pragma deprecated(lstrcatA) -#pragma deprecated(lstrcatW) -#pragma deprecated(wsprintfA) -#pragma deprecated(wsprintfW) - -#pragma deprecated(StrCpyW) -#pragma deprecated(StrCatW) -#pragma deprecated(StrNCatA) -#pragma deprecated(StrNCatW) -#pragma deprecated(StrCatNA) -#pragma deprecated(StrCatNW) -#pragma deprecated(wvsprintfA) -#pragma deprecated(wvsprintfW) - -#pragma deprecated(strcpy) -#pragma deprecated(wcscpy) -#pragma deprecated(strcat) -#pragma deprecated(wcscat) -#pragma deprecated(sprintf) -#pragma deprecated(swprintf) -#pragma deprecated(vsprintf) -#pragma deprecated(vswprintf) -#pragma deprecated(_snprintf) -#pragma deprecated(_snwprintf) -#pragma deprecated(_vsnprintf) -#pragma deprecated(_vsnwprintf) -#pragma deprecated(gets) -#pragma deprecated(_getws) - -// Then all the windows.h names - we need to undef and redef based on UNICODE setting -#undef lstrcpy -#undef lstrcat -#undef wsprintf -#undef wvsprintf -#pragma deprecated(lstrcpy) -#pragma deprecated(lstrcat) -#pragma deprecated(wsprintf) -#pragma deprecated(wvsprintf) -#ifdef UNICODE -#define lstrcpy lstrcpyW -#define lstrcat lstrcatW -#define wsprintf wsprintfW -#define wvsprintf wvsprintfW -#else -#define lstrcpy lstrcpyA -#define lstrcat lstrcatA -#define wsprintf wsprintfA -#define wvsprintf wvsprintfA -#endif - -// Then the shlwapi names - they key off UNICODE also. -#undef StrCpyA -#undef StrCpy -#undef StrCatA -#undef StrCat -#undef StrNCat -#undef StrCatN -#pragma deprecated(StrCpyA) -#pragma deprecated(StrCatA) -#pragma deprecated(StrCatN) -#pragma deprecated(StrCpy) -#pragma deprecated(StrCat) -#pragma deprecated(StrNCat) -#define StrCpyA lstrcpyA -#define StrCatA lstrcatA -#define StrCatN StrNCat -#ifdef UNICODE -#define StrCpy StrCpyW -#define StrCat StrCatW -#define StrNCat StrNCatW -#else -#define StrCpy lstrcpyA -#define StrCat lstrcatA -#define StrNCat StrNCatA -#endif - -// Then all the CRT names - we need to undef/redef based on _UNICODE value. -#undef _tcscpy -#undef _ftcscpy -#undef _tcscat -#undef _ftcscat -#undef _stprintf -#undef _sntprintf -#undef _vstprintf -#undef _vsntprintf -#undef _getts -#pragma deprecated(_tcscpy) -#pragma deprecated(_ftcscpy) -#pragma deprecated(_tcscat) -#pragma deprecated(_ftcscat) -#pragma deprecated(_stprintf) -#pragma deprecated(_sntprintf) -#pragma deprecated(_vstprintf) -#pragma deprecated(_vsntprintf) -#pragma deprecated(_getts) -#ifdef _UNICODE -#define _tcscpy wcscpy -#define _ftcscpy wcscpy -#define _tcscat wcscat -#define _ftcscat wcscat -#define _stprintf swprintf -#define _sntprintf _snwprintf -#define _vstprintf vswprintf -#define _vsntprintf _vsnwprintf -#define _getts _getws -#else -#define _tcscpy strcpy -#define _ftcscpy strcpy -#define _tcscat strcat -#define _ftcscat strcat -#define _stprintf sprintf -#define _sntprintf _snprintf -#define _vstprintf vsprintf -#define _vsntprintf _vsnprintf -#define _getts gets -#endif - -#else // DEPRECATE_SUPPORTED - -#undef strcpy -#define strcpy strcpy_instead_use_StringCbCopyA_or_StringCchCopyA; - -#undef wcscpy -#define wcscpy wcscpy_instead_use_StringCbCopyW_or_StringCchCopyW; - -#undef strcat -#define strcat strcat_instead_use_StringCbCatA_or_StringCchCatA; - -#undef wcscat -#define wcscat wcscat_instead_use_StringCbCatW_or_StringCchCatW; - -#undef sprintf -#define sprintf sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; - -#undef swprintf -#define swprintf swprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; - -#undef vsprintf -#define vsprintf vsprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; - -#undef vswprintf -#define vswprintf vswprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; - -#undef _snprintf -#define _snprintf _snprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA; - -#undef _snwprintf -#define _snwprintf _snwprintf_instead_use_StringCbPrintfW_or_StringCchPrintfW; - -#undef _vsnprintf -#define _vsnprintf _vsnprintf_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; - -#undef _vsnwprintf -#define _vsnwprintf _vsnwprintf_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; - -#undef strcpyA -#define strcpyA strcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; - -#undef strcpyW -#define strcpyW strcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; - -#undef lstrcpy -#define lstrcpy lstrcpy_instead_use_StringCbCopy_or_StringCchCopy; - -#undef lstrcpyA -#define lstrcpyA lstrcpyA_instead_use_StringCbCopyA_or_StringCchCopyA; - -#undef lstrcpyW -#define lstrcpyW lstrcpyW_instead_use_StringCbCopyW_or_StringCchCopyW; - -#undef StrCpy -#define StrCpy StrCpy_instead_use_StringCbCopy_or_StringCchCopy; - -#undef StrCpyA -#define StrCpyA StrCpyA_instead_use_StringCbCopyA_or_StringCchCopyA; - -#undef StrCpyW -#define StrCpyW StrCpyW_instead_use_StringCbCopyW_or_StringCchCopyW; - -#undef _tcscpy -#define _tcscpy _tcscpy_instead_use_StringCbCopy_or_StringCchCopy; - -#undef _ftcscpy -#define _ftcscpy _ftcscpy_instead_use_StringCbCopy_or_StringCchCopy; - -#undef lstrcat -#define lstrcat lstrcat_instead_use_StringCbCat_or_StringCchCat; - -#undef lstrcatA -#define lstrcatA lstrcatA_instead_use_StringCbCatA_or_StringCchCatA; - -#undef lstrcatW -#define lstrcatW lstrcatW_instead_use_StringCbCatW_or_StringCchCatW; - -#undef StrCat -#define StrCat StrCat_instead_use_StringCbCat_or_StringCchCat; - -#undef StrCatA -#define StrCatA StrCatA_instead_use_StringCbCatA_or_StringCchCatA; - -#undef StrCatW -#define StrCatW StrCatW_instead_use_StringCbCatW_or_StringCchCatW; - -#undef StrNCat -#define StrNCat StrNCat_instead_use_StringCbCatN_or_StringCchCatN; - -#undef StrNCatA -#define StrNCatA StrNCatA_instead_use_StringCbCatNA_or_StringCchCatNA; - -#undef StrNCatW -#define StrNCatW StrNCatW_instead_use_StringCbCatNW_or_StringCchCatNW; - -#undef StrCatN -#define StrCatN StrCatN_instead_use_StringCbCatN_or_StringCchCatN; - -#undef StrCatNA -#define StrCatNA StrCatNA_instead_use_StringCbCatNA_or_StringCchCatNA; - -#undef StrCatNW -#define StrCatNW StrCatNW_instead_use_StringCbCatNW_or_StringCchCatNW; - -#undef _tcscat -#define _tcscat _tcscat_instead_use_StringCbCat_or_StringCchCat; - -#undef _ftcscat -#define _ftcscat _ftcscat_instead_use_StringCbCat_or_StringCchCat; - -#undef wsprintf -#define wsprintf wsprintf_instead_use_StringCbPrintf_or_StringCchPrintf; - -#undef wsprintfA -#define wsprintfA wsprintfA_instead_use_StringCbPrintfA_or_StringCchPrintfA; - -#undef wsprintfW -#define wsprintfW wsprintfW_instead_use_StringCbPrintfW_or_StringCchPrintfW; - -#undef wvsprintf -#define wvsprintf wvsprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; - -#undef wvsprintfA -#define wvsprintfA wvsprintfA_instead_use_StringCbVPrintfA_or_StringCchVPrintfA; - -#undef wvsprintfW -#define wvsprintfW wvsprintfW_instead_use_StringCbVPrintfW_or_StringCchVPrintfW; - -#undef _vstprintf -#define _vstprintf _vstprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; - -#undef _vsntprintf -#define _vsntprintf _vsntprintf_instead_use_StringCbVPrintf_or_StringCchVPrintf; - -#undef _stprintf -#define _stprintf _stprintf_instead_use_StringCbPrintf_or_StringCchPrintf; - -#undef _sntprintf -#define _sntprintf _sntprintf_instead_use_StringCbPrintf_or_StringCchPrintf; - -#undef _getts -#define _getts _getts_instead_use_StringCbGets_or_StringCchGets; - -#undef gets -#define gets _gets_instead_use_StringCbGetsA_or_StringCchGetsA; - -#undef _getws -#define _getws _getws_instead_use_StringCbGetsW_or_StringCchGetsW; - -#endif // !DEPRECATE_SUPPORTED -#endif // !STRSAFE_NO_DEPRECATE - -#ifdef _NTSTRSAFE_H_INCLUDED_ -#pragma warning(pop) -#endif // _NTSTRSAFE_H_INCLUDED_ - -#endif // _STRSAFE_H_INCLUDED_ |