master
   1/**
   2 * This file has no copyright assigned and is placed in the Public Domain.
   3 * This file is part of the mingw-w64 runtime package.
   4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
   5 */
   6#ifndef _NTSTRSAFE_H_INCLUDED_
   7#define _NTSTRSAFE_H_INCLUDED_
   8
   9#include <_mingw_unicode.h>
  10#include <stdio.h>
  11#include <string.h>
  12#include <stdarg.h>
  13#include <specstrings.h>
  14
  15#if defined(__CRT__NO_INLINE) && !defined(__CRT_STRSAFE_IMPL)
  16#define __STRSAFE__NO_INLINE
  17#endif
  18
  19#ifndef _SIZE_T_DEFINED
  20#define _SIZE_T_DEFINED
  21#undef size_t
  22#ifdef _WIN64
  23__MINGW_EXTENSION typedef unsigned __int64 size_t;
  24#else
  25typedef unsigned int size_t;
  26#endif
  27#endif
  28
  29#ifndef _WCHAR_T_DEFINED
  30#define _WCHAR_T_DEFINED
  31typedef unsigned short wchar_t;
  32#endif
  33
  34#ifndef _NTSTATUS_DEFINED
  35#define _NTSTATUS_DEFINED
  36typedef __LONG32 NTSTATUS;
  37#endif
  38
  39#ifndef C_ASSERT
  40#ifdef _MSC_VER
  41# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
  42#else
  43# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1])
  44#endif
  45#endif /* C_ASSERT */
  46
  47/* extern removed for C mode to avoid double extern qualifier from __CRT_INLINE */
  48#ifdef __cplusplus
  49#define _STRSAFE_EXTERN_C extern "C"
  50#else
  51#define _STRSAFE_EXTERN_C extern
  52#endif
  53
  54#ifndef WINAPI
  55#if defined(_ARM_)
  56#define WINAPI
  57#else
  58#define WINAPI __stdcall
  59#endif
  60#endif
  61
  62#if !defined(__CRT__NO_INLINE) && !defined(__CRT_STRSAFE_IMPL)
  63#define NTSTRSAFEDDI _STRSAFE_EXTERN_C __inline NTSTATUS WINAPI
  64/* Variadic functions can't be __stdcall.  */
  65#define NTSTRSAFEDDIV _STRSAFE_EXTERN_C __inline NTSTATUS
  66#else
  67#define NTSTRSAFEDDI _STRSAFE_EXTERN_C NTSTATUS WINAPI
  68/* Variadic functions can't be __stdcall.  */
  69#define NTSTRSAFEDDIV _STRSAFE_EXTERN_C NTSTATUS
  70#endif
  71
  72#define NTSTRSAFE_MAX_CCH 2147483647
  73
  74#define STRSAFE_IGNORE_NULLS 0x00000100
  75#define STRSAFE_FILL_BEHIND_NULL 0x00000200
  76#define STRSAFE_FILL_ON_FAILURE 0x00000400
  77#define STRSAFE_NULL_ON_FAILURE 0x00000800
  78#define STRSAFE_NO_TRUNCATION 0x00001000
  79#define STRSAFE_IGNORE_NULL_UNICODE_STRINGS 0x00010000
  80#define STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED 0x00020000
  81
  82#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)
  83#define STRSAFE_UNICODE_STRING_VALID_FLAGS (STRSAFE_VALID_FLAGS | STRSAFE_IGNORE_NULL_UNICODE_STRINGS | STRSAFE_UNICODE_STRING_DEST_NULL_TERMINATED)
  84
  85#define STRSAFE_FILL_BYTE(x) ((unsigned __LONG32)((x & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL))
  86#define STRSAFE_FAILURE_BYTE(x) ((unsigned __LONG32)((x & 0x000000FF) | STRSAFE_FILL_ON_FAILURE))
  87
  88#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)(dwFlags & 0x000000FF))
  89
  90typedef char *NTSTRSAFE_PSTR;
  91typedef const char *NTSTRSAFE_PCSTR;
  92typedef wchar_t *NTSTRSAFE_PWSTR;
  93typedef const wchar_t *NTSTRSAFE_PCWSTR;
  94
  95NTSTRSAFEDDI RtlStringCopyWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc);
  96NTSTRSAFEDDI RtlStringCopyWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc);
  97NTSTRSAFEDDI RtlStringCopyExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
  98NTSTRSAFEDDI RtlStringCopyExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
  99NTSTRSAFEDDI RtlStringCopyNWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy);
 100NTSTRSAFEDDI RtlStringCopyNWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy);
 101NTSTRSAFEDDI RtlStringCopyNExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 102NTSTRSAFEDDI RtlStringCopyNExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 103NTSTRSAFEDDI RtlStringCatWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc);
 104NTSTRSAFEDDI RtlStringCatWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc);
 105NTSTRSAFEDDI RtlStringCatExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 106NTSTRSAFEDDI RtlStringCatExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 107NTSTRSAFEDDI RtlStringCatNWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend);
 108NTSTRSAFEDDI RtlStringCatNWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend);
 109NTSTRSAFEDDI RtlStringCatNExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 110NTSTRSAFEDDI RtlStringCatNExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 111NTSTRSAFEDDI RtlStringVPrintfWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszFormat,va_list argList);
 112NTSTRSAFEDDI RtlStringVPrintfWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszFormat,va_list argList);
 113NTSTRSAFEDDI RtlStringVPrintfExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,va_list argList);
 114NTSTRSAFEDDI RtlStringVPrintfExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,va_list argList);
 115NTSTRSAFEDDI RtlStringLengthWorkerA(NTSTRSAFE_PCSTR psz,size_t cchMax,size_t *pcchLength);
 116NTSTRSAFEDDI RtlStringLengthWorkerW(NTSTRSAFE_PCWSTR psz,size_t cchMax,size_t *pcchLength);
 117
 118#define RtlStringCchCopy __MINGW_NAME_AW(RtlStringCchCopy)
 119
 120NTSTRSAFEDDI RtlStringCchCopyA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc);
 121NTSTRSAFEDDI RtlStringCchCopyW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc);
 122
 123#ifndef __STRSAFE__NO_INLINE
 124NTSTRSAFEDDI RtlStringCchCopyA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc) {
 125  return (cchDest > NTSTRSAFE_MAX_CCH ? STATUS_INVALID_PARAMETER : RtlStringCopyWorkerA(pszDest,cchDest,pszSrc));
 126}
 127
 128NTSTRSAFEDDI RtlStringCchCopyW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc) {
 129  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 130  return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc);
 131}
 132#endif /* !__STRSAFE__NO_INLINE */
 133
 134#define RtlStringCbCopy __MINGW_NAME_AW(RtlStringCbCopy)
 135
 136NTSTRSAFEDDI RtlStringCbCopyA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc);
 137NTSTRSAFEDDI RtlStringCbCopyW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc);
 138
 139#ifndef __STRSAFE__NO_INLINE
 140NTSTRSAFEDDI RtlStringCbCopyA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc) {
 141  if(cbDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 142  return RtlStringCopyWorkerA(pszDest,cbDest,pszSrc);
 143}
 144
 145NTSTRSAFEDDI RtlStringCbCopyW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc) {
 146  size_t cchDest = cbDest / sizeof(wchar_t);
 147  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 148  return RtlStringCopyWorkerW(pszDest,cchDest,pszSrc);
 149}
 150#endif /* !__STRSAFE__NO_INLINE */
 151
 152#define RtlStringCchCopyEx __MINGW_NAME_AW(RtlStringCchCopyEx)
 153
 154NTSTRSAFEDDI RtlStringCchCopyExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 155NTSTRSAFEDDI RtlStringCchCopyExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 156
 157#ifndef __STRSAFE__NO_INLINE
 158NTSTRSAFEDDI RtlStringCchCopyExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 159  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 160  return RtlStringCopyExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
 161}
 162
 163NTSTRSAFEDDI RtlStringCchCopyExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 164  size_t cbDest;
 165  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 166  cbDest = cchDest * sizeof(wchar_t);
 167  return RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
 168}
 169#endif /* !__STRSAFE__NO_INLINE */
 170
 171#define RtlStringCbCopyEx __MINGW_NAME_AW(RtlStringCbCopyEx)
 172
 173NTSTRSAFEDDI RtlStringCbCopyExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 174NTSTRSAFEDDI RtlStringCbCopyExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 175
 176#ifndef __STRSAFE__NO_INLINE
 177NTSTRSAFEDDI RtlStringCbCopyExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 178  NTSTATUS hr;
 179  size_t cchRemaining = 0;
 180  if(cbDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 181  hr = RtlStringCopyExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
 182  if(NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) {
 183    if(pcbRemaining)
 184      *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
 185  }
 186  return hr;
 187}
 188
 189NTSTRSAFEDDI RtlStringCbCopyExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 190  NTSTATUS hr;
 191  size_t cchDest = cbDest / sizeof(wchar_t);
 192  size_t cchRemaining = 0;
 193
 194  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 195  hr = RtlStringCopyExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
 196  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 197    if(pcbRemaining)
 198      *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
 199  }
 200  return hr;
 201}
 202#endif /* !__STRSAFE__NO_INLINE */
 203
 204NTSTRSAFEDDI RtlStringCchCopyNA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy);
 205NTSTRSAFEDDI RtlStringCchCopyNW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy);
 206#define RtlStringCchCopyN __MINGW_NAME_AW(RtlStringCchCopyN)
 207
 208#ifndef __STRSAFE__NO_INLINE
 209NTSTRSAFEDDI RtlStringCchCopyNA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy) {
 210  if(cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
 211    return STATUS_INVALID_PARAMETER;
 212  return RtlStringCopyNWorkerA(pszDest,cchDest,pszSrc,cchToCopy);
 213}
 214
 215NTSTRSAFEDDI RtlStringCchCopyNW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy) {
 216  if(cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
 217    return STATUS_INVALID_PARAMETER;
 218  return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy);
 219}
 220#endif /* !__STRSAFE__NO_INLINE */
 221
 222NTSTRSAFEDDI RtlStringCbCopyNA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToCopy);
 223NTSTRSAFEDDI RtlStringCbCopyNW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToCopy);
 224
 225#define RtlStringCbCopyN __MINGW_NAME_AW(RtlStringCbCopyN)
 226
 227#ifndef __STRSAFE__NO_INLINE
 228NTSTRSAFEDDI RtlStringCbCopyNA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToCopy) {
 229  if(cbDest > NTSTRSAFE_MAX_CCH || cbToCopy > NTSTRSAFE_MAX_CCH)
 230    return STATUS_INVALID_PARAMETER;
 231  return RtlStringCopyNWorkerA(pszDest,cbDest,pszSrc,cbToCopy);
 232}
 233
 234NTSTRSAFEDDI RtlStringCbCopyNW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToCopy) {
 235  size_t cchDest  = cbDest / sizeof(wchar_t);
 236  size_t cchToCopy = cbToCopy / sizeof(wchar_t);
 237  if(cchDest > NTSTRSAFE_MAX_CCH || cchToCopy > NTSTRSAFE_MAX_CCH)
 238    return STATUS_INVALID_PARAMETER;
 239  return RtlStringCopyNWorkerW(pszDest,cchDest,pszSrc,cchToCopy);
 240}
 241#endif /* !__STRSAFE__NO_INLINE */
 242
 243NTSTRSAFEDDI RtlStringCchCopyNExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 244NTSTRSAFEDDI RtlStringCchCopyNExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 245
 246#define RtlStringCchCopyNEx __MINGW_NAME_AW(RtlStringCchCopyNEx)
 247
 248#ifndef __STRSAFE__NO_INLINE
 249NTSTRSAFEDDI RtlStringCchCopyNExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 250  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 251  return RtlStringCopyNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags);
 252}
 253
 254NTSTRSAFEDDI RtlStringCchCopyNExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 255  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 256  return RtlStringCopyNExWorkerW(pszDest,cchDest,cchDest * sizeof(wchar_t),pszSrc,cchToCopy,ppszDestEnd,pcchRemaining,dwFlags);
 257}
 258#endif /* !__STRSAFE__NO_INLINE */
 259
 260NTSTRSAFEDDI RtlStringCbCopyNExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToCopy,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 261NTSTRSAFEDDI RtlStringCbCopyNExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToCopy,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 262
 263#define RtlStringCbCopyNEx __MINGW_NAME_AW(RtlStringCbCopyNEx)
 264
 265#ifndef __STRSAFE__NO_INLINE
 266NTSTRSAFEDDI RtlStringCbCopyNExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToCopy,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 267  NTSTATUS hr;
 268  size_t cchRemaining = 0;
 269  if(cbDest > NTSTRSAFE_MAX_CCH)
 270    hr = STATUS_INVALID_PARAMETER;
 271  else
 272    hr = RtlStringCopyNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToCopy,ppszDestEnd,&cchRemaining,dwFlags);
 273  if((NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
 274    *pcbRemaining = cchRemaining;
 275  return hr;
 276}
 277
 278NTSTRSAFEDDI RtlStringCbCopyNExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToCopy,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 279  NTSTATUS hr;
 280  size_t cchDest;
 281  size_t cchToCopy;
 282  size_t cchRemaining = 0;
 283  cchDest = cbDest / sizeof(wchar_t);
 284  cchToCopy = cbToCopy / sizeof(wchar_t);
 285  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 286  else hr = RtlStringCopyNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToCopy,ppszDestEnd,&cchRemaining,dwFlags);
 287  if((NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
 288    *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
 289  return hr;
 290}
 291#endif /* !__STRSAFE__NO_INLINE */
 292
 293NTSTRSAFEDDI RtlStringCchCatA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc);
 294NTSTRSAFEDDI RtlStringCchCatW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc);
 295
 296#define RtlStringCchCat __MINGW_NAME_AW(RtlStringCchCat)
 297
 298#ifndef __STRSAFE__NO_INLINE
 299NTSTRSAFEDDI RtlStringCchCatA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc) {
 300  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 301  return RtlStringCatWorkerA(pszDest,cchDest,pszSrc);
 302}
 303
 304NTSTRSAFEDDI RtlStringCchCatW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc) {
 305  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 306  return RtlStringCatWorkerW(pszDest,cchDest,pszSrc);
 307}
 308#endif /* !__STRSAFE__NO_INLINE */
 309
 310NTSTRSAFEDDI RtlStringCbCatA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc);
 311NTSTRSAFEDDI RtlStringCbCatW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc);
 312
 313#define RtlStringCbCat __MINGW_NAME_AW(RtlStringCbCat)
 314
 315#ifndef __STRSAFE__NO_INLINE
 316NTSTRSAFEDDI RtlStringCbCatA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc) {
 317  if(cbDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 318  return RtlStringCatWorkerA(pszDest,cbDest,pszSrc);
 319}
 320
 321NTSTRSAFEDDI RtlStringCbCatW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc) {
 322  size_t cchDest = cbDest / sizeof(wchar_t);
 323  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 324  return RtlStringCatWorkerW(pszDest,cchDest,pszSrc);
 325}
 326#endif /* !__STRSAFE__NO_INLINE */
 327
 328NTSTRSAFEDDI RtlStringCchCatExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 329NTSTRSAFEDDI RtlStringCchCatExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 330
 331#define RtlStringCchCatEx __MINGW_NAME_AW(RtlStringCchCatEx)
 332
 333#ifndef __STRSAFE__NO_INLINE
 334NTSTRSAFEDDI RtlStringCchCatExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 335  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 336  return RtlStringCatExWorkerA(pszDest,cchDest,cchDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
 337}
 338
 339NTSTRSAFEDDI RtlStringCchCatExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 340  size_t cbDest = cchDest*sizeof(wchar_t);
 341  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 342  return RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,pcchRemaining,dwFlags);
 343}
 344#endif /* !__STRSAFE__NO_INLINE */
 345
 346NTSTRSAFEDDI RtlStringCbCatExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 347NTSTRSAFEDDI RtlStringCbCatExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 348
 349#define RtlStringCbCatEx __MINGW_NAME_AW(RtlStringCbCatEx)
 350
 351#ifndef __STRSAFE__NO_INLINE
 352NTSTRSAFEDDI RtlStringCbCatExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 353  NTSTATUS hr;
 354  size_t cchRemaining = 0;
 355  if(cbDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 356  else hr = RtlStringCatExWorkerA(pszDest,cbDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
 357  if((NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
 358    *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
 359  return hr;
 360}
 361
 362NTSTRSAFEDDI RtlStringCbCatExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 363  NTSTATUS hr;
 364  size_t cchDest = cbDest / sizeof(wchar_t);
 365  size_t cchRemaining = 0;
 366
 367  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 368  else hr = RtlStringCatExWorkerW(pszDest,cchDest,cbDest,pszSrc,ppszDestEnd,&cchRemaining,dwFlags);
 369  if((NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
 370    *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
 371  return hr;
 372}
 373#endif /* !__STRSAFE__NO_INLINE */
 374
 375NTSTRSAFEDDI RtlStringCchCatNA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend);
 376NTSTRSAFEDDI RtlStringCchCatNW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend);
 377
 378#define RtlStringCchCatN __MINGW_NAME_AW(RtlStringCchCatN)
 379
 380#ifndef __STRSAFE__NO_INLINE
 381NTSTRSAFEDDI RtlStringCchCatNA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend) {
 382  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 383  return RtlStringCatNWorkerA(pszDest,cchDest,pszSrc,cchToAppend);
 384}
 385
 386NTSTRSAFEDDI RtlStringCchCatNW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend) {
 387  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 388  return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend);
 389}
 390#endif /* !__STRSAFE__NO_INLINE */
 391
 392NTSTRSAFEDDI RtlStringCbCatNA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToAppend);
 393NTSTRSAFEDDI RtlStringCbCatNW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToAppend);
 394
 395#define RtlStringCbCatN __MINGW_NAME_AW(RtlStringCbCatN)
 396
 397#ifndef __STRSAFE__NO_INLINE
 398NTSTRSAFEDDI RtlStringCbCatNA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToAppend) {
 399  if(cbDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 400  return RtlStringCatNWorkerA(pszDest,cbDest,pszSrc,cbToAppend);
 401}
 402
 403NTSTRSAFEDDI RtlStringCbCatNW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToAppend) {
 404  size_t cchDest = cbDest / sizeof(wchar_t);
 405  size_t cchToAppend = cbToAppend / sizeof(wchar_t);
 406
 407  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 408  return RtlStringCatNWorkerW(pszDest,cchDest,pszSrc,cchToAppend);
 409}
 410#endif /* !__STRSAFE__NO_INLINE */
 411
 412NTSTRSAFEDDI RtlStringCchCatNExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 413NTSTRSAFEDDI RtlStringCchCatNExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags);
 414
 415#define RtlStringCchCatNEx __MINGW_NAME_AW(RtlStringCchCatNEx)
 416
 417#ifndef __STRSAFE__NO_INLINE
 418NTSTRSAFEDDI RtlStringCchCatNExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 419  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 420  return RtlStringCatNExWorkerA(pszDest,cchDest,cchDest,pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags);
 421}
 422
 423NTSTRSAFEDDI RtlStringCchCatNExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 424  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 425  return RtlStringCatNExWorkerW(pszDest,cchDest,(cchDest*sizeof(wchar_t)),pszSrc,cchToAppend,ppszDestEnd,pcchRemaining,dwFlags);
 426}
 427#endif
 428
 429NTSTRSAFEDDI RtlStringCbCatNExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToAppend,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 430NTSTRSAFEDDI RtlStringCbCatNExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToAppend,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags);
 431
 432#define RtlStringCbCatNEx __MINGW_NAME_AW(RtlStringCbCatNEx)
 433
 434#ifndef __STRSAFE__NO_INLINE
 435NTSTRSAFEDDI RtlStringCbCatNExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cbToAppend,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 436  NTSTATUS hr;
 437  size_t cchRemaining = 0;
 438  if(cbDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 439  else hr = RtlStringCatNExWorkerA(pszDest,cbDest,cbDest,pszSrc,cbToAppend,ppszDestEnd,&cchRemaining,dwFlags);
 440  if((NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
 441    *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
 442  return hr;
 443}
 444
 445NTSTRSAFEDDI RtlStringCbCatNExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cbToAppend,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags) {
 446  NTSTATUS hr;
 447  size_t cchDest = cbDest / sizeof(wchar_t);
 448  size_t cchToAppend = cbToAppend / sizeof(wchar_t);
 449  size_t cchRemaining = 0;
 450  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 451  else hr = RtlStringCatNExWorkerW(pszDest,cchDest,cbDest,pszSrc,cchToAppend,ppszDestEnd,&cchRemaining,dwFlags);
 452  if((NT_SUCCESS(hr) || hr == STATUS_BUFFER_OVERFLOW) && pcbRemaining)
 453    *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
 454  return hr;
 455}
 456#endif /* !__STRSAFE__NO_INLINE */
 457
 458NTSTRSAFEDDI RtlStringCchVPrintfA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszFormat,va_list argList);
 459NTSTRSAFEDDI RtlStringCchVPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszFormat,va_list argList);
 460
 461#define RtlStringCchVPrintf __MINGW_NAME_AW(RtlStringCchVPrintf)
 462
 463#ifndef __STRSAFE__NO_INLINE
 464NTSTRSAFEDDI RtlStringCchVPrintfA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszFormat,va_list argList) {
 465  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 466  return RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList);
 467}
 468
 469NTSTRSAFEDDI RtlStringCchVPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszFormat,va_list argList) {
 470  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 471  return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
 472}
 473#endif /* !__STRSAFE__NO_INLINE */
 474
 475NTSTRSAFEDDI RtlStringCbVPrintfA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszFormat,va_list argList);
 476NTSTRSAFEDDI RtlStringCbVPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszFormat,va_list argList);
 477
 478#define RtlStringCbVPrintf __MINGW_NAME_AW(RtlStringCbVPrintf)
 479
 480#ifndef __STRSAFE__NO_INLINE
 481NTSTRSAFEDDI RtlStringCbVPrintfA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszFormat,va_list argList) {
 482  if(cbDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 483  return RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList);
 484}
 485
 486NTSTRSAFEDDI RtlStringCbVPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszFormat,va_list argList) {
 487  size_t cchDest = cbDest / sizeof(wchar_t);
 488  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 489  return RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
 490}
 491#endif /* !__STRSAFE__NO_INLINE */
 492
 493NTSTRSAFEDDIV RtlStringCchPrintfA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszFormat,...);
 494NTSTRSAFEDDIV RtlStringCchPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszFormat,...);
 495
 496#define RtlStringCchPrintf __MINGW_NAME_AW(RtlStringCchPrintf)
 497
 498#ifndef __STRSAFE__NO_INLINE
 499NTSTRSAFEDDIV RtlStringCchPrintfA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszFormat,...) {
 500  NTSTATUS hr;
 501  va_list argList;
 502  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 503  va_start(argList,pszFormat);
 504  hr = RtlStringVPrintfWorkerA(pszDest,cchDest,pszFormat,argList);
 505  va_end(argList);
 506  return hr;
 507}
 508
 509NTSTRSAFEDDIV RtlStringCchPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszFormat,...) {
 510  NTSTATUS hr;
 511  va_list argList;
 512  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 513  va_start(argList,pszFormat);
 514  hr = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
 515  va_end(argList);
 516  return hr;
 517}
 518#endif /* !__STRSAFE__NO_INLINE */
 519
 520NTSTRSAFEDDIV RtlStringCbPrintfA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszFormat,...);
 521NTSTRSAFEDDIV RtlStringCbPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszFormat,...);
 522
 523#define RtlStringCbPrintf __MINGW_NAME_AW(RtlStringCbPrintf)
 524
 525#ifndef __STRSAFE__NO_INLINE
 526NTSTRSAFEDDIV RtlStringCbPrintfA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PCSTR pszFormat,...) {
 527  NTSTATUS hr;
 528  va_list argList;
 529  if(cbDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 530  va_start(argList,pszFormat);
 531  hr = RtlStringVPrintfWorkerA(pszDest,cbDest,pszFormat,argList);
 532  va_end(argList);
 533  return hr;
 534}
 535
 536NTSTRSAFEDDIV RtlStringCbPrintfW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PCWSTR pszFormat,...) {
 537  NTSTATUS hr;
 538  va_list argList;
 539  size_t cchDest = cbDest / sizeof(wchar_t);
 540  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 541  va_start(argList,pszFormat);
 542  hr = RtlStringVPrintfWorkerW(pszDest,cchDest,pszFormat,argList);
 543  va_end(argList);
 544  return hr;
 545}
 546#endif /* !__STRSAFE__NO_INLINE */
 547
 548NTSTRSAFEDDIV RtlStringCchPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,...);
 549NTSTRSAFEDDIV RtlStringCchPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,...);
 550
 551#define RtlStringCchPrintfEx __MINGW_NAME_AW(RtlStringCchPrintfEx)
 552
 553#ifndef __STRSAFE__NO_INLINE
 554NTSTRSAFEDDIV RtlStringCchPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,...) {
 555  NTSTATUS hr;
 556  va_list argList;
 557  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 558  va_start(argList,pszFormat);
 559  hr = RtlStringVPrintfExWorkerA(pszDest,cchDest,cchDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
 560  va_end(argList);
 561  return hr;
 562}
 563
 564NTSTRSAFEDDIV RtlStringCchPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,...) {
 565  NTSTATUS hr;
 566  size_t cbDest = cchDest * sizeof(wchar_t);
 567  va_list argList;
 568  if(cchDest > NTSTRSAFE_MAX_CCH) return STATUS_INVALID_PARAMETER;
 569  va_start(argList,pszFormat);
 570  hr = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
 571  va_end(argList);
 572  return hr;
 573}
 574#endif /* !__STRSAFE__NO_INLINE */
 575
 576NTSTRSAFEDDIV RtlStringCbPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,...);
 577NTSTRSAFEDDIV RtlStringCbPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,...);
 578
 579#define RtlStringCbPrintfEx __MINGW_NAME_AW(RtlStringCbPrintfEx)
 580
 581#ifndef __STRSAFE__NO_INLINE
 582NTSTRSAFEDDIV RtlStringCbPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,...) {
 583  NTSTATUS hr;
 584  size_t cchDest;
 585  size_t cchRemaining = 0;
 586  cchDest = cbDest / sizeof(char);
 587  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 588  else {
 589    va_list argList;
 590    va_start(argList,pszFormat);
 591    hr = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
 592    va_end(argList);
 593  }
 594  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 595    if(pcbRemaining) {
 596      *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
 597    }
 598  }
 599  return hr;
 600}
 601
 602NTSTRSAFEDDIV RtlStringCbPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,...) {
 603  NTSTATUS hr;
 604  size_t cchDest;
 605  size_t cchRemaining = 0;
 606  cchDest = cbDest / sizeof(wchar_t);
 607  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 608  else {
 609    va_list argList;
 610    va_start(argList,pszFormat);
 611    hr = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
 612    va_end(argList);
 613  }
 614  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 615    if(pcbRemaining) {
 616      *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
 617    }
 618  }
 619  return hr;
 620}
 621#endif /* !__STRSAFE__NO_INLINE */
 622
 623NTSTRSAFEDDI RtlStringCchVPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,va_list argList);
 624NTSTRSAFEDDI RtlStringCchVPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,va_list argList);
 625
 626#define RtlStringCchVPrintfEx __MINGW_NAME_AW(RtlStringCchVPrintfEx)
 627
 628#ifndef __STRSAFE__NO_INLINE
 629NTSTRSAFEDDI RtlStringCchVPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,va_list argList) {
 630  NTSTATUS hr;
 631  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 632  else {
 633    size_t cbDest;
 634    cbDest = cchDest*sizeof(char);
 635    hr = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
 636  }
 637  return hr;
 638}
 639
 640NTSTRSAFEDDI RtlStringCchVPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,va_list argList) {
 641  NTSTATUS hr;
 642  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 643  else {
 644    size_t cbDest;
 645    cbDest = cchDest*sizeof(wchar_t);
 646    hr = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,pcchRemaining,dwFlags,pszFormat,argList);
 647  }
 648  return hr;
 649}
 650#endif /* !__STRSAFE__NO_INLINE */
 651
 652NTSTRSAFEDDI RtlStringCbVPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,va_list argList);
 653NTSTRSAFEDDI RtlStringCbVPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,va_list argList);
 654
 655#define RtlStringCbVPrintfEx __MINGW_NAME_AW(RtlStringCbVPrintfEx)
 656
 657#ifndef __STRSAFE__NO_INLINE
 658NTSTRSAFEDDI RtlStringCbVPrintfExA(NTSTRSAFE_PSTR pszDest,size_t cbDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,va_list argList) {
 659  NTSTATUS hr;
 660  size_t cchDest;
 661  size_t cchRemaining = 0;
 662  cchDest = cbDest / sizeof(char);
 663  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 664  else hr = RtlStringVPrintfExWorkerA(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
 665  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 666    if(pcbRemaining) {
 667      *pcbRemaining = (cchRemaining*sizeof(char)) + (cbDest % sizeof(char));
 668    }
 669  }
 670  return hr;
 671}
 672
 673NTSTRSAFEDDI RtlStringCbVPrintfExW(NTSTRSAFE_PWSTR pszDest,size_t cbDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcbRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,va_list argList) {
 674  NTSTATUS hr;
 675  size_t cchDest;
 676  size_t cchRemaining = 0;
 677  cchDest = cbDest / sizeof(wchar_t);
 678  if(cchDest > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 679  else hr = RtlStringVPrintfExWorkerW(pszDest,cchDest,cbDest,ppszDestEnd,&cchRemaining,dwFlags,pszFormat,argList);
 680  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 681    if(pcbRemaining) {
 682      *pcbRemaining = (cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
 683    }
 684  }
 685  return hr;
 686}
 687#endif /* !__STRSAFE__NO_INLINE */
 688
 689NTSTRSAFEDDI RtlStringCchLengthA(NTSTRSAFE_PCSTR psz,size_t cchMax,size_t *pcchLength);
 690NTSTRSAFEDDI RtlStringCchLengthW(NTSTRSAFE_PCWSTR psz,size_t cchMax,size_t *pcchLength);
 691
 692#define RtlStringCchLength __MINGW_NAME_AW(RtlStringCchLength)
 693
 694#ifndef __STRSAFE__NO_INLINE
 695NTSTRSAFEDDI RtlStringCchLengthA(NTSTRSAFE_PCSTR psz,size_t cchMax,size_t *pcchLength) {
 696  NTSTATUS hr;
 697  if(!psz || (cchMax > NTSTRSAFE_MAX_CCH)) hr = STATUS_INVALID_PARAMETER;
 698  else hr = RtlStringLengthWorkerA(psz,cchMax,pcchLength);
 699  if(!NT_SUCCESS(hr) && pcchLength) {
 700    *pcchLength = 0;
 701  }
 702  return hr;
 703}
 704
 705NTSTRSAFEDDI RtlStringCchLengthW(NTSTRSAFE_PCWSTR psz,size_t cchMax,size_t *pcchLength) {
 706  NTSTATUS hr;
 707  if(!psz || (cchMax > NTSTRSAFE_MAX_CCH)) hr = STATUS_INVALID_PARAMETER;
 708  else hr = RtlStringLengthWorkerW(psz,cchMax,pcchLength);
 709  if(!NT_SUCCESS(hr) && pcchLength) {
 710    *pcchLength = 0;
 711  }
 712  return hr;
 713}
 714#endif /* !__STRSAFE__NO_INLINE */
 715
 716NTSTRSAFEDDI RtlStringCbLengthA(NTSTRSAFE_PCSTR psz,size_t cbMax,size_t *pcbLength);
 717NTSTRSAFEDDI RtlStringCbLengthW(NTSTRSAFE_PCWSTR psz,size_t cbMax,size_t *pcbLength);
 718
 719#define RtlStringCbLength __MINGW_NAME_AW(RtlStringCbLength)
 720
 721#ifndef __STRSAFE__NO_INLINE
 722NTSTRSAFEDDI RtlStringCbLengthA(NTSTRSAFE_PCSTR psz,size_t cbMax,size_t *pcbLength) {
 723  NTSTATUS hr;
 724  size_t cchMax;
 725  size_t cchLength = 0;
 726  cchMax = cbMax / sizeof(char);
 727  if(!psz || (cchMax > NTSTRSAFE_MAX_CCH)) hr = STATUS_INVALID_PARAMETER;
 728  else hr = RtlStringLengthWorkerA(psz,cchMax,&cchLength);
 729  if(pcbLength) {
 730    if(NT_SUCCESS(hr)) {
 731      *pcbLength = cchLength*sizeof(char);
 732    } else {
 733      *pcbLength = 0;
 734    }
 735  }
 736  return hr;
 737}
 738
 739NTSTRSAFEDDI RtlStringCbLengthW(NTSTRSAFE_PCWSTR psz,size_t cbMax,size_t *pcbLength) {
 740  NTSTATUS hr;
 741  size_t cchMax;
 742  size_t cchLength = 0;
 743  cchMax = cbMax / sizeof(wchar_t);
 744  if(!psz || (cchMax > NTSTRSAFE_MAX_CCH)) hr = STATUS_INVALID_PARAMETER;
 745  else hr = RtlStringLengthWorkerW(psz,cchMax,&cchLength);
 746  if(pcbLength) {
 747    if(NT_SUCCESS(hr)) {
 748      *pcbLength = cchLength*sizeof(wchar_t);
 749    } else {
 750      *pcbLength = 0;
 751    }
 752  }
 753  return hr;
 754}
 755
 756NTSTRSAFEDDI RtlStringCopyWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc) {
 757  NTSTATUS hr = STATUS_SUCCESS;
 758  if(cchDest==0) hr = STATUS_INVALID_PARAMETER;
 759  else {
 760    while(cchDest && (*pszSrc!='\0')) {
 761      *pszDest++ = *pszSrc++;
 762      cchDest--;
 763    }
 764    if(cchDest==0) {
 765      pszDest--;
 766      hr = STATUS_BUFFER_OVERFLOW;
 767    }
 768    *pszDest= '\0';
 769  }
 770  return hr;
 771}
 772
 773NTSTRSAFEDDI RtlStringCopyWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc) {
 774  NTSTATUS hr = STATUS_SUCCESS;
 775  if(cchDest==0) hr = STATUS_INVALID_PARAMETER;
 776  else {
 777    while(cchDest && (*pszSrc!=L'\0')) {
 778      *pszDest++ = *pszSrc++;
 779      cchDest--;
 780    }
 781    if(cchDest==0) {
 782      pszDest--;
 783      hr = STATUS_BUFFER_OVERFLOW;
 784    }
 785    *pszDest= L'\0';
 786  }
 787  return hr;
 788}
 789
 790NTSTRSAFEDDI RtlStringCopyExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 791  NTSTATUS hr = STATUS_SUCCESS;
 792  NTSTRSAFE_PSTR pszDestEnd = pszDest;
 793  size_t cchRemaining = 0;
 794  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
 795  else {
 796    if(dwFlags & STRSAFE_IGNORE_NULLS) {
 797      if(!pszDest) {
 798	if((cchDest!=0) || (cbDest!=0)) hr = STATUS_INVALID_PARAMETER;
 799      }
 800      if(!pszSrc) pszSrc = "";
 801    }
 802    if(NT_SUCCESS(hr)) {
 803      if(cchDest==0) {
 804	pszDestEnd = pszDest;
 805	cchRemaining = 0;
 806	if(*pszSrc!='\0') {
 807	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
 808	  else hr = STATUS_BUFFER_OVERFLOW;
 809	}
 810      } else {
 811	pszDestEnd = pszDest;
 812	cchRemaining = cchDest;
 813	while(cchRemaining && (*pszSrc!='\0')) {
 814	  *pszDestEnd++ = *pszSrc++;
 815	  cchRemaining--;
 816	}
 817	if(cchRemaining > 0) {
 818	  if(dwFlags & STRSAFE_FILL_BEHIND_NULL) {
 819	    memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
 820	  }
 821	} else {
 822	  pszDestEnd--;
 823	  cchRemaining++;
 824	  hr = STATUS_BUFFER_OVERFLOW;
 825	}
 826	*pszDestEnd = '\0';
 827      }
 828    }
 829  }
 830  if(!NT_SUCCESS(hr)) {
 831    if(pszDest) {
 832      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
 833	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
 834	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
 835	  pszDestEnd = pszDest;
 836	  cchRemaining = cchDest;
 837	} else if(cchDest > 0) {
 838	  pszDestEnd = pszDest + cchDest - 1;
 839	  cchRemaining = 1;
 840	  *pszDestEnd = '\0';
 841	}
 842      }
 843      if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) {
 844	if(cchDest > 0) {
 845	  pszDestEnd = pszDest;
 846	  cchRemaining = cchDest;
 847	  *pszDestEnd = '\0';
 848	}
 849      }
 850    }
 851  }
 852  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 853    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
 854    if(pcchRemaining) *pcchRemaining = cchRemaining;
 855  }
 856  return hr;
 857}
 858
 859NTSTRSAFEDDI RtlStringCopyExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 860  NTSTATUS hr = STATUS_SUCCESS;
 861  NTSTRSAFE_PWSTR pszDestEnd = pszDest;
 862  size_t cchRemaining = 0;
 863  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
 864  else {
 865    if(dwFlags & STRSAFE_IGNORE_NULLS) {
 866      if(!pszDest) {
 867	if((cchDest!=0) || (cbDest!=0)) hr = STATUS_INVALID_PARAMETER;
 868      }
 869      if(!pszSrc) pszSrc = L"";
 870    }
 871    if(NT_SUCCESS(hr)) {
 872      if(cchDest==0) {
 873	pszDestEnd = pszDest;
 874	cchRemaining = 0;
 875	if(*pszSrc!=L'\0') {
 876	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
 877	  else hr = STATUS_BUFFER_OVERFLOW;
 878	}
 879      } else {
 880	pszDestEnd = pszDest;
 881	cchRemaining = cchDest;
 882	while(cchRemaining && (*pszSrc!=L'\0')) {
 883	  *pszDestEnd++ = *pszSrc++;
 884	  cchRemaining--;
 885	}
 886	if(cchRemaining > 0) {
 887	  if(dwFlags & STRSAFE_FILL_BEHIND_NULL) {
 888	    memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
 889	  }
 890	} else {
 891	  pszDestEnd--;
 892	  cchRemaining++;
 893	  hr = STATUS_BUFFER_OVERFLOW;
 894	}
 895	*pszDestEnd = L'\0';
 896      }
 897    }
 898  }
 899  if(!NT_SUCCESS(hr)) {
 900    if(pszDest) {
 901      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
 902	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
 903	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
 904	  pszDestEnd = pszDest;
 905	  cchRemaining = cchDest;
 906	} else if(cchDest > 0) {
 907	  pszDestEnd = pszDest + cchDest - 1;
 908	  cchRemaining = 1;
 909	  *pszDestEnd = L'\0';
 910	}
 911      }
 912      if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) {
 913	if(cchDest > 0) {
 914	  pszDestEnd = pszDest;
 915	  cchRemaining = cchDest;
 916	  *pszDestEnd = L'\0';
 917	}
 918      }
 919    }
 920  }
 921  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
 922    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
 923    if(pcchRemaining) *pcchRemaining = cchRemaining;
 924  }
 925  return hr;
 926}
 927
 928NTSTRSAFEDDI RtlStringCopyNWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchSrc) {
 929  NTSTATUS hr = STATUS_SUCCESS;
 930  if(cchDest==0) hr = STATUS_INVALID_PARAMETER;
 931  else {
 932    while(cchDest && cchSrc && (*pszSrc!='\0')) {
 933      *pszDest++ = *pszSrc++;
 934      cchDest--;
 935      cchSrc--;
 936    }
 937    if(cchDest==0) {
 938      pszDest--;
 939      hr = STATUS_BUFFER_OVERFLOW;
 940    }
 941    *pszDest= '\0';
 942  }
 943  return hr;
 944}
 945
 946NTSTRSAFEDDI RtlStringCopyNWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy) {
 947  NTSTATUS hr = STATUS_SUCCESS;
 948  if(cchDest==0) hr = STATUS_INVALID_PARAMETER;
 949  else {
 950    while(cchDest && cchToCopy && (*pszSrc!=L'\0')) {
 951      *pszDest++ = *pszSrc++;
 952      cchDest--;
 953      cchToCopy--;
 954    }
 955    if(cchDest==0) {
 956      pszDest--;
 957      hr = STATUS_BUFFER_OVERFLOW;
 958    }
 959    *pszDest= L'\0';
 960  }
 961  return hr;
 962}
 963
 964NTSTRSAFEDDI RtlStringCopyNExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
 965  NTSTATUS hr = STATUS_SUCCESS;
 966  NTSTRSAFE_PSTR pszDestEnd = pszDest;
 967  size_t cchRemaining = 0;
 968  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
 969  else if(cchToCopy > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
 970  else {
 971    if(dwFlags & STRSAFE_IGNORE_NULLS) {
 972      if(!pszDest) {
 973	if((cchDest!=0) || (cbDest!=0)) hr = STATUS_INVALID_PARAMETER;
 974      }
 975      if(!pszSrc) pszSrc = "";
 976    }
 977    if(NT_SUCCESS(hr)) {
 978      if(cchDest==0) {
 979	pszDestEnd = pszDest;
 980	cchRemaining = 0;
 981	if((cchToCopy!=0) && (*pszSrc!='\0')) {
 982	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
 983	  else hr = STATUS_BUFFER_OVERFLOW;
 984	}
 985      } else {
 986	pszDestEnd = pszDest;
 987	cchRemaining = cchDest;
 988	while(cchRemaining && cchToCopy && (*pszSrc!='\0')) {
 989	  *pszDestEnd++ = *pszSrc++;
 990	  cchRemaining--;
 991	  cchToCopy--;
 992	}
 993	if(cchRemaining > 0) {
 994	  if(dwFlags & STRSAFE_FILL_BEHIND_NULL) {
 995	    memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
 996	  }
 997	} else {
 998	  pszDestEnd--;
 999	  cchRemaining++;
1000	  hr = STATUS_BUFFER_OVERFLOW;
1001	}
1002	*pszDestEnd = '\0';
1003      }
1004    }
1005  }
1006  if(!NT_SUCCESS(hr)) {
1007    if(pszDest) {
1008      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1009	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1010	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1011	  pszDestEnd = pszDest;
1012	  cchRemaining = cchDest;
1013	} else if(cchDest > 0) {
1014	  pszDestEnd = pszDest + cchDest - 1;
1015	  cchRemaining = 1;
1016	  *pszDestEnd = '\0';
1017	}
1018      }
1019      if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) {
1020	if(cchDest > 0) {
1021	  pszDestEnd = pszDest;
1022	  cchRemaining = cchDest;
1023	  *pszDestEnd = '\0';
1024	}
1025      }
1026    }
1027  }
1028  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1029    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1030    if(pcchRemaining) *pcchRemaining = cchRemaining;
1031  }
1032  return hr;
1033}
1034
1035NTSTRSAFEDDI RtlStringCopyNExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToCopy,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
1036  NTSTATUS hr = STATUS_SUCCESS;
1037  NTSTRSAFE_PWSTR pszDestEnd = pszDest;
1038  size_t cchRemaining = 0;
1039  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1040  else if(cchToCopy > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
1041  else {
1042    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1043      if(!pszDest) {
1044	if((cchDest!=0) || (cbDest!=0)) hr = STATUS_INVALID_PARAMETER;
1045      }
1046      if(!pszSrc) pszSrc = L"";
1047    }
1048    if(NT_SUCCESS(hr)) {
1049      if(cchDest==0) {
1050	pszDestEnd = pszDest;
1051	cchRemaining = 0;
1052	if((cchToCopy!=0) && (*pszSrc!=L'\0')) {
1053	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1054	  else hr = STATUS_BUFFER_OVERFLOW;
1055	}
1056      } else {
1057	pszDestEnd = pszDest;
1058	cchRemaining = cchDest;
1059	while(cchRemaining && cchToCopy && (*pszSrc!=L'\0')) {
1060	  *pszDestEnd++ = *pszSrc++;
1061	  cchRemaining--;
1062	  cchToCopy--;
1063	}
1064	if(cchRemaining > 0) {
1065	  if(dwFlags & STRSAFE_FILL_BEHIND_NULL) {
1066	    memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
1067	  }
1068	} else {
1069	  pszDestEnd--;
1070	  cchRemaining++;
1071	  hr = STATUS_BUFFER_OVERFLOW;
1072	}
1073	*pszDestEnd = L'\0';
1074      }
1075    }
1076  }
1077  if(!NT_SUCCESS(hr)) {
1078    if(pszDest) {
1079      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1080	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1081	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1082	  pszDestEnd = pszDest;
1083	  cchRemaining = cchDest;
1084	} else if(cchDest > 0) {
1085	  pszDestEnd = pszDest + cchDest - 1;
1086	  cchRemaining = 1;
1087	  *pszDestEnd = L'\0';
1088	}
1089      }
1090      if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) {
1091	if(cchDest > 0) {
1092	  pszDestEnd = pszDest;
1093	  cchRemaining = cchDest;
1094	  *pszDestEnd = L'\0';
1095	}
1096      }
1097    }
1098  }
1099  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1100    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1101    if(pcchRemaining) *pcchRemaining = cchRemaining;
1102  }
1103  return hr;
1104}
1105
1106NTSTRSAFEDDI RtlStringCatWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc) {
1107  NTSTATUS hr;
1108  size_t cchDestLength;
1109  hr = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1110  if(NT_SUCCESS(hr)) hr = RtlStringCopyWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc);
1111  return hr;
1112}
1113
1114NTSTRSAFEDDI RtlStringCatWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc) {
1115  NTSTATUS hr;
1116  size_t cchDestLength;
1117  hr = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1118  if(NT_SUCCESS(hr)) hr = RtlStringCopyWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc);
1119  return hr;
1120}
1121
1122NTSTRSAFEDDI RtlStringCatExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
1123  NTSTATUS hr = STATUS_SUCCESS;
1124  NTSTRSAFE_PSTR pszDestEnd = pszDest;
1125  size_t cchRemaining = 0;
1126  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1127  else {
1128    size_t cchDestLength;
1129    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1130      if(!pszDest) {
1131	if((cchDest==0) && (cbDest==0)) cchDestLength = 0;
1132	else hr = STATUS_INVALID_PARAMETER;
1133      } else {
1134	hr = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1135	if(NT_SUCCESS(hr)) {
1136	  pszDestEnd = pszDest + cchDestLength;
1137	  cchRemaining = cchDest - cchDestLength;
1138	}
1139      }
1140      if(!pszSrc) pszSrc = "";
1141    } else {
1142      hr = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1143      if(NT_SUCCESS(hr)) {
1144	pszDestEnd = pszDest + cchDestLength;
1145	cchRemaining = cchDest - cchDestLength;
1146      }
1147    }
1148    if(NT_SUCCESS(hr)) {
1149      if(cchDest==0) {
1150	if(*pszSrc!='\0') {
1151	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1152	  else hr = STATUS_BUFFER_OVERFLOW;
1153	}
1154      } else hr = RtlStringCopyExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1155    }
1156  }
1157  if(!NT_SUCCESS(hr)) {
1158    if(pszDest) {
1159      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1160	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1161	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1162	  pszDestEnd = pszDest;
1163	  cchRemaining = cchDest;
1164	} else if(cchDest > 0) {
1165	  pszDestEnd = pszDest + cchDest - 1;
1166	  cchRemaining = 1;
1167	  *pszDestEnd = '\0';
1168	}
1169      }
1170      if(dwFlags & STRSAFE_NULL_ON_FAILURE) {
1171	if(cchDest > 0) {
1172	  pszDestEnd = pszDest;
1173	  cchRemaining = cchDest;
1174	  *pszDestEnd = '\0';
1175	}
1176      }
1177    }
1178  }
1179  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1180    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1181    if(pcchRemaining) *pcchRemaining = cchRemaining;
1182  }
1183  return hr;
1184}
1185
1186NTSTRSAFEDDI RtlStringCatExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
1187  NTSTATUS hr = STATUS_SUCCESS;
1188  NTSTRSAFE_PWSTR pszDestEnd = pszDest;
1189  size_t cchRemaining = 0;
1190  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1191  else {
1192    size_t cchDestLength;
1193    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1194      if(!pszDest) {
1195	if((cchDest==0) && (cbDest==0)) cchDestLength = 0;
1196	else hr = STATUS_INVALID_PARAMETER;
1197      } else {
1198	hr = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1199	if(NT_SUCCESS(hr)) {
1200	  pszDestEnd = pszDest + cchDestLength;
1201	  cchRemaining = cchDest - cchDestLength;
1202	}
1203      }
1204      if(!pszSrc) pszSrc = L"";
1205    } else {
1206      hr = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1207      if(NT_SUCCESS(hr)) {
1208	pszDestEnd = pszDest + cchDestLength;
1209	cchRemaining = cchDest - cchDestLength;
1210      }
1211    }
1212    if(NT_SUCCESS(hr)) {
1213      if(cchDest==0) {
1214	if(*pszSrc!=L'\0') {
1215	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1216	  else hr = STATUS_BUFFER_OVERFLOW;
1217	}
1218      } else hr = RtlStringCopyExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1219    }
1220  }
1221  if(!NT_SUCCESS(hr)) {
1222    if(pszDest) {
1223      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1224	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1225	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1226	  pszDestEnd = pszDest;
1227	  cchRemaining = cchDest;
1228	} else if(cchDest > 0) {
1229	  pszDestEnd = pszDest + cchDest - 1;
1230	  cchRemaining = 1;
1231	  *pszDestEnd = L'\0';
1232	}
1233      }
1234      if(dwFlags & STRSAFE_NULL_ON_FAILURE) {
1235	if(cchDest > 0) {
1236	  pszDestEnd = pszDest;
1237	  cchRemaining = cchDest;
1238	  *pszDestEnd = L'\0';
1239	}
1240      }
1241    }
1242  }
1243  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1244    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1245    if(pcchRemaining) *pcchRemaining = cchRemaining;
1246  }
1247  return hr;
1248}
1249
1250NTSTRSAFEDDI RtlStringCatNWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend) {
1251  NTSTATUS hr;
1252  size_t cchDestLength;
1253  hr = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1254  if(NT_SUCCESS(hr)) hr = RtlStringCopyNWorkerA(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend);
1255  return hr;
1256}
1257
1258NTSTRSAFEDDI RtlStringCatNWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend) {
1259  NTSTATUS hr;
1260  size_t cchDestLength;
1261  hr = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1262  if(NT_SUCCESS(hr)) hr = RtlStringCopyNWorkerW(pszDest + cchDestLength,cchDest - cchDestLength,pszSrc,cchToAppend);
1263  return hr;
1264}
1265
1266NTSTRSAFEDDI RtlStringCatNExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
1267  NTSTATUS hr = STATUS_SUCCESS;
1268  NTSTRSAFE_PSTR pszDestEnd = pszDest;
1269  size_t cchRemaining = 0;
1270  size_t cchDestLength = 0;
1271  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1272  else if(cchToAppend > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
1273  else {
1274    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1275      if(!pszDest) {
1276	if((cchDest==0) && (cbDest==0)) cchDestLength = 0;
1277	else hr = STATUS_INVALID_PARAMETER;
1278      } else {
1279	hr = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1280	if(NT_SUCCESS(hr)) {
1281	  pszDestEnd = pszDest + cchDestLength;
1282	  cchRemaining = cchDest - cchDestLength;
1283	}
1284      }
1285      if(!pszSrc) pszSrc = "";
1286    } else {
1287      hr = RtlStringLengthWorkerA(pszDest,cchDest,&cchDestLength);
1288      if(NT_SUCCESS(hr)) {
1289	pszDestEnd = pszDest + cchDestLength;
1290	cchRemaining = cchDest - cchDestLength;
1291      }
1292    }
1293    if(NT_SUCCESS(hr)) {
1294      if(cchDest==0) {
1295	if((cchToAppend!=0) && (*pszSrc!='\0')) {
1296	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1297	  else hr = STATUS_BUFFER_OVERFLOW;
1298	}
1299      } else hr = RtlStringCopyNExWorkerA(pszDestEnd,cchRemaining,(cchRemaining*sizeof(char)) + (cbDest % sizeof(char)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1300    }
1301  }
1302  if(!NT_SUCCESS(hr)) {
1303    if(pszDest) {
1304      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1305	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1306	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1307	  pszDestEnd = pszDest;
1308	  cchRemaining = cchDest;
1309	} else if(cchDest > 0) {
1310	  pszDestEnd = pszDest + cchDest - 1;
1311	  cchRemaining = 1;
1312	  *pszDestEnd = '\0';
1313	}
1314      }
1315      if(dwFlags & (STRSAFE_NULL_ON_FAILURE)) {
1316	if(cchDest > 0) {
1317	  pszDestEnd = pszDest;
1318	  cchRemaining = cchDest;
1319	  *pszDestEnd = '\0';
1320	}
1321      }
1322    }
1323  }
1324  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1325    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1326    if(pcchRemaining) *pcchRemaining = cchRemaining;
1327  }
1328  return hr;
1329}
1330
1331NTSTRSAFEDDI RtlStringCatNExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PCWSTR pszSrc,size_t cchToAppend,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags) {
1332  NTSTATUS hr = STATUS_SUCCESS;
1333  NTSTRSAFE_PWSTR pszDestEnd = pszDest;
1334  size_t cchRemaining = 0;
1335  size_t cchDestLength = 0;
1336  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1337  else if(cchToAppend > NTSTRSAFE_MAX_CCH) hr = STATUS_INVALID_PARAMETER;
1338  else {
1339    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1340      if(!pszDest) {
1341	if((cchDest==0) && (cbDest==0)) cchDestLength = 0;
1342	else hr = STATUS_INVALID_PARAMETER;
1343      } else {
1344	hr = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1345	if(NT_SUCCESS(hr)) {
1346	  pszDestEnd = pszDest + cchDestLength;
1347	  cchRemaining = cchDest - cchDestLength;
1348	}
1349      }
1350      if(!pszSrc) pszSrc = L"";
1351    } else {
1352      hr = RtlStringLengthWorkerW(pszDest,cchDest,&cchDestLength);
1353      if(NT_SUCCESS(hr)) {
1354	pszDestEnd = pszDest + cchDestLength;
1355	cchRemaining = cchDest - cchDestLength;
1356      }
1357    }
1358    if(NT_SUCCESS(hr)) {
1359      if(cchDest==0) {
1360	if((cchToAppend!=0) && (*pszSrc!=L'\0')) {
1361	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1362	  else hr = STATUS_BUFFER_OVERFLOW;
1363	}
1364      } else hr = RtlStringCopyNExWorkerW(pszDestEnd,cchRemaining,(cchRemaining*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)),pszSrc,cchToAppend,&pszDestEnd,&cchRemaining,dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)));
1365    }
1366  }
1367  if(!NT_SUCCESS(hr)) {
1368    if(pszDest) {
1369      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1370	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1371	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1372	  pszDestEnd = pszDest;
1373	  cchRemaining = cchDest;
1374	} else if(cchDest > 0) {
1375	  pszDestEnd = pszDest + cchDest - 1;
1376	  cchRemaining = 1;
1377	  *pszDestEnd = L'\0';
1378	}
1379      }
1380      if(dwFlags & (STRSAFE_NULL_ON_FAILURE)) {
1381	if(cchDest > 0) {
1382	  pszDestEnd = pszDest;
1383	  cchRemaining = cchDest;
1384	  *pszDestEnd = L'\0';
1385	}
1386      }
1387    }
1388  }
1389  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1390    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1391    if(pcchRemaining) *pcchRemaining = cchRemaining;
1392  }
1393  return hr;
1394}
1395
1396NTSTRSAFEDDI RtlStringVPrintfWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,NTSTRSAFE_PCSTR pszFormat,va_list argList) {
1397  NTSTATUS hr = STATUS_SUCCESS;
1398  if(cchDest==0) hr = STATUS_INVALID_PARAMETER;
1399  else {
1400    int iRet;
1401    size_t cchMax;
1402    cchMax = cchDest - 1;
1403    iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList);
1404    if((iRet < 0) || (((size_t)iRet) > cchMax)) {
1405      pszDest += cchMax;
1406      *pszDest = '\0';
1407      hr = STATUS_BUFFER_OVERFLOW;
1408    } else if(((size_t)iRet)==cchMax) {
1409      pszDest += cchMax;
1410      *pszDest = '\0';
1411    }
1412  }
1413  return hr;
1414}
1415
1416NTSTRSAFEDDI RtlStringVPrintfWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,NTSTRSAFE_PCWSTR pszFormat,va_list argList) {
1417  NTSTATUS hr = STATUS_SUCCESS;
1418  if(cchDest==0) hr = STATUS_INVALID_PARAMETER;
1419  else {
1420    int iRet;
1421    size_t cchMax;
1422    cchMax = cchDest - 1;
1423    iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList);
1424    if((iRet < 0) || (((size_t)iRet) > cchMax)) {
1425      pszDest += cchMax;
1426      *pszDest = L'\0';
1427      hr = STATUS_BUFFER_OVERFLOW;
1428    } else if(((size_t)iRet)==cchMax) {
1429      pszDest += cchMax;
1430      *pszDest = L'\0';
1431    }
1432  }
1433  return hr;
1434}
1435
1436NTSTRSAFEDDI RtlStringVPrintfExWorkerA(NTSTRSAFE_PSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCSTR pszFormat,va_list argList) {
1437  NTSTATUS hr = STATUS_SUCCESS;
1438  NTSTRSAFE_PSTR pszDestEnd = pszDest;
1439  size_t cchRemaining = 0;
1440  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1441  else {
1442    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1443      if(!pszDest) {
1444	if((cchDest!=0) || (cbDest!=0)) hr = STATUS_INVALID_PARAMETER;
1445      }
1446      if(!pszFormat) pszFormat = "";
1447    }
1448    if(NT_SUCCESS(hr)) {
1449      if(cchDest==0) {
1450	pszDestEnd = pszDest;
1451	cchRemaining = 0;
1452	if(*pszFormat!='\0') {
1453	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1454	  else hr = STATUS_BUFFER_OVERFLOW;
1455	}
1456      } else {
1457	int iRet;
1458	size_t cchMax;
1459	cchMax = cchDest - 1;
1460	iRet = _vsnprintf(pszDest,cchMax,pszFormat,argList);
1461	if((iRet < 0) || (((size_t)iRet) > cchMax)) {
1462	  pszDestEnd = pszDest + cchMax;
1463	  cchRemaining = 1;
1464	  *pszDestEnd = '\0';
1465	  hr = STATUS_BUFFER_OVERFLOW;
1466	} else if(((size_t)iRet)==cchMax) {
1467	  pszDestEnd = pszDest + cchMax;
1468	  cchRemaining = 1;
1469	  *pszDestEnd = '\0';
1470	} else if(((size_t)iRet) < cchMax) {
1471	  pszDestEnd = pszDest + iRet;
1472	  cchRemaining = cchDest - iRet;
1473	  if(dwFlags & STRSAFE_FILL_BEHIND_NULL) {
1474	    memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(char)) + (cbDest % sizeof(char)));
1475	  }
1476	}
1477      }
1478    }
1479  }
1480  if(!NT_SUCCESS(hr)) {
1481    if(pszDest) {
1482      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1483	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1484	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1485	  pszDestEnd = pszDest;
1486	  cchRemaining = cchDest;
1487	} else if(cchDest > 0) {
1488	  pszDestEnd = pszDest + cchDest - 1;
1489	  cchRemaining = 1;
1490	  *pszDestEnd = '\0';
1491	}
1492      }
1493      if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) {
1494	if(cchDest > 0) {
1495	  pszDestEnd = pszDest;
1496	  cchRemaining = cchDest;
1497	  *pszDestEnd = '\0';
1498	}
1499      }
1500    }
1501  }
1502  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1503    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1504    if(pcchRemaining) *pcchRemaining = cchRemaining;
1505  }
1506  return hr;
1507}
1508
1509NTSTRSAFEDDI RtlStringVPrintfExWorkerW(NTSTRSAFE_PWSTR pszDest,size_t cchDest,size_t cbDest,NTSTRSAFE_PWSTR *ppszDestEnd,size_t *pcchRemaining,unsigned __LONG32 dwFlags,NTSTRSAFE_PCWSTR pszFormat,va_list argList) {
1510  NTSTATUS hr = STATUS_SUCCESS;
1511  NTSTRSAFE_PWSTR pszDestEnd = pszDest;
1512  size_t cchRemaining = 0;
1513  if(dwFlags & (~STRSAFE_VALID_FLAGS)) hr = STATUS_INVALID_PARAMETER;
1514  else {
1515    if(dwFlags & STRSAFE_IGNORE_NULLS) {
1516      if(!pszDest) {
1517	if((cchDest!=0) || (cbDest!=0)) hr = STATUS_INVALID_PARAMETER;
1518      }
1519      if(!pszFormat) pszFormat = L"";
1520    }
1521    if(NT_SUCCESS(hr)) {
1522      if(cchDest==0) {
1523	pszDestEnd = pszDest;
1524	cchRemaining = 0;
1525	if(*pszFormat!=L'\0') {
1526	  if(!pszDest) hr = STATUS_INVALID_PARAMETER;
1527	  else hr = STATUS_BUFFER_OVERFLOW;
1528	}
1529      } else {
1530	int iRet;
1531	size_t cchMax;
1532	cchMax = cchDest - 1;
1533	iRet = _vsnwprintf(pszDest,cchMax,pszFormat,argList);
1534	if((iRet < 0) || (((size_t)iRet) > cchMax)) {
1535	  pszDestEnd = pszDest + cchMax;
1536	  cchRemaining = 1;
1537	  *pszDestEnd = L'\0';
1538	  hr = STATUS_BUFFER_OVERFLOW;
1539	} else if(((size_t)iRet)==cchMax) {
1540	  pszDestEnd = pszDest + cchMax;
1541	  cchRemaining = 1;
1542	  *pszDestEnd = L'\0';
1543	} else if(((size_t)iRet) < cchMax) {
1544	  pszDestEnd = pszDest + iRet;
1545	  cchRemaining = cchDest - iRet;
1546	  if(dwFlags & STRSAFE_FILL_BEHIND_NULL) {
1547	    memset(pszDestEnd + 1,STRSAFE_GET_FILL_PATTERN(dwFlags),((cchRemaining - 1)*sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
1548	  }
1549	}
1550      }
1551    }
1552  }
1553  if(!NT_SUCCESS(hr)) {
1554    if(pszDest) {
1555      if(dwFlags & STRSAFE_FILL_ON_FAILURE) {
1556	memset(pszDest,STRSAFE_GET_FILL_PATTERN(dwFlags),cbDest);
1557	if(STRSAFE_GET_FILL_PATTERN(dwFlags)==0) {
1558	  pszDestEnd = pszDest;
1559	  cchRemaining = cchDest;
1560	} else if(cchDest > 0) {
1561	  pszDestEnd = pszDest + cchDest - 1;
1562	  cchRemaining = 1;
1563	  *pszDestEnd = L'\0';
1564	}
1565      }
1566      if(dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) {
1567	if(cchDest > 0) {
1568	  pszDestEnd = pszDest;
1569	  cchRemaining = cchDest;
1570	  *pszDestEnd = L'\0';
1571	}
1572      }
1573    }
1574  }
1575  if(NT_SUCCESS(hr) || (hr==STATUS_BUFFER_OVERFLOW)) {
1576    if(ppszDestEnd) *ppszDestEnd = pszDestEnd;
1577    if(pcchRemaining) *pcchRemaining = cchRemaining;
1578  }
1579  return hr;
1580}
1581
1582NTSTRSAFEDDI RtlStringLengthWorkerA(NTSTRSAFE_PCSTR psz,size_t cchMax,size_t *pcchLength) {
1583  NTSTATUS hr = STATUS_SUCCESS;
1584  size_t cchMaxPrev = cchMax;
1585  while(cchMax && (*psz!='\0')) {
1586    psz++;
1587    cchMax--;
1588  }
1589  if(cchMax==0) hr = STATUS_INVALID_PARAMETER;
1590  if(pcchLength) {
1591    if(NT_SUCCESS(hr)) *pcchLength = cchMaxPrev - cchMax;
1592    else *pcchLength = 0;
1593  }
1594  return hr;
1595}
1596
1597NTSTRSAFEDDI RtlStringLengthWorkerW(NTSTRSAFE_PCWSTR psz,size_t cchMax,size_t *pcchLength) {
1598  NTSTATUS hr = STATUS_SUCCESS;
1599  size_t cchMaxPrev = cchMax;
1600  while(cchMax && (*psz!=L'\0')) {
1601    psz++;
1602    cchMax--;
1603  }
1604  if(cchMax==0) hr = STATUS_INVALID_PARAMETER;
1605  if(pcchLength) {
1606    if(NT_SUCCESS(hr)) *pcchLength = cchMaxPrev - cchMax;
1607    else *pcchLength = 0;
1608  }
1609  return hr;
1610}
1611
1612#endif /* !__STRSAFE__NO_INLINE */
1613
1614#define RtlStringCopyWorkerA RtlStringCopyWorkerA_instead_use_RtlStringCchCopyA_or_RtlStringCchCopyExA;
1615#define RtlStringCopyWorkerW RtlStringCopyWorkerW_instead_use_RtlStringCchCopyW_or_RtlStringCchCopyExW;
1616#define RtlStringCopyExWorkerA RtlStringCopyExWorkerA_instead_use_RtlStringCchCopyA_or_RtlStringCchCopyExA;
1617#define RtlStringCopyExWorkerW RtlStringCopyExWorkerW_instead_use_RtlStringCchCopyW_or_RtlStringCchCopyExW;
1618#define RtlStringCatWorkerA RtlStringCatWorkerA_instead_use_RtlStringCchCatA_or_RtlStringCchCatExA;
1619#define RtlStringCatWorkerW RtlStringCatWorkerW_instead_use_RtlStringCchCatW_or_RtlStringCchCatExW;
1620#define RtlStringCatExWorkerA RtlStringCatExWorkerA_instead_use_RtlStringCchCatA_or_RtlStringCchCatExA;
1621#define RtlStringCatExWorkerW RtlStringCatExWorkerW_instead_use_RtlStringCchCatW_or_RtlStringCchCatExW;
1622#define RtlStringCatNWorkerA RtlStringCatNWorkerA_instead_use_RtlStringCchCatNA_or_StrincCbCatNA;
1623#define RtlStringCatNWorkerW RtlStringCatNWorkerW_instead_use_RtlStringCchCatNW_or_RtlStringCbCatNW;
1624#define RtlStringCatNExWorkerA RtlStringCatNExWorkerA_instead_use_RtlStringCchCatNExA_or_RtlStringCbCatNExA;
1625#define RtlStringCatNExWorkerW RtlStringCatNExWorkerW_instead_use_RtlStringCchCatNExW_or_RtlStringCbCatNExW;
1626#define RtlStringVPrintfWorkerA RtlStringVPrintfWorkerA_instead_use_RtlStringCchVPrintfA_or_RtlStringCchVPrintfExA;
1627#define RtlStringVPrintfWorkerW RtlStringVPrintfWorkerW_instead_use_RtlStringCchVPrintfW_or_RtlStringCchVPrintfExW;
1628#define RtlStringVPrintfExWorkerA RtlStringVPrintfExWorkerA_instead_use_RtlStringCchVPrintfA_or_RtlStringCchVPrintfExA;
1629#define RtlStringVPrintfExWorkerW RtlStringVPrintfExWorkerW_instead_use_RtlStringCchVPrintfW_or_RtlStringCchVPrintfExW;
1630#define RtlStringLengthWorkerA RtlStringLengthWorkerA_instead_use_RtlStringCchLengthA_or_RtlStringCbLengthA;
1631#define RtlStringLengthWorkerW RtlStringLengthWorkerW_instead_use_RtlStringCchLengthW_or_RtlStringCbLengthW;
1632
1633#endif