text: #include <winapifamily.h>
  
  /*++
  
  Copyright (c) 2000  Microsoft Corporation
  
  Module Name:
  
      stralign.h
  
  Abstract:
  
      This module contains macros and prototypes to expose the unaligned wide
      character interfaces.
  
      Public interfaces created or declared here include:
  
      ua_CharUpper()
      ua_CharUpperW()
      ua_lstrcmp()
      ua_lstrcmpW()
      ua_lstrcmpi()
      ua_lstrcmpiW()
      ua_lstrlen()
      ua_lstrlenW()
      ua_tcscpy()
      ua_tcscpy_s()
      ua_wcschr()
      ua_wcscpy()
      ua_wcscpy_s()
      ua_wcsicmp()
      ua_wcslen()
      ua_wcsrchr()
  
      STRUC_ALIGNED_STACK_COPY()
      TSTR_ALIGNED()
      TSTR_ALIGNED_STACK_COPY()
      WSTR_ALIGNED()
      WSTR_ALIGNED_STACK_COPY()
  
  Author:
  
  --*/
  
  #if !defined(__STRALIGN_H_) && !defined(MIDL_PASS)
  #define __STRALIGN_H_
  
  #ifndef _STRALIGN_USE_SECURE_CRT
  #if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L
  #define _STRALIGN_USE_SECURE_CRT 1
  #else
  #define _STRALIGN_USE_SECURE_CRT 0
  #endif
  #endif
  
  #if !defined(_WINDOWS_INSECURE_DEPRECATE)
  #if defined(_WINDOWS_SECURE_NO_DEPRECATE) || !_STRALIGN_USE_SECURE_CRT
  #define _WINDOWS_INSECURE_DEPRECATE
  #else
  #define _WINDOWS_INSECURE_DEPRECATE __declspec(deprecated)
  #endif
  #endif
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  #pragma region Desktop Family
  #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  
  //
  // N.B. On AMD64 platforms the key word __unaligned is enabled, but has no
  //      effect and strings can be unaligned exactly as they are on the x86.
  //      Therefore, all AMD64 alignment macros are forced to produce values
  //      that make the subject arguments appear as it they are aligned.
  //
  //      On ARM platforms, the operation is similar.
  //
  
  #if defined(_AMD64_) || defined(_ARM_)
  #pragma warning(push)
  #pragma warning(disable:4127)
  #endif
  
  #if defined(_X86_)
  
  //
  // Alignment of unicode strings is not necessary on X86.
  //
  
  #define WSTR_ALIGNED(s) TRUE
  
  #define ua_CharUpperW CharUpperW
  #define ua_lstrcmpiW  lstrcmpiW
  #define ua_lstrcmpW   lstrcmpW
  #define ua_lstrlenW   lstrlenW
  #define ua_wcschr     wcschr
  #define ua_wcsicmp    wcsicmp
  #define ua_wcslen     wcslen
  #define ua_wcsrchr    wcsrchr
  #if _STRALIGN_USE_SECURE_CRT
  #define ua_wcscpy_s   wcscpy_s
  #endif
  
  __inline
  PUWSTR
  static
  _WINDOWS_INSECURE_DEPRECATE
  ua_wcscpy(
      _Out_writes_(_Inexpressible_("Sufficient length")) PUWSTR  Destination,
      _In_ PCUWSTR Source
      )
  {
  #pragma warning(push)
  #pragma warning(disable:4995)
  #pragma warning(disable:4996)
  #ifdef _PREFAST_
  #pragma warning(disable:28719) // This function (ua_wcscpy) is also tagged as insecure and deprecated
  #endif // _PREFAST_
      return wcscpy(Destination, Source);
  #pragma warning(pop)
  }
  
  #else
  
  //
  // The C runtime libraries expect aligned string pointers.  Following are the
  // prototypes for our own, slower worker functions that accept unaligned
  // UNICODE strings.
  //
  // Macro to determine whether a pointer to a unicode character is naturally
  // aligned.
  //
  
  #if defined(_AMD64_) || defined(_ARM_)
  
  #define WSTR_ALIGNED(s) TRUE
  
  #else
  
  #define WSTR_ALIGNED(s) (((DWORD_PTR)(s) & (sizeof(WCHAR)-1)) == 0)
  
  #endif
  
  //
  // Platform-specific prototypes for worker functions exported from kernel32.
  // Do not call these directly, they do not exist on all platforms.  Instead
  // use the equivalent ua_xxx() routines.
  //
  
  LPUWSTR
  WINAPI
  uaw_CharUpperW(
      _Inout_ LPUWSTR String
      );
  
  int
  APIENTRY
  uaw_lstrcmpW(
      _In_ PCUWSTR String1,
      _In_ PCUWSTR String2
      );
  
  int
  APIENTRY
  uaw_lstrcmpiW(
      _In_ PCUWSTR String1,
      _In_ PCUWSTR String2
      );
  
  int
  WINAPI
  uaw_lstrlenW(
      _In_ LPCUWSTR String
      );
  
  PUWSTR
  __cdecl
  uaw_wcschr(
      _In_ PCUWSTR String,
      _In_ WCHAR   Character
      );
  
  PUWSTR
  __cdecl
  uaw_wcscpy(
      _Out_writes_(_Inexpressible_("Sufficient length")) PUWSTR  Destination,
      _In_  PCUWSTR Source
      );
  
  int
  __cdecl
  uaw_wcsicmp(
      _In_ PCUWSTR String1,
      _In_ PCUWSTR String2
      );
  
  size_t
  __cdecl
  uaw_wcslen(
      _In_ PCUWSTR String
      );
  
  PUWSTR
  __cdecl
  uaw_wcsrchr(
      _In_ PCUWSTR String,
      _In_ WCHAR   Character
      );
  
  //
  // Following are the inline wrappers that determine the optimal worker function
  // to call based on the alignment of the UNICODE string arguments.  Their
  // behavior is otherwise identical to the corresponding standard run-time
  // routiunes.
  //
  
  #if defined(CharUpper)
  __inline
  LPUWSTR
  static
  ua_CharUpperW(
      _Inout_ LPUWSTR String
      )
  {
      if (WSTR_ALIGNED(String)) {
          return CharUpperW( (PWSTR)String );
      } else {
          return uaw_CharUpperW( String );
      }
  }
  #endif
  
  #if defined(lstrcmp)
  __inline
  int
  static
  ua_lstrcmpW(
      _In_ LPCUWSTR String1,
      _In_ LPCUWSTR String2
      )
  {
      if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
          return lstrcmpW( (LPCWSTR)String1, (LPCWSTR)String2);
      } else {
          return uaw_lstrcmpW( String1, String2 );
      }
  }
  #endif
  
  #if defined(lstrcmpi)
  __inline
  int
  static
  ua_lstrcmpiW(
      _In_ LPCUWSTR String1,
      _In_ LPCUWSTR String2
      )
  {
      if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
          return lstrcmpiW( (LPCWSTR)String1, (LPCWSTR)String2 );
      } else {
          return uaw_lstrcmpiW( String1, String2 );
      }
  }
  #endif
  
  #if defined(lstrlen)
  __inline
  int
  static
  ua_lstrlenW(
      _In_ LPCUWSTR String
      )
  {
      if (WSTR_ALIGNED(String)) {
  #pragma warning(suppress: 28750) // use of deprecated API
          return lstrlenW( (PCWSTR)String );
      } else {
          return uaw_lstrlenW( String );
      }
  }
  #endif
  
  #if defined(_WSTRING_DEFINED)
  
  //
  // Certain run-time string functions are overloaded in C++, to avoid
  // inadvertent stripping of the const attribute.
  //
  // The functions of interest here include: wcschr and wcsrchr.
  //
  // There are three flavors of these functions:
  //
  // Flavor  Returns    Parameter
  //
  // 1       PWSTR      PCWSTR
  // 2       PCWSTR     PCWSTR
  // 3       PWSTR      PWSTR
  //
  // string.h declares flavor 1 whether for C or C++.  This is the non-ANSI,
  // backward compatible mode.
  //
  // wchar.h declares flavor 1 if C, or flavors 2 and 3 if C++.  This is the
  // ANSI method.
  //
  // Our corresponding functions need to match what was declared.  The way
  // we can tell is by looking at _WConst_return... if it is defined then
  // we want to match the prototypes in wchar.h, otherwise we'll match
  // the prototypes in string.h.
  //
  
  #if defined(_WConst_return)
  typedef _WConst_return WCHAR UNALIGNED *PUWSTR_C;
  #else
  typedef WCHAR UNALIGNED *PUWSTR_C;
  #endif
  
  //
  // Here is flavor 1 or 2
  //
  
  __inline
  PUWSTR_C
  static
  ua_wcschr(
      _In_ PCUWSTR String,
      _In_ WCHAR   Character
      )
  {
      if (WSTR_ALIGNED(String)) {
          return wcschr((PCWSTR)String, Character);
      } else {
          return (PUWSTR_C)uaw_wcschr(String, Character);
      }
  }
  
  __inline
  PUWSTR_C
  static
  ua_wcsrchr(
      _In_ PCUWSTR String,
      _In_ WCHAR   Character
      )
  {
      if (WSTR_ALIGNED(String)) {
          return wcsrchr((PCWSTR)String, Character);
      } else {
          return (PUWSTR_C)uaw_wcsrchr(String, Character);
      }
  }
  
  #if defined(__cplusplus) && defined(_WConst_Return)
  
  //
  // Here is flavor 3
  //
  
  __inline
  PUWSTR
  static
  _WINDOWS_INSECURE_DEPRECATE
  ua_wcschr(
      _In_ PUWSTR String,
      _In_ WCHAR  Character
      )
  {
      if (WSTR_ALIGNED(String)) {
  #pragma warning(push)
  #pragma warning(disable:4995)
  #pragma warning(disable:4996)
          return wcscpy( (PWSTR)Destination, (PCWSTR)Source );
  #pragma warning(pop)
      } else {
          return uaw_wcscpy( Destination, Source );
      }
  }
  
  __inline
  PUWSTR
  static
  ua_wcscpy_s(
      _Out_writes_(DestinationSize) PUWSTR  Destination,
      _In_ size_t  DestinationSize,
      _In_ PCUWSTR Source
      )
  {
      if (WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) {
          return (wcscpy_s( (PWSTR)Destination, DestinationSize, (PCWSTR)Source ) == 0 ? Destination : NULL);
      } else {
          /* */
          return uaw_wcscpy((PCUWSTR)String, Character);
      }
  }
  
  __inline
  PUWSTR
  static
  ua_wcsrchr(
      _In_ PUWSTR String,
      _In_ WCHAR  Character
      )
  {
      if (WSTR_ALIGNED(String)) {
          return wcsrchr(String, Character);
      } else {
          return uaw_wcsrchr((PCUWSTR)String, Character);
      }
  }
  
  #endif  // __cplusplus && _WConst_Return
  
  __inline
  PUWSTR
  static
  _WINDOWS_INSECURE_DEPRECATE
  ua_wcscpy(
      _Out_writes_(_Inexpressible_("Sufficient length")) PUWSTR  Destination,
      _In_ PCUWSTR Source
      )
  {
      if (WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) {
  #pragma warning(push)
  #pragma warning(disable:4995)
  #pragma warning(disable:4996)
  #ifdef _PREFAST_
  #pragma warning(disable:28719) // This function (ua_wcscpy) is also tagged as insecure and deprecated
  #endif // _PREFAST_
          return wcscpy( (PWSTR)Destination, (PCWSTR)Source );
  #pragma warning(pop)
      } else {
          return uaw_wcscpy( Destination, Source );
      }
  }
  
  
  #if _STRALIGN_USE_SECURE_CRT
  __inline
  PUWSTR
  static
  ua_wcscpy_s(
      _Out_writes_(DestinationSize) PUWSTR Destination,
      _In_ size_t  DestinationSize,
      _In_ PCUWSTR Source
      )
  {
      if (WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) {
          return (wcscpy_s( (PWSTR)Destination, DestinationSize, (PCWSTR)Source ) == 0 ? Destination : NULL);
      } else {
          /* */
          return uaw_wcscpy( Destination, Source );
      }
  }
  #endif
  
  __inline
  size_t
  static
  ua_wcslen(
      _In_ PCUWSTR String
      )
  {
      if (WSTR_ALIGNED(String)) {
          return wcslen( (PCWSTR)String );
      } else {
          return uaw_wcslen( String );
      }
  }
  
  #endif  // _WSTRING_DEFINED
  
  __inline
  int
  static
  ua_wcsicmp(
      _In_ PCUWSTR String1,
      _In_ PCUWSTR String2
      )
  {
      if (WSTR_ALIGNED(String1) && WSTR_ALIGNED(String2)) {
          return _wcsicmp( (LPCWSTR)String1, (LPCWSTR)String2 );
      } else {
          return uaw_wcsicmp( String1, String2 );
      }
  }
  
  #endif  // _X86_
  
  //++
  //
  // VOID
  // WSTR_ALIGNED_STACK_COPY (
  //    _Out_ PCWSTR *TargetString,
  //    _In_opt_  PCUWSTR SourceString
  //    )
  //
  // VOID
  // TSTR_ALIGNED_STACK_COPY (
  //    _Out_ PCTSTR *TargetString,
  //    _In_opt_  PCUTSTR SourceString
  //    )
  //
  // Routine Description:
  //
  //    These macros set TargetString to an aligned pointer to the string
  //    represented by SourceString.  If necessary, an aligned copy of
  //    SourceString is copied onto the stack.
  //
  // Arguments:
  //
  //    TargetString - Supplies a pointer to a pointer to the resultant
  //                   string.  This may be the same as SourceString if
  //                   that argument is aligned.
  //
  //    SourceString - Supplies a pointer to the possibly unaligned UNICODE
  //                   string.
  //
  // Return Value:
  //
  //    None.
  //
  // Note:
  //
  //    These macros may allocate memory on the stack via the CRT function
  //    _alloca().  This memory is "freed" when the calling function exits.
  //    As a result, do not use these macros inside of a loop that may execute
  //    a large number of times - instead, use a wrapper function, or use
  //    an explicit buffer like this:
  //
  //    TCHAR AlignedStringBuffer[ MAX_FOOSTR_CHARS ];
  //    PTSTR AlignedString;
  //
  //    while (a < b) {
  //        ...
  //        if (TSTR_ALIGNED(s) {
  //            AlignedString = s;
  //        } else {
  //            AlignedString = (PTSTR)ua_tcscpy(AlignedStringBuffer,s);
  //        }
  //        SomeSystemFunction(AlignedString);
  //        ...
  //    }
  //
  //
  //--
  
  //
  // __UA_WSTRSIZE returns the number of bytes required to store the
  // supplied null-terminated UNICODE string.
  //
  // __UA_LOCALCOPY accepts a pointer to unaligned data and a size.  It
  // allocates an aligned buffer on the stack and copies the data into
  // it, returning a pointer to the buffer.
  //
  
  #if !defined(__UA_WCSLEN)
  #define __UA_WCSLEN ua_wcslen
  #endif
  
  #define __UA_WSTRSIZE(s)    ((__UA_WCSLEN(s)+1)*sizeof(WCHAR))
  #define __UA_STACKCOPY(p,s) memcpy_s(_alloca(s),s,p,s)
  
  //
  // Note that NULL is aligned.
  //
  
  #if defined(_AMD64_) || defined(_ARM_) || defined(_X86_)
  
  #define WSTR_ALIGNED_STACK_COPY(d,s) (*(d) = (PCWSTR)(s))
  
  #else
  
  //
  // Use of an inline function here is not possible, as the results of
  // the _alloca() will not be preserved upon return from the function.
  //
  
  #define WSTR_ALIGNED_STACK_COPY(d,s)                                \
      {                                                               \
          PCUWSTR __ua_src;                                           \
          size_t  __ua_size;                                          \
          PWSTR  __ua_dst;                                            \
                                                                      \
          __ua_src = (s);                                             \
          if (WSTR_ALIGNED(__ua_src)) {                               \
              __ua_dst = (PWSTR)__ua_src;                             \
          } else {                                                    \
              __ua_size = __UA_WSTRSIZE(__ua_src);                    \
              __ua_dst = (PWSTR)_alloca(__ua_size);                   \
              memcpy_s(__ua_dst,__ua_size,__ua_src,__ua_size);          \
          }                                                           \
          *(d) = (PCWSTR)__ua_dst;                                    \
      }
  
  #endif
  
  #define ASTR_ALIGNED_STACK_COPY(d,s) (*(d) = (PCSTR)(s))
  
  //++
  //
  // <type> CONST *
  // STRUC_ALIGNED_STACK_COPY (
  //     _In_ <type name>,
  //     _In_opt_ PVOID Struc
  //     )
  //
  // Routine Description:
  //
  //    This macro returns an aligned pointer to Struc, creating a local
  //    copy on the stack if necessary.
  //
  //    This should be used only for relatively small structures, and efforts
  //    should be made to align the structure properly in the first place.  Use
  //    this macro only as a last resort.
  //
  // Arguments:
  //
  //    <type> - The type specifier of Struc
  //
  //    Struc - Supplies a pointer to the structure in question.
  //
  // Return Value:
  //
  //    Returns a const pointer to Struc if it is properly aligned, or a pointer
  //    to a stack-allocated copy of Struc if it is not.
  //
  //--
  
  #if !defined(_AMD64_) && !defined(_ARM_) && !defined(_X86_)
  
  #define __UA_STRUC_ALIGNED(t,s) \
      (((DWORD_PTR)(s) & (TYPE_ALIGNMENT(t)-1)) == 0)
  
  #define STRUC_ALIGNED_STACK_COPY(t,s) \
      __UA_STRUC_ALIGNED(t,s) ?   \
          ((t const *)(s)) :      \
          ((t const *)__UA_STACKCOPY((s),sizeof(t)))
  
  #else
  
  #define STRUC_ALIGNED_STACK_COPY(t,s) ((CONST t *)(s))
  
  #endif
  
  #if defined(UNICODE)
  
  #define TSTR_ALIGNED_STACK_COPY(d,s)    WSTR_ALIGNED_STACK_COPY(d,s)
  #define TSTR_ALIGNED(x)                 WSTR_ALIGNED(x)
  #define ua_CharUpper                    ua_CharUpperW
  #define ua_lstrcmp                      ua_lstrcmpW
  #define ua_lstrcmpi                     ua_lstrcmpiW
  #define ua_lstrlen                      ua_lstrlenW
  #define ua_tcscpy                       ua_wcscpy
  #if _STRALIGN_USE_SECURE_CRT
  #define ua_tcscpy_s                     ua_wcscpy_s
  #endif
  
  #else
  
  #define TSTR_ALIGNED_STACK_COPY(d,s)    ASTR_ALIGNED_STACK_COPY(d,s)
  #define TSTR_ALIGNED(x)                 TRUE
  #define ua_CharUpper                    CharUpperA
  #define ua_lstrcmp                      lstrcmpA
  #define ua_lstrcmpi                     lstrcmpiA
  #define ua_lstrlen                      lstrlenA
  #define ua_tcscpy                       strcpy
  #if _STRALIGN_USE_SECURE_CRT
  #define ua_tcscpy_s                     strcpy_s
  #endif
  
  #endif  // UNICODE
  
  #if defined(_AMD64_) || defined(_ARM_)
  #pragma warning(pop)
  #endif
  
  #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
  #pragma endregion
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif  // __STRALIGN_H_
  
  
  
  
  
  
  
  
  