Просмотр исходного кода

Remove dead code and clean up multisz/a and stringa (#58373)

Aditya Mandaleeka 1 год назад
Родитель
Сommit
70ace17217

+ 0 - 1
src/Servers/IIS/AspNetCoreModuleV2/IISLib/acache.cpp

@@ -429,7 +429,6 @@ Finished:
 
     if ( fLockedHeap )
     {
-        fLockedHeap = FALSE;
         DBG_REQUIRE( ::HeapUnlock( hHeap ) );
     }
 

+ 0 - 173
src/Servers/IIS/AspNetCoreModuleV2/IISLib/multisz.cpp

@@ -7,12 +7,7 @@
 #include "precomp.h"
 #include "multisz.h"
 
-//
-//  Private Definitions
-//
-
 #define MAXULONG 4294967295
-#define ISWHITE( ch )       ((ch) == L' ' || (ch) == L'\t' || (ch) == L'\r')
 
 //
 //  When appending data, this is the extra amount we request to avoid
@@ -44,74 +39,6 @@ MULTISZ::CalcLength( const WCHAR * str,
 }   // MULTISZ::CalcLength
 
 
-BOOL
-MULTISZ::FindString( const WCHAR * str ) const
-{
-    //
-    // Sanity check.
-    //
-
-    DBG_ASSERT( QueryStr() != nullptr );
-    DBG_ASSERT( str != nullptr );
-    DBG_ASSERT( *str != '\0' );
-
-    //
-    // Scan it.
-    //
-
-    WCHAR* multisz = QueryStr();
-
-    while( *multisz != '\0' ) {
-
-        if( !::wcscmp( multisz, str ) ) {
-
-            return TRUE;
-
-        }
-
-        multisz += ::wcslen( multisz ) + 1;
-
-    }
-
-    return FALSE;
-
-}   // MULTISZ::FindString
-
-
-BOOL
-MULTISZ::FindStringNoCase( const WCHAR * str ) const
-{
-    //
-    // Sanity check.
-    //
-
-    DBG_ASSERT( QueryStr() != nullptr );
-    DBG_ASSERT( str != nullptr );
-    DBG_ASSERT( *str != '\0' );
-
-    //
-    // Scan it.
-    //
-
-    WCHAR* multisz = QueryStr();
-
-    while( *multisz != '\0' ) {
-
-        if( !_wcsicmp( multisz, str ) ) {
-
-            return TRUE;
-
-        }
-
-        multisz += wcslen( multisz ) + 1;
-
-    }
-
-    return FALSE;
-
-}   // MULTISZ::FindStringNoCase
-
-
 VOID
 MULTISZ::AuxInit( const WCHAR * pInit )
 {
@@ -361,104 +288,4 @@ MULTISZ::Equals(
     return TRUE;
 }
 
-HRESULT
-SplitCommaDelimitedString(
-    PCWSTR                      pszList,
-    BOOL                        fTrimEntries,
-    BOOL                        fRemoveEmptyEntries,
-    MULTISZ *                   pmszList
-)
-/*++
-
-Routine Description:
-
-    Split comma delimited string into a multisz. Additional leading empty
-    entries after the first are discarded.
-
-Arguments:
-
-    pszList - List to split up
-    fTrimEntries - Whether each entry should be trimmed before added to multisz
-    fRemoveEmptyEntries - Whether empty entires should be discarded
-    pmszList - Filled with MULTISZ list
-
-Return Value:
-
-    HRESULT
-
---*/
-{
-    HRESULT                 hr = S_OK;
-
-    if ( pszList == nullptr ||
-         pmszList == nullptr )
-    {
-        DBG_ASSERT( FALSE );
-        hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
-        goto Finished;
-    }
-
-    pmszList->Reset();
-
-    /*
-        pszCurrent: start of the current entry which may be the comma that
-                    precedes the next entry if the entry is empty
-
-        pszNext: the comma that precedes the next entry. If
-                 pszCurrent == pszNext, then the entry is empty
-
-        pszEnd: just past the end of the current entry
-    */
-
-    for ( PCWSTR pszCurrent = pszList,
-                 pszNext = wcschr( pszCurrent, L',' )
-            ;
-            ;
-          pszCurrent = pszNext + 1,
-          pszNext = wcschr( pszCurrent, L',' ) )
-    {
-        PCWSTR pszEnd = nullptr;
-
-        if ( pszNext != nullptr )
-        {
-            pszEnd = pszNext;
-        }
-        else
-        {
-            pszEnd = pszCurrent + wcslen( pszCurrent );
-        }
-
-        if ( fTrimEntries )
-        {
-            while ( pszCurrent < pszEnd && ISWHITE( pszCurrent[ 0 ] ) )
-            {
-                pszCurrent++;
-            }
-
-            while ( pszEnd > pszCurrent && ISWHITE( pszEnd[ -1 ] ) )
-            {
-                pszEnd--;
-            }
-        }
-
-        if ( pszCurrent != pszEnd || !fRemoveEmptyEntries  )
-        {
-            if ( !pmszList->Append( pszCurrent, (DWORD) ( pszEnd - pszCurrent ) ) )
-            {
-                hr = HRESULT_FROM_WIN32( GetLastError() );
-                goto Finished;
-            }
-        }
-
-        if ( pszNext == nullptr )
-        {
-            break;
-        }
-    }
-
-Finished:
-
-    return hr;
-}
-
 #pragma warning(default:4267)

+ 5 - 86
src/Servers/IIS/AspNetCoreModuleV2/IISLib/multisz.h

@@ -8,9 +8,6 @@
 #include "ntassert.h"
 #include <CodeAnalysis/Warnings.h>
 
-#pragma warning( push )
-#pragma warning ( disable : ALL_CODE_ANALYSIS_WARNINGS )
-
 /*++
   class MULTISZ:
 
@@ -20,9 +17,6 @@
     This object is derived from BUFFER class.
     It maintains following state:
 
-     m_fValid  - whether this object is valid -
-        used only by MULTISZ() init functions
-        * NYI: I need to kill this someday *
      m_cchLen - string length cached when we update the string.
      m_cStrings - number of strings.
 
@@ -65,26 +59,13 @@ public:
           m_cStrings(0)
     { AuxInit( str.QueryStr()); }
 
-//    BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
-    //
-    //  Checks and returns TRUE if this string has no valid data else FALSE
-    //
-    BOOL IsEmpty() const      { return ( *QueryStr() == L'\0'); }
-
     BOOL Append( const WCHAR  * pchInit ) {
-      return ((pchInit != NULL) ? (AuxAppend( pchInit,
+      return ((pchInit != nullptr) ? (AuxAppend( pchInit,
                                               static_cast<DWORD>(wcslen(pchInit)) * sizeof(WCHAR)
                                               )) :
               TRUE);
     }
 
-
-    BOOL Append( const WCHAR  * pchInit, DWORD cchLen ) {
-      return ((pchInit != NULL) ? (AuxAppend( pchInit,
-                                              cchLen * sizeof(WCHAR))) :
-              TRUE);
-    }
-
     BOOL Append( STRU & str )
       { return AuxAppend( str.QueryStr(),
                           (str.QueryCCH()) * sizeof(WCHAR)); }
@@ -100,7 +81,7 @@ public:
 
     BOOL Copy( const WCHAR  * pchInit, IN DWORD cbLen ) {
       if ( QueryPtr() ) { Reset(); }
-      return ( (pchInit != NULL) ?
+      return ( (pchInit != nullptr) ?
                AuxAppend( pchInit, cbLen, FALSE ):
                TRUE);
     }
@@ -120,12 +101,6 @@ public:
     //
     UINT QueryCCH() const { return (m_cchLen); }
 
-    //
-    //  Returns # of strings in the multisz.
-    //
-
-    DWORD QueryStringCount() const { return m_cStrings; }
-
     //
     // Makes a copy of the stored string in given buffer
     //
@@ -134,28 +109,8 @@ public:
     //
     //  Return the string buffer
     //
-    WCHAR * QueryStrA() const { return ( QueryStr()); }
     WCHAR * QueryStr() const { return ((WCHAR *) QueryPtr()); }
 
-    //
-    //  Makes a clone of the current string in the string pointer passed in.
-    //
-    BOOL
-      Clone( OUT MULTISZ * pstrClone) const
-        {
-          return ((pstrClone == NULL) ?
-                  (SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
-                  (pstrClone->Copy( *this))
-                  );
-        } // MULTISZ::Clone()
-
-    //
-    //  Recalculates the length of *this because we've modified the buffers
-    //  directly
-    //
-
-    VOID RecalcLen()
-        { m_cchLen = CalcLength( QueryStr(), &m_cStrings ); }
 
     //
     // Calculate total character length of a MULTI_SZ, including the
@@ -165,34 +120,16 @@ public:
     static DWORD CalcLength( const WCHAR * str,
                                     LPDWORD pcStrings = NULL );
 
-    //
-    // Determine if the MULTISZ contains a specific string.
-    //
-
-    BOOL FindString( const WCHAR * str ) const;
-
-    BOOL FindString( STRU & str )
-        { return FindString( str.QueryStr() ); }
-
-    //
-    // Determine if the MULTISZ contains a specific string - case-insensitive
-    //
-
-    BOOL FindStringNoCase( const WCHAR * str ) const;
-
-    BOOL FindStringNoCase( STRU & str )
-        { return FindStringNoCase( str.QueryStr() ); }
-
     //
     // Used for scanning a multisz.
     //
 
     const WCHAR * First() const
-        { return *QueryStr() == L'\0' ? NULL : QueryStr(); }
+        { return *QueryStr() == L'\0' ? nullptr : QueryStr(); }
 
     const WCHAR * Next( const WCHAR * Current ) const
         { Current += wcslen( Current ) + 1;
-          return *Current == L'\0' ? NULL : Current; }
+          return *Current == L'\0' ? nullptr : Current; }
 
     BOOL
     Equals(
@@ -209,22 +146,4 @@ private:
 
 };
 
-//
-//  Quick macro for declaring a MULTISZ that will use stack memory of <size>
-//  bytes.  If the buffer overflows then a heap buffer will be allocated
-//
-
-#define STACK_MULTISZ( name, size )     WCHAR __ach##name[size]; \
-                                    MULTISZ name( __ach##name, sizeof( __ach##name ))
-
-HRESULT
-SplitCommaDelimitedString(
-    PCWSTR                      pszList,
-    BOOL                        fTrimEntries,
-    BOOL                        fRemoveEmptyEntries,
-    MULTISZ *                   pmszList
-);
-
-#pragma warning( pop )
-
-#endif // !_MULTISZ_HXX_
+#endif // !_MULTISZ_H_

+ 0 - 210
src/Servers/IIS/AspNetCoreModuleV2/IISLib/multisza.cpp

@@ -10,7 +10,6 @@
 //
 
 #define MAXULONG 4294967295
-#define ISWHITE( ch )       ((ch) == L' ' || (ch) == L'\t' || (ch) == L'\r')
 
 //
 //  When appending data, this is the extra amount we request to avoid
@@ -42,72 +41,6 @@ MULTISZA::CalcLength( const CHAR * str,
 }   // MULTISZA::CalcLength
 
 
-BOOL
-MULTISZA::FindString( const CHAR * str ) const
-{
-    //
-    // Sanity check.
-    //
-
-    DBG_ASSERT( QueryStr() != nullptr);
-    DBG_ASSERT( str != nullptr );
-    DBG_ASSERT( *str != '\0' );
-
-    //
-    // Scan it.
-    //
-
-    CHAR* multisz = QueryStr();
-
-    while( *multisz != '\0' ) {
-
-        if( !::strcmp( multisz, str ) ) {
-
-            return TRUE;
-
-        }
-
-        multisz += ::strlen( multisz ) + 1;
-
-    }
-
-    return FALSE;
-
-}   // MULTISZA::FindString
-
-
-BOOL
-MULTISZA::FindStringNoCase( const CHAR * str ) const
-{
-    //
-    // Sanity check.
-    //
-
-    DBG_ASSERT( QueryStr() != nullptr);
-    DBG_ASSERT( str != nullptr);
-    DBG_ASSERT( *str != '\0' );
-
-    //
-    // Scan it.
-    //
-
-    CHAR* multisz = QueryStr();
-
-    while( *multisz != '\0' ) {
-
-        if( !_stricmp( multisz, str ) ) {
-            return TRUE;
-        }
-
-        multisz += strlen( multisz ) + 1;
-
-    }
-
-    return FALSE;
-
-}   // MULTISZA::FindStringNoCase
-
-
 VOID
 MULTISZA::AuxInit( const CHAR * pInit )
 {
@@ -215,50 +148,6 @@ BOOL MULTISZA::AuxAppend( const CHAR * pStr, UINT cbStr, BOOL fAddSlop )
 
 } // MULTISZA::AuxAppend()
 
-BOOL
-MULTISZA::CopyToBuffer( __out_ecount_opt(*lpcch) CHAR * lpszBuffer, LPDWORD lpcch) const
-/*++
-    Description:
-        Copies the string into the CHAR buffer passed in if the buffer
-          is sufficient to hold the translated string.
-        If the buffer is small, the function returns small and sets *lpcch
-          to contain the required number of characters.
-
-    Arguments:
-        lpszBuffer      pointer to CHAR buffer which on return contains
-                        the string on success.
-        lpcch           pointer to DWORD containing the length of the buffer.
-                        If *lpcch == 0 then the function returns TRUE with
-                        the count of characters required stored in lpcch.
-                        Also in this case lpszBuffer is not affected.
-    Returns:
-        TRUE on success.
-        FALSE on failure.  Use GetLastError() for further details.
---*/
-{
-   BOOL fReturn = TRUE;
-
-    if ( lpcch == nullptr) {
-        SetLastError( ERROR_INVALID_PARAMETER);
-        return ( FALSE);
-    }
-
-   DWORD cch = QueryCCH();
-
-    if ( *lpcch >= cch) {
-
-        DBG_ASSERT( lpszBuffer);
-        memcpy( lpszBuffer, QueryStr(), cch * sizeof(CHAR));
-    } else {
-        DBG_ASSERT( *lpcch < cch);
-        SetLastError( ERROR_INSUFFICIENT_BUFFER);
-        fReturn = FALSE;
-    }
-
-    *lpcch = cch;
-
-    return ( fReturn);
-} // MULTISZA::CopyToBuffer()
 
 BOOL
 MULTISZA::Equals(
@@ -294,103 +183,4 @@ MULTISZA::Equals(
     return TRUE;
 }
 
-HRESULT
-SplitCommaDelimitedString(
-    PCSTR                        pszList,
-    BOOL                         fTrimEntries,
-    BOOL                         fRemoveEmptyEntries,
-    MULTISZA *                   pmszList
-)
-/*++
-
-Routine Description:
-
-    Split comma delimited string into a MULTISZA. Additional leading empty
-    entries after the first are discarded.
-
-Arguments:
-
-    pszList - List to split up
-    fTrimEntries - Whether each entry should be trimmed before added to MULTISZA
-    fRemoveEmptyEntries - Whether empty entires should be discarded
-    pmszList - Filled with MULTISZA list
-
-Return Value:
-
-    HRESULT
-
---*/
-{
-    HRESULT                 hr = S_OK;
-
-    if ( pszList == nullptr ||
-         pmszList == nullptr)
-    {
-        DBG_ASSERT( FALSE );
-        hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
-        goto Finished;
-    }
-    
-    pmszList->Reset();
-
-    /*
-        pszCurrent: start of the current entry which may be the comma that
-                    precedes the next entry if the entry is empty
-
-        pszNext: the comma that precedes the next entry. If
-                 pszCurrent == pszNext, then the entry is empty
-
-        pszEnd: just past the end of the current entry
-    */
-    
-    for ( PCSTR pszCurrent = pszList,
-                 pszNext = strchr( pszCurrent, L',' )
-            ;
-            ;
-          pszCurrent = pszNext + 1,
-          pszNext = strchr( pszCurrent, L',' ) )
-    {
-        PCSTR pszEnd = nullptr;
-
-        if ( pszNext != nullptr )
-        {
-            pszEnd = pszNext;
-        }
-        else
-        {
-            pszEnd = pszCurrent + strlen( pszCurrent );
-        }
-
-        if ( fTrimEntries )
-        {
-            while ( pszCurrent < pszEnd && ISWHITE( pszCurrent[ 0 ] ) )
-            {
-                pszCurrent++;
-            }
-
-            while ( pszEnd > pszCurrent && ISWHITE( pszEnd[ -1 ] ) )
-            {
-                pszEnd--;
-            }
-        }
-
-        if ( pszCurrent != pszEnd || !fRemoveEmptyEntries  )
-        {
-            if ( !pmszList->Append( pszCurrent, static_cast<DWORD>(pszEnd - pszCurrent) ) )
-            {
-                hr = HRESULT_FROM_WIN32( GetLastError() );
-                goto Finished;
-            }
-        }
-        
-        if ( pszNext == nullptr )
-        {
-            break;
-        }
-    }
-
-Finished:
-
-    return hr;
-}
 #pragma warning(default:4267)

+ 2 - 80
src/Servers/IIS/AspNetCoreModuleV2/IISLib/multisza.h

@@ -9,7 +9,7 @@
 
 
 /*++
-  class MULTISZ:
+  class MULTISZA:
 
   Intention:
     A light-weight multi-string class supporting encapsulated string class.
@@ -17,9 +17,6 @@
     This object is derived from BUFFER class.
     It maintains following state:
 
-     m_fValid  - whether this object is valid -
-        used only by MULTISZ() init functions
-        * NYI: I need to kill this someday *
      m_cchLen - string length cached when we update the string.
      m_cStrings - number of strings.
 
@@ -62,30 +59,12 @@ public:
           m_cStrings(0)
     { AuxInit( str.QueryStr()); }
 
-//    BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
-    //
-    //  Checks and returns TRUE if this string has no valid data else FALSE
-    //
-    BOOL IsEmpty( VOID) const      { return ( *QueryStr() == L'\0'); }
-
-    BOOL Append( const CHAR  * pchInit ) {
-      return ((pchInit != nullptr) ? (AuxAppend( pchInit,
-                                              (DWORD) (::strlen(pchInit)) * sizeof(CHAR)
-                                              )) :
-              TRUE);
-    }
-
-
     BOOL Append( const CHAR  * pchInit, DWORD cchLen ) {
       return ((pchInit != nullptr) ? (AuxAppend( pchInit,
                                               cchLen * sizeof(CHAR))) :
               TRUE);
     }
 
-    BOOL Append( STRA & str )
-      { return AuxAppend( str.QueryStr(),
-                          (str.QueryCCH()) * sizeof(CHAR)); }
-
     // Resets the internal string to be NULL string. Buffer remains cached.
     VOID Reset()
     { DBG_ASSERT( QueryPtr() != nullptr );
@@ -112,26 +91,10 @@ public:
     UINT QueryCB() const
         { return ( m_cchLen * sizeof(CHAR)); }
 
-    //
-    //  Returns # of characters in the string including the terminating NULLs
-    //
-    UINT QueryCCH() const { return (m_cchLen); }
-
-    //
-    //  Returns # of strings in the MULTISZA.
-    //
-
-    DWORD QueryStringCount() const { return m_cStrings; }
-
-    //
-    // Makes a copy of the stored string in given buffer
-    //
-    BOOL CopyToBuffer( __out_ecount_opt(*lpcch) CHAR * lpszBuffer,  LPDWORD lpcch) const;
 
     //
     //  Return the string buffer
     //
-    CHAR * QueryStrA() const { return ( QueryStr()); }
     CHAR * QueryStr() const { return reinterpret_cast<CHAR*>(QueryPtr()); }
 
     //
@@ -146,13 +109,6 @@ public:
                   );
         } // MULTISZA::Clone()
 
-    //
-    //  Recalculates the length of *this because we've modified the buffers
-    //  directly
-    //
-
-    VOID RecalcLen()
-        { m_cchLen = MULTISZA::CalcLength( QueryStr(), &m_cStrings ); }
 
     //
     // Calculate total character length of a MULTI_SZ, including the
@@ -162,24 +118,6 @@ public:
     static DWORD CalcLength( const CHAR * str,
                                     LPDWORD pcStrings = nullptr );
 
-    //
-    // Determine if the MULTISZA contains a specific string.
-    //
-
-    BOOL FindString( const CHAR * str ) const;
-
-    BOOL FindString( STRA & str ) const
-    { return FindString( str.QueryStr() ); }
-
-    //
-    // Determine if the MULTISZA contains a specific string - case-insensitive
-    //
-
-    BOOL FindStringNoCase( const CHAR * str ) const;
-
-    BOOL FindStringNoCase( STRA & str ) const
-    { return FindStringNoCase( str.QueryStr() ); }
-
     //
     // Used for scanning a MULTISZA.
     //
@@ -206,21 +144,5 @@ private:
 
 };
 
-//
-//  Quick macro for declaring a MULTISZA that will use stack memory of <size>
-//  bytes.  If the buffer overflows then a heap buffer will be allocated
-//
-
-#define STACK_MULTISZA( name, size )     CHAR __ach##name[size]; \
-                                    MULTISZA name( __ach##name, sizeof( __ach##name ))
-
-HRESULT
-SplitCommaDelimitedString(
-    PCSTR                       pszList,
-    BOOL                        fTrimEntries,
-    BOOL                        fRemoveEmptyEntries,
-    MULTISZA *                  pmszList
-);
-
-#endif // !_MULTISZA_HXX_
+#endif // !_MULTISZA_H_
 

+ 107 - 1064
src/Servers/IIS/AspNetCoreModuleV2/IISLib/stringa.cpp

@@ -38,9 +38,7 @@ STRA::STRA(
 }
 
 BOOL
-STRA::IsEmpty(
-    VOID
-) const
+STRA::IsEmpty() const
 {
     return ( m_cchLen == 0 );
 }
@@ -63,27 +61,16 @@ STRA::Equals(
 
 BOOL
 STRA::Equals(
-    __in const STRA *   pstrRhs,
-    __in BOOL           fIgnoreCase /*= FALSE*/
-) const
-{
-    _ASSERTE( nullptr != pstrRhs );
-    return Equals( pstrRhs->QueryStr(), fIgnoreCase );
-}
-
-BOOL
-STRA::Equals(
-    __in const STRA &  strRhs,
+    __in const STRA* pstrRhs,
     __in BOOL           fIgnoreCase /*= FALSE*/
 ) const
 {
-    return Equals( strRhs.QueryStr(), fIgnoreCase );
+    _ASSERTE(nullptr != pstrRhs);
+    return Equals(pstrRhs->QueryStr(), fIgnoreCase);
 }
 
 DWORD
-STRA::QueryCB(
-    VOID
-) const
+STRA::QueryCB() const
 //
 // Returns the number of bytes in the string excluding the terminating NULL
 //
@@ -92,9 +79,7 @@ STRA::QueryCB(
 }
 
 DWORD
-STRA::QueryCCH(
-    VOID
-) const
+STRA::QueryCCH() const
 //
 //  Returns the number of characters in the string excluding the terminating NULL
 //
@@ -125,9 +110,7 @@ STRA::QuerySize(
 __nullterminated
 __bcount(this->m_cchLen)
 CHAR *
-STRA::QueryStr(
-    VOID
-) const
+STRA::QueryStr() const
 //
 //  Return the string buffer
 //
@@ -254,41 +237,6 @@ STRA::CopyW(
     return CopyW( pszCopyW, cchLen );
 }
 
-HRESULT
-STRA::CopyWTruncate(
-    __in PCWSTR pszCopyWTruncate
-)
-{
-    size_t      cchLen;
-    HRESULT hr = StringCchLengthW(pszCopyWTruncate,
-                                  STRSAFE_MAX_CCH,
-                                  &cchLen);
-    if ( FAILED( hr ) )
-    {
-        return hr;
-    }
-    return CopyWTruncate( pszCopyWTruncate, cchLen );
-}
-
-HRESULT
-STRA::CopyWTruncate(
-    __in_ecount(cchLen)
-    PCWSTR          pszCopyWTruncate,
-    __in SIZE_T     cchLen
-)
-//
-// The "Truncate" methods do not do proper conversion. They do a (CHAR) caste
-//
-{
-    _ASSERTE( cchLen <= MAXDWORD );
-
-    return AuxAppendWTruncate(
-        pszCopyWTruncate,
-        static_cast<DWORD>(cchLen),
-        0
-    );
-}
-
 HRESULT
 STRA::Append(
     __in PCSTR pszAppend
@@ -324,15 +272,6 @@ STRA::Append(
     );
 }
 
-HRESULT
-STRA::Append(
-    __in const STRA * pstrRhs
-)
-{
-    _ASSERTE( pstrRhs != nullptr );
-    return Append( pstrRhs->QueryStr(), pstrRhs->QueryCCH() );
-}
-
 HRESULT
 STRA::Append(
     __in const STRA & strRhs
@@ -341,44 +280,6 @@ STRA::Append(
     return Append( strRhs.QueryStr(), strRhs.QueryCCH() );
 }
 
-HRESULT
-STRA::AppendWTruncate(
-    __in PCWSTR pszAppendWTruncate
-)
-{
-    size_t      cchLen;
-    HRESULT hr = StringCchLengthW(pszAppendWTruncate,
-                                  STRSAFE_MAX_CCH,
-                                  &cchLen);
-    if ( FAILED( hr ) )
-    {
-        return hr;
-    }
-    return AppendWTruncate( pszAppendWTruncate, cchLen );
-}
-
-HRESULT
-STRA::AppendWTruncate(
-    __in_ecount(cchLen)
-    PCWSTR          pszAppendWTruncate,
-    __in SIZE_T     cchLen
-)
-//
-// The "Truncate" methods do not do proper conversion. They do a (CHAR) caste
-//
-{
-    _ASSERTE( cchLen <= MAXDWORD );
-    if ( cchLen == 0 )
-    {
-        return S_OK;
-    }
-    return AuxAppendWTruncate(
-        pszAppendWTruncate,
-        static_cast<DWORD>(cchLen),
-        QueryCB()
-    );
-}
-
 HRESULT
 STRA::CopyToBuffer(
     __out_bcount(*pcb) CHAR*    pszBuffer,
@@ -409,72 +310,6 @@ Finished:
     return hr;
 }
 
-HRESULT
-STRA::SetLen(
-    __in DWORD cchLen
-)
-/*++
- *
-Routine Description:
-
-    Set the length of the string and null terminate, if there
-    is sufficient buffer already allocated. Will not reallocate.
-
-Arguments:
-
-    cchLen - The number of characters in the new string.
-
-Return Value:
-
-    HRESULT
-
---*/
-{
-    if( cchLen >= QuerySizeCCH() )
-    {
-        return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
-    }
-
-    *( QueryStr() + cchLen ) = '\0';
-    m_cchLen = cchLen;
-
-    return S_OK;
-}
-
-
-HRESULT
-STRA::SafeSnprintf(
-    __in __format_string
-    PCSTR       pszFormatString,
-    ...
-)
-/*++
-
-Routine Description:
-
-    Writes to a STRA, growing it as needed. It arbitrarily caps growth at 64k chars.
-
-Arguments:
-
-    pszFormatString    - printf format
-    ...                - printf args
-
-Return Value:
-
-    HRESULT
-
---*/
-{
-    va_list     argsList;
-    va_start(   argsList, pszFormatString );
-
-    HRESULT hr = SafeVsnprintf(pszFormatString, argsList);
-
-#pragma warning(suppress: 26477) // va_end uses 0
-    va_end( argsList );
-    return hr;
-}
-
 HRESULT
 STRA::SafeVsnprintf(
     __in __format_string
@@ -582,516 +417,139 @@ Finished:
     return hr;
 }
 
-bool
-FShouldEscapeUtf8(
-    BYTE ch
-    )
-{
-    if ( ( ch >= 128 ) )
-    {
-        return true;
-    }
-
-    return false;
-}
-
-bool
-FShouldEscapeUrl(
-    BYTE ch
-    )
+HRESULT
+STRA::CopyWToUTF8Unescaped(
+    __in LPCWSTR cpchStr
+)
 {
-    if ( ( ch >= 128   ||
-           ch <= 32    ||
-           ch == '<'   ||
-           ch == '>'   ||
-           ch == '%'   ||
-           ch == '?'   ||
-           ch == '#' ) &&
-         !( ch == '\n' || ch == '\r' ) )
-    {
-        return true;
-    }
-
-    return false;
+    return STRA::CopyWToUTF8Unescaped(cpchStr, static_cast<DWORD>(wcslen(cpchStr)));
 }
 
 HRESULT
-STRA::Escape(
-    VOID
+STRA::CopyWToUTF8Unescaped(
+    __in_ecount(cch)
+    LPCWSTR         cpchStr,
+    __in DWORD      cch
 )
-/*++
-
-Routine Description:
-
-    Escapes a STRA
-
-Arguments:
+{
+    HRESULT hr = S_OK;
 
-    None
+    if (cch == 0)
+    {
+        Reset();
+        return S_OK;
+    }
 
-Return Value:
+    int iRet = ConvertUnicodeToUTF8(cpchStr,
+                                    &m_Buff,
+                                    cch);
+    if (-1 == iRet)
+    {
+        // could not convert
+        hr = HRESULT_FROM_WIN32(GetLastError());
+        goto Finished;
+    }
 
-    None
+    m_cchLen = iRet;
 
---*/
-{
-    return EscapeInternal( FShouldEscapeUrl );
+    _ASSERTE(strlen(m_Buff.QueryPtr()) == m_cchLen);
+Finished:
+    return hr;
 }
 
 HRESULT
-STRA::EscapeUtf8(
+STRA::AuxAppend(
+    __in_ecount(cbLen)
+    LPCSTR          pStr,
+    __in DWORD      cbLen,
+    __in DWORD      cbOffset
 )
-/*++
-
-Routine Description:
+{
+    _ASSERTE( nullptr != pStr );
+    _ASSERTE( cbOffset <= QueryCB() );
 
-    Escapes the high-bit chars in a STRA.  LWS, CR, LF & controls are untouched.
+    ULONGLONG cb64NewSize = static_cast<ULONGLONG>(cbOffset) + cbLen + sizeof( CHAR );
+    if( cb64NewSize > MAXDWORD )
+    {
+        return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW );
+    }
 
-Arguments:
+    if( m_Buff.QuerySize() < cb64NewSize )
+    {
+        if( !m_Buff.Resize( static_cast<SIZE_T>(cb64NewSize) ) )
+        {
+            return E_OUTOFMEMORY;
+        }
+    }
 
-    None
+    memcpy( reinterpret_cast<BYTE*>(m_Buff.QueryPtr()) + cbOffset, pStr, cbLen );
 
-Return Value:
+    m_cchLen = cbLen + cbOffset;
 
-    None
+    *( QueryStr() + m_cchLen ) = '\0';
 
---*/
-{
-    return EscapeInternal( FShouldEscapeUtf8 );
+    return S_OK;
 }
 
-
 HRESULT
-STRA::EscapeInternal(
-    PFN_F_SHOULD_ESCAPE pfnFShouldEscape
+STRA::AuxAppendW(
+    __in_ecount(cchAppendW)
+    PCWSTR          pszAppendW,
+    __in DWORD      cchAppendW,
+    __in DWORD      cbOffset,
+    __in UINT       CodePage,
+    __in BOOL       fFailIfNoTranslation,
+    __in DWORD      dwFlags
 )
-/*++
-
-Routine Description:
-
-    Escapes a STRA according to the predicate function passed in
-
-Arguments:
-
-    None
-
-Return Value:
-
-    None
-
---*/
 {
-    LPCSTR  pch     = QueryStr();
-    __analysis_assume( pch != nullptr );
-    int     i      = 0;
-    BYTE    ch;
-    HRESULT hr      = S_OK;
-    ULONG64  NewSize = 0;
+    HRESULT hr          = S_OK;
+    DWORD   cbRet       = 0;
+    DWORD cbAvailable   = 0;
+    UNREFERENCED_PARAMETER(fFailIfNoTranslation);
+
+    //
+    // There are only two expect places to append
+    //
+    _ASSERTE( 0 == cbOffset || QueryCB() == cbOffset );
 
-    // Set to true if any % escaping occurs
-    BOOL fEscapingDone = FALSE;
+    if ( cchAppendW == 0 )
+    {
+        goto Finished;
+    }
 
     //
-    // If there are any characters that need to be escaped we copy the entire string
-    // character by character into straTemp, escaping as we go, then at the end
-    // copy all of straTemp over. Don't modify InlineBuffer directly.
+    // start by assuming 1 char to 1 char will be enough space
     //
-    CHAR InlineBuffer[512];
-    InlineBuffer[0] = '\0';
-    STRA straTemp(InlineBuffer, sizeof(InlineBuffer)/sizeof(*InlineBuffer));
+    if( !m_Buff.Resize( cbOffset + cchAppendW + sizeof( CHAR ) ) )
+    {
+        hr = E_OUTOFMEMORY;
+        goto Finished;
+    }
 
-    _ASSERTE( pch );
+    cbAvailable = m_Buff.QuerySize() - cbOffset;
 
-    while ((DWORD)i < m_cchLen && pch[i] != NULL)
+    cbRet = WideCharToMultiByte(
+        CodePage,
+        dwFlags,
+        pszAppendW,
+        cchAppendW,
+        QueryStr() + cbOffset,
+        cbAvailable,
+        nullptr,
+        nullptr
+    );
+    if( 0 != cbRet )
     {
+        if(!m_Buff.Resize(cbOffset + cbRet + 1))
+        {
+            hr = E_OUTOFMEMORY;
+        }
+
         //
-        //  Escape characters that are in the non-printable range
-        //  but ignore CR and LF
+        // not zero --> success, so we're done
         //
-
-        ch = pch[i];
-        if ( pfnFShouldEscape( ch ) )
-        {
-            if (FALSE == fEscapingDone)
-            {
-                // first character in the string that needed escaping
-                fEscapingDone = TRUE;
-
-                // guess that the size needs to be larger than
-                // what we used to have times two
-                NewSize = static_cast<ULONG64>(QueryCCH()) * 2;
-                if ( NewSize > MAXDWORD )
-                {
-                    hr = HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW );
-                    return hr;
-                }
-
-                hr = straTemp.Resize( static_cast<DWORD>(NewSize) );
-
-                if (FAILED(hr))
-                {
-                    return hr;
-                }
-
-                // Copy all of the previous buffer into buffTemp, only if it is not the first character:
-
-                if ( i > 0)
-                {
-                    hr = straTemp.Copy(QueryStr(),
-                                       i * sizeof(CHAR));
-                    if (FAILED(hr))
-                    {
-                        return hr;
-                    }
-                }
-            }
-
-            // resize the temporary (if needed) with the slop of the entire buffer length
-            // this fixes constant reallocation if the entire string needs to be escaped
-            NewSize = static_cast<ULONG64>(QueryCCH()) + 2 * sizeof(CHAR) + 1 * sizeof(CHAR);
-            if ( NewSize > MAXDWORD )
-            {
-                hr = HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW );
-                return hr;
-            }
-
-            BOOL fRet = straTemp.m_Buff.Resize(static_cast<size_t>(NewSize));
-            if ( !fRet )
-            {
-                hr = HRESULT_FROM_WIN32(GetLastError());
-                return hr;
-            }
-
-            //
-            //  Create the string to append for the current character
-            //
-
-            CHAR chHex[3];
-            chHex[0] = '%';
-
-            //
-            //  Convert the low then the high character to hex
-            //
-
-            UINT nLowDigit = static_cast<UINT>(ch % 16);
-            chHex[2] = TODIGIT( nLowDigit );
-
-            ch /= 16;
-
-            UINT nHighDigit = static_cast<UINT>(ch % 16);
-
-            chHex[1] = TODIGIT( nHighDigit );
-
-            //
-            // Actually append the converted character to the end of the temporary
-            //
-            hr = straTemp.Append(chHex, 3);
-            if (FAILED(hr))
-            {
-                return hr;
-            }
-        }
-        else
-        {
-            // if no escaping done, no need to copy
-            if (fEscapingDone)
-            {
-                // if ANY escaping done, copy current character into new buffer
-                straTemp.Append(&pch[i], 1);
-            }
-        }
-
-        // inspect the next character in the string
-        i++;
-    }
-
-    if (fEscapingDone)
-    {
-        // the escaped string is now in straTemp
-        hr = Copy(straTemp);
-    }
-
-    return hr;
-
-} // EscapeInternal()
-
-VOID
-STRA::Unescape(
-)
-/*++
-
-Routine Description:
-
-    Unescapes a STRA
-
-    Supported escape sequences are:
-      %uxxxx unescapes Unicode character xxxx into system codepage
-      %xx    unescapes character xx
-      %      without following hex digits is ignored
-
-Arguments:
-
-    None
-
-Return Value:
-
-    None
-
---*/
-{
-    CHAR   *pScan;
-    WCHAR   wch;
-    DWORD   dwLen;
-    BOOL    fChanged = FALSE;
-
-    //
-    // Now take care of any escape characters
-    //
-    CHAR* pDest = pScan = strchr(QueryStr(), '%');
-
-    while (pScan)
-    {
-        if ((pScan[1] == 'u' || pScan[1] == 'U') &&
-            SAFEIsXDigit(pScan[2]) &&
-            SAFEIsXDigit(pScan[3]) &&
-            SAFEIsXDigit(pScan[4]) &&
-            SAFEIsXDigit(pScan[5]))
-        {
-            wch = TOHEX(pScan[2]) * 4096 + TOHEX(pScan[3]) * 256
-                + TOHEX(pScan[4]) * 16 + TOHEX(pScan[5]);
-
-            dwLen = WideCharToMultiByte(CP_ACP,
-                                        WC_NO_BEST_FIT_CHARS,
-                                        &wch,
-                                        1,
-                                        static_cast<LPSTR>(pDest),
-                                        6,
-                                        nullptr,
-                                        nullptr);
-
-            pDest += dwLen;
-            pScan += 6;
-            fChanged = TRUE;
-        }
-        else if (SAFEIsXDigit(pScan[1]) && SAFEIsXDigit(pScan[2]))
-        {
-            *pDest = TOHEX(pScan[1]) * 16 + TOHEX(pScan[2]);
-
-            pDest ++;
-            pScan += 3;
-            fChanged = TRUE;
-        }
-        else   // Not an escaped char, just a '%'
-        {
-            if (fChanged)
-            {
-                *pDest = *pScan;
-            }
-
-            pDest++;
-            pScan++;
-        }
-
-        //
-        // Copy all the information between this and the next escaped char
-        //
-        CHAR* pNextScan = strchr(pScan, '%');
-
-        if (fChanged)   // pScan!=pDest, so we have to copy the char's
-        {
-            if (!pNextScan)   // That was the last '%' in the string
-            {
-                memmove(pDest,
-                        pScan,
-                        QueryCCH() - DIFF(pScan - QueryStr()) + 1);
-            }
-            else
-            {
-                // There is another '%', move intermediate chars
-                if ((dwLen = static_cast<DWORD>(DIFF(pNextScan - pScan))) != 0)
-                {
-                    memmove(pDest,
-                            pScan,
-                            dwLen);
-                    pDest += dwLen;
-                }
-            }
-        }
-
-        pScan = pNextScan;
-    }
-
-    if (fChanged)
-    {
-        m_cchLen = static_cast<DWORD>(strlen(QueryStr()));  // for safety recalc the length
-    }
-}
-
-HRESULT
-STRA::CopyWToUTF8Unescaped(
-    __in LPCWSTR cpchStr
-)
-{
-    return STRA::CopyWToUTF8Unescaped(cpchStr, static_cast<DWORD>(wcslen(cpchStr)));
-}
-
-HRESULT
-STRA::CopyWToUTF8Unescaped(
-    __in_ecount(cch)
-    LPCWSTR         cpchStr,
-    __in DWORD      cch
-)
-{
-    HRESULT hr = S_OK;
-
-    if (cch == 0)
-    {
-        Reset();
-        return S_OK;
-    }
-
-    int iRet = ConvertUnicodeToUTF8(cpchStr,
-                                    &m_Buff,
-                                    cch);
-    if (-1 == iRet)
-    {
-        // could not convert
-        hr = HRESULT_FROM_WIN32(GetLastError());
-        goto Finished;
-    }
-
-    m_cchLen = iRet;
-
-    _ASSERTE(strlen(m_Buff.QueryPtr()) == m_cchLen);
-Finished:
-    return hr;
-}
-
-HRESULT
-STRA::CopyWToUTF8Escaped(
-    __in LPCWSTR cpchStr
-)
-{
-    return STRA::CopyWToUTF8Escaped(cpchStr, static_cast<DWORD>(wcslen(cpchStr)));
-}
-
-HRESULT
-STRA::CopyWToUTF8Escaped(
-    __in_ecount(cch)
-    LPCWSTR         cpchStr,
-    __in DWORD      cch
-)
-{
-    HRESULT hr = CopyWToUTF8Unescaped(cpchStr, cch);
-    if (FAILED(hr))
-    {
-        goto Finished;
-    }
-
-    hr = Escape();
-    if (FAILED(hr))
-    {
-        goto Finished;
-    }
-
-    hr = S_OK;
-Finished:
-    return hr;
-}
-
-HRESULT
-STRA::AuxAppend(
-    __in_ecount(cbLen)
-    LPCSTR          pStr,
-    __in DWORD      cbLen,
-    __in DWORD      cbOffset
-)
-{
-    _ASSERTE( nullptr != pStr );
-    _ASSERTE( cbOffset <= QueryCB() );
-
-    ULONGLONG cb64NewSize = static_cast<ULONGLONG>(cbOffset) + cbLen + sizeof( CHAR );
-    if( cb64NewSize > MAXDWORD )
-    {
-        return HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW );
-    }
-
-    if( m_Buff.QuerySize() < cb64NewSize )
-    {
-        if( !m_Buff.Resize( static_cast<SIZE_T>(cb64NewSize) ) )
-        {
-            return E_OUTOFMEMORY;
-        }
-    }
-
-    memcpy( reinterpret_cast<BYTE*>(m_Buff.QueryPtr()) + cbOffset, pStr, cbLen );
-
-    m_cchLen = cbLen + cbOffset;
-
-    *( QueryStr() + m_cchLen ) = '\0';
-
-    return S_OK;
-}
-
-HRESULT
-STRA::AuxAppendW(
-    __in_ecount(cchAppendW)
-    PCWSTR          pszAppendW,
-    __in DWORD      cchAppendW,
-    __in DWORD      cbOffset,
-    __in UINT       CodePage,
-    __in BOOL       fFailIfNoTranslation,
-    __in DWORD      dwFlags
-)
-{
-    HRESULT hr          = S_OK;
-    DWORD   cbRet       = 0;
-    DWORD cbAvailable   = 0;
-    UNREFERENCED_PARAMETER(fFailIfNoTranslation);
-
-    //
-    // There are only two expect places to append
-    //
-    _ASSERTE( 0 == cbOffset || QueryCB() == cbOffset );
-
-    if ( cchAppendW == 0 )
-    {
-        goto Finished;
-    }
-
-    //
-    // start by assuming 1 char to 1 char will be enough space
-    //
-    if( !m_Buff.Resize( cbOffset + cchAppendW + sizeof( CHAR ) ) )
-    {
-        hr = E_OUTOFMEMORY;
-        goto Finished;
-    }
-
-    cbAvailable = m_Buff.QuerySize() - cbOffset;
-
-    cbRet = WideCharToMultiByte(
-        CodePage,
-        dwFlags,
-        pszAppendW,
-        cchAppendW,
-        QueryStr() + cbOffset,
-        cbAvailable,
-        nullptr,
-        nullptr
-    );
-    if( 0 != cbRet )
-    {
-        if(!m_Buff.Resize(cbOffset + cbRet + 1))
-        {
-            hr = E_OUTOFMEMORY;
-        }
-
-        //
-        // not zero --> success, so we're done
-        //
-        goto Finished;
-    }
+        goto Finished;
+    }
 
     //
     // We only know how to handle ERROR_INSUFFICIENT_BUFFER
@@ -1287,21 +745,6 @@ STRA::ConvertUnicodeToCodePage(
     return iStrLen;
 }
 
-// static
-HRESULT
-STRA::ConvertUnicodeToMultiByte(
-    __in_ecount(dwStringLen)
-    LPCWSTR                     pszSrcUnicodeString,
-    __in BUFFER_T<CHAR,1> *     pbufDstAnsiString,
-    __in DWORD                  dwStringLen
-)
-{
-    return ConvertUnicodeToCodePage( pszSrcUnicodeString,
-                                      pbufDstAnsiString,
-                                      dwStringLen,
-                                      CP_ACP );
-}
-
 // static
 HRESULT
 STRA::ConvertUnicodeToUTF8(
@@ -1316,403 +759,3 @@ STRA::ConvertUnicodeToUTF8(
                                       dwStringLen,
                                       CP_UTF8 );
 }
-
-/*++
-
-Routine Description:
-
-    Removes leading and trailing whitespace
-
---*/
-
-VOID
-STRA::Trim()
-{
-    PSTR    pszString               = QueryStr();
-    DWORD   cchNewLength            = m_cchLen;
-    DWORD   cchLeadingWhitespace    = 0;
-
-    for (LONG ixString = m_cchLen - 1; ixString >= 0; ixString--)
-    {
-        if (isspace(static_cast<unsigned char>(pszString[ixString])) != 0)
-        {
-            pszString[ixString] = '\0';
-            cchNewLength--;
-        }
-        else
-        {
-            break;
-        }
-    }
-
-    DWORD cchTempLength = cchNewLength;
-    for (DWORD ixString = 0; ixString < cchTempLength; ixString++)
-    {
-        if (isspace(static_cast<unsigned char>(pszString[ixString])) != 0)
-        {
-            cchLeadingWhitespace++;
-            cchNewLength--;
-        }
-        else
-        {
-            break;
-        }
-    }
-
-    if (cchNewLength == 0)
-    {
-
-        Reset();
-    }
-    else if (cchLeadingWhitespace > 0)
-    {
-        memmove(pszString, pszString + cchLeadingWhitespace, cchNewLength * sizeof(CHAR));
-        pszString[cchNewLength] = '\0';
-    }
-
-    SyncWithBuffer();
-}
-
-/*++
-
-Routine Description:
-
-    Compares the string to the provided prefix to check for equality
-
-Arguments:
-
-    pStraPrefix - string to compare with
-    fIgnoreCase - indicates whether the string comparison should be case-sensitive
-
-Return Value:
-
-    TRUE if prefix string matches with internal string, FALSE otherwise
-
---*/
-BOOL
-STRA::StartsWith(
-    __in const STRA *   pStraPrefix,
-    __in bool           fIgnoreCase) const
-{
-    _ASSERTE( pStraPrefix != nullptr );
-    return StartsWith(pStraPrefix->QueryStr(), fIgnoreCase);
-}
-
-/*++
-
-Routine Description:
-
-    Compares the string to the provided prefix to check for equality
-
-Arguments:
-
-    straPrefix  - string to compare with
-    fIgnoreCase - indicates whether the string comparison should be case-sensitive
-
-Return Value:
-
-    TRUE if prefix string matches with internal string, FALSE otherwise
-
---*/
-BOOL
-STRA::StartsWith(
-    __in const STRA &   straPrefix,
-    __in bool           fIgnoreCase) const
-{
-    return StartsWith(straPrefix.QueryStr(), fIgnoreCase);
-}
-
-/*++
-
-Routine Description:
-
-    Compares the string to the provided prefix to check for equality
-
-Arguments:
-
-    pszPrefix   - string to compare with
-    fIgnoreCase - indicates whether the string comparison should be case-sensitive
-
-Return Value:
-
-    TRUE if prefix string matches with internal string, FALSE otherwise
-
---*/
-BOOL
-STRA::StartsWith(
-    __in PCSTR          pszPrefix,
-    __in bool           fIgnoreCase) const
-{
-    if (pszPrefix == nullptr)
-    {
-        return FALSE;
-    }
-
-    size_t  cchPrefix   = 0;
-    HRESULT hr = StringCchLengthA(pszPrefix, STRSAFE_MAX_CCH, &cchPrefix);
-    if (FAILED(hr))
-    {
-        return FALSE;
-    }
-
-    _ASSERTE( cchPrefix <= MAXDWORD );
-    if (cchPrefix > m_cchLen)
-    {
-        return FALSE;
-    }
-
-    BOOL fMatch = FALSE;
-    if ( fIgnoreCase )
-    {
-        fMatch = ( 0 == _strnicmp( QueryStr(), pszPrefix, cchPrefix ) );
-    }
-    else
-    {
-        fMatch = ( 0 == strncmp( QueryStr(), pszPrefix, cchPrefix ) );
-    }
-
-    return fMatch;
-}
-
-/*++
-
-Routine Description:
-
-    Compares the string to the provided suffix to check for equality
-
-Arguments:
-
-    pStraSuffix - string to compare with
-    fIgnoreCase - indicates whether the string comparison should be case-sensitive
-
-Return Value:
-
-    TRUE if suffix string matches with internal string, FALSE otherwise
-
---*/
-BOOL
-STRA::EndsWith(
-    __in const STRA *   pStraSuffix,
-    __in bool           fIgnoreCase) const
-{
-    _ASSERTE( pStraSuffix != nullptr );
-    return EndsWith(pStraSuffix->QueryStr(), fIgnoreCase);
-}
-
-
-/*++
-
-Routine Description:
-
-    Compares the string to the provided suffix to check for equality
-
-Arguments:
-
-    straSuffix  - string to compare with
-    fIgnoreCase - indicates whether the string comparison should be case-sensitive
-
-Return Value:
-
-    TRUE if suffix string matches with internal string, FALSE otherwise
-
---*/
-BOOL
-STRA::EndsWith(
-    __in const STRA &   straSuffix,
-    __in bool           fIgnoreCase) const
-{
-    return EndsWith(straSuffix.QueryStr(), fIgnoreCase);
-}
-
-
-/*++
-
-Routine Description:
-
-    Compares the string to the provided suffix to check for equality
-
-Arguments:
-
-    pszSuffix   - string to compare with
-    fIgnoreCase - indicates whether the string comparison should be case-sensitive
-
-Return Value:
-
-    TRUE if suffix string matches with internal string, FALSE otherwise
-
---*/
-BOOL
-STRA::EndsWith(
-    __in PCSTR          pszSuffix,
-    __in bool           fIgnoreCase) const
-{
-    PSTR      pszString   = QueryStr();
-
-    if (pszSuffix == nullptr)
-    {
-        return FALSE;
-    }
-
-    size_t    cchSuffix   = 0;
-    HRESULT hr = StringCchLengthA(pszSuffix, STRSAFE_MAX_CCH, &cchSuffix);
-    if (FAILED(hr))
-    {
-        return FALSE;
-    }
-
-    _ASSERTE( cchSuffix <= MAXDWORD );
-    if (cchSuffix > m_cchLen)
-    {
-        return FALSE;
-    }
-
-    ptrdiff_t ixOffset = m_cchLen - cchSuffix;
-    _ASSERTE(ixOffset >= 0 && ixOffset <= MAXDWORD);
-
-    BOOL fMatch = FALSE;
-    if ( fIgnoreCase )
-    {
-        fMatch = ( 0 == _strnicmp( pszString + ixOffset, pszSuffix, cchSuffix ) );
-    }
-    else
-    {
-        fMatch = ( 0 == strncmp( pszString + ixOffset, pszSuffix, cchSuffix ) );
-    }
-
-    return fMatch;
-}
-
-
-/*++
-
-Routine Description:
-
-    Searches the string for the first occurrence of the specified character.
-
-Arguments:
-
-    charValue       - character to find
-    dwStartIndex    - the initial index.
-
-Return Value:
-
-    The index for the first character occurrence in the string.
-
-    -1 if not found.
-
---*/
-INT
-STRA::IndexOf(
-    __in CHAR           charValue,
-    __in DWORD          dwStartIndex
-    ) const
-{
-    INT nIndex = -1;
-
-    // Make sure that there are no buffer overruns.
-    if ( dwStartIndex >= QueryCCH() )
-    {
-        return nIndex;
-    }
-
-    const CHAR* pChar = strchr( QueryStr() + dwStartIndex, charValue );
-
-    // Determine the index if found
-    if ( pChar )
-    {
-        // nIndex will be set to -1 on failure.
-        (VOID)SizeTToInt( pChar - QueryStr(), &nIndex );
-    }
-
-    return nIndex;
-}
-
-
-/*++
-
-Routine Description:
-
-    Searches the string for the first occurrence of the specified substring.
-
-Arguments:
-
-    pszValue        - substring to find
-    dwStartIndex    - initial index.
-
-Return Value:
-
-    The index for the first character occurrence in the string.
-
-    -1 if not found.
-
---*/
-INT
-STRA::IndexOf(
-    __in PCSTR          pszValue,
-    __in DWORD          dwStartIndex
-    ) const
-{
-    INT nIndex = -1;
-
-    // Validate input parameters
-    if( dwStartIndex >= QueryCCH() || !pszValue )
-    {
-        return nIndex;
-    }
-
-    const CHAR* pChar = strstr( QueryStr() + dwStartIndex, pszValue );
-
-    // Determine the index if found
-    if( pChar )
-    {
-        // nIndex will be set to -1 on failure.
-        (VOID)SizeTToInt( pChar - QueryStr(), &nIndex );
-    }
-
-    return nIndex;
-}
-
-
-/*++
-
-Routine Description:
-
-    Searches the string for the last occurrence of the specified character.
-
-Arguments:
-
-    charValue       - character to find
-    dwStartIndex    - initial index.
-
-Return Value:
-
-    The index for the last character occurrence in the string.
-
-    -1 if not found.
-
---*/
-INT
-STRA::LastIndexOf(
-    __in CHAR           charValue,
-    __in DWORD          dwStartIndex
-    ) const
-{
-    INT nIndex = -1;
-
-    // Make sure that there are no buffer overruns.
-    if( dwStartIndex >= QueryCCH() )
-    {
-        return nIndex;
-    }
-
-    const CHAR* pChar = strrchr( QueryStr() + dwStartIndex, charValue );
-
-    // Determine the index if found
-    if( pChar )
-    {
-        // nIndex will be set to -1 on failure.
-        (VOID)SizeTToInt( pChar - QueryStr(), &nIndex );
-    }
-
-    return nIndex;
-}

+ 0 - 195
src/Servers/IIS/AspNetCoreModuleV2/IISLib/stringa.h

@@ -6,10 +6,6 @@
 #include "buffer.h"
 #include <strsafe.h>
 
-
-#pragma warning( push )
-#pragma warning ( disable : ALL_CODE_ANALYSIS_WARNINGS )
-
 class STRA
 {
 
@@ -39,88 +35,6 @@ public:
         __in BOOL           fIgnoreCase = FALSE
     ) const;
 
-    BOOL
-    Equals(
-        __in const STRA &  strRhs,
-        __in BOOL           fIgnoreCase = FALSE
-    ) const;
-
-    static
-    BOOL
-    Equals(
-        __in PCSTR          pszLhs,
-        __in PCSTR          pszRhs,
-        __in bool           fIgnoreCase = false
-    )
-    {
-        // Return FALSE if either or both strings are NULL.
-        if (!pszLhs || !pszRhs) return FALSE;
-
-        if( fIgnoreCase )
-        {
-            return ( 0 == _stricmp( pszLhs, pszRhs ) );
-        }
-
-        return ( 0 == strcmp( pszLhs, pszRhs ) );
-    }
-
-    VOID
-    Trim();
-
-    BOOL
-    StartsWith(
-        __in const STRA *   pStraPrefix,
-        __in bool           fIgnoreCase = FALSE
-    ) const;
-
-    BOOL
-    StartsWith(
-        __in const STRA &   straPrefix,
-        __in bool           fIgnoreCase = FALSE
-    ) const;
-
-    BOOL
-    StartsWith(
-        __in PCSTR          pszPrefix,
-        __in bool           fIgnoreCase = FALSE
-    ) const;
-
-    BOOL
-    EndsWith(
-        __in const STRA *   pStraSuffix,
-        __in bool           fIgnoreCase = FALSE
-    ) const;
-
-    BOOL
-    EndsWith(
-        __in const STRA &   straSuffix,
-        __in bool           fIgnoreCase = FALSE
-    ) const;
-
-    BOOL
-    EndsWith(
-        __in PCSTR          pszSuffix,
-        __in bool           fIgnoreCase = FALSE
-    ) const;
-
-    INT
-    IndexOf(
-        __in CHAR           charValue,
-        __in DWORD          dwStartIndex = 0
-    ) const;
-
-    INT
-    IndexOf(
-        __in PCSTR          pszValue,
-        __in DWORD          dwStartIndex = 0
-    ) const;
-
-    INT
-    LastIndexOf(
-        __in CHAR           charValue,
-        __in DWORD          dwStartIndex = 0
-    ) const;
-
     DWORD
     QueryCB(
     ) const;
@@ -143,7 +57,6 @@ public:
     QueryStr(
     ) const;
 
-
     VOID EnsureNullTerminated();
 
     VOID
@@ -206,18 +119,6 @@ public:
         );
     }
 
-    HRESULT
-    CopyWTruncate(
-        __in PCWSTR pszCopyWTruncate
-    );
-
-    HRESULT
-    CopyWTruncate(
-        __in_ecount(cchLen)
-        PCWSTR          pszCopyWTruncate,
-        __in SIZE_T     cchLen
-    );
-
     HRESULT
     Append(
         __in PCSTR pszAppend
@@ -230,11 +131,6 @@ public:
         __in SIZE_T cbLen
     );
 
-    HRESULT
-    Append(
-        __in const STRA * pstrRhs
-    );
-
     HRESULT
     Append(
         __in const STRA & strRhs
@@ -279,36 +175,12 @@ public:
         );
     }
 
-    HRESULT
-    AppendWTruncate(
-        __in PCWSTR pszAppendWTruncate
-    );
-
-    HRESULT
-    AppendWTruncate(
-        __in_ecount(cchLen)
-        PCWSTR          pszAppendWTruncate,
-        __in SIZE_T     cchLen
-    );
-
     HRESULT
     CopyToBuffer(
         __out_bcount(*pcb) CHAR*    pszBuffer,
         __inout DWORD *             pcb
     ) const;
 
-    HRESULT
-    SetLen(
-        __in DWORD cchLen
-    );
-
-    HRESULT
-    SafeSnprintf(
-        __in __format_string
-        PCSTR       pszFormatString,
-        ...
-    );
-
     HRESULT
     SafeVsnprintf(
         __in __format_string
@@ -316,18 +188,6 @@ public:
         va_list     argsList
     );
 
-    HRESULT
-    Escape(
-    );
-
-    HRESULT
-    EscapeUtf8(
-    );
-
-    VOID
-    Unescape(
-    );
-
     HRESULT
     CopyWToUTF8Unescaped(
         __in LPCWSTR cpchStr
@@ -340,18 +200,6 @@ public:
         __in DWORD      cch
     );
 
-    HRESULT
-    CopyWToUTF8Escaped(
-        __in LPCWSTR cpchStr
-    );
-
-    HRESULT
-    CopyWToUTF8Escaped(
-        __in_ecount(cch)
-        LPCWSTR         cpchStr,
-        __in DWORD      cch
-    );
-
 private:
 
     //
@@ -434,15 +282,6 @@ private:
         __in UINT                   uCodePage
     );
 
-    static
-    HRESULT
-    ConvertUnicodeToMultiByte(
-        __in_ecount(dwStringLen)
-        LPCWSTR                     pszSrcUnicodeString,
-        __in BUFFER_T<CHAR,1> *     pbufDstAnsiString,
-        __in DWORD                  dwStringLen
-    );
-
     static
     HRESULT
     ConvertUnicodeToUTF8(
@@ -454,11 +293,6 @@ private:
 
     typedef bool (* PFN_F_SHOULD_ESCAPE)(BYTE ch);
 
-    HRESULT
-    EscapeInternal(
-        PFN_F_SHOULD_ESCAPE pfnFShouldEscape
-    );
-
     //
     // Buffer with an inline buffer of 1,
     // enough to hold null-terminating character.
@@ -467,28 +301,6 @@ private:
     DWORD               m_cchLen;
 };
 
-inline
-HRESULT
-AppendToString(
-    ULONGLONG Number,
-    STRA & String
-)
-{
-    // prefast complains Append requires input
-    // to be null terminated, so zero initialize
-    // and pass the size of the buffer minus one
-    // to _ui64toa_s
-    CHAR chNumber[32] = {0};
-    if (_ui64toa_s(Number,
-                   chNumber,
-                   sizeof(chNumber) - sizeof(CHAR),
-                   10) != 0)
-    {
-        return E_INVALIDARG;
-    }
-    return String.Append(chNumber);
-}
-
 template<DWORD size>
 CHAR* InitHelper(__out CHAR (&psz)[size])
 {
@@ -501,10 +313,3 @@ CHAR* InitHelper(__out CHAR (&psz)[size])
 //
 #define STACK_STRA(name, size)  CHAR __ach##name[size];\
                                 STRA  name(InitHelper(__ach##name), sizeof(__ach##name))
-
-#define INLINE_STRA(name, size) CHAR __ach##name[size];\
-                                STRA  name;
-
-#define INLINE_STRA_INIT(name) name(InitHelper(__ach##name), sizeof(__ach##name))
-
-#pragma warning( pop )

+ 0 - 850
src/Servers/IIS/AspNetCoreModuleV2/IISLib/treehash.h

@@ -1,850 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-
-#pragma once
-
-#include <crtdbg.h>
-#include "rwlock.h"
-#include "prime.h"
-
-template <class _Record>
-class TREE_HASH_NODE
-{
-    template <class _Record>
-    friend class TREE_HASH_TABLE;
-
- private:
-    // Next node in the hash table look-aside
-    TREE_HASH_NODE<_Record> *_pNext;
-
-    // links in the tree structure
-    TREE_HASH_NODE *    _pParentNode;
-    TREE_HASH_NODE *    _pFirstChild;
-    TREE_HASH_NODE *    _pNextSibling;
-
-    // actual record
-    _Record *           _pRecord;
-
-    // hash value
-    PCWSTR              _pszPath;
-    DWORD               _dwHash;
-};
-
-template <class _Record>
-class TREE_HASH_TABLE
-{
-protected:
-    typedef BOOL
-    (PFN_DELETE_IF)(
-        _Record *           pRecord,
-        PVOID               pvContext
-    );
-
-    typedef VOID
-    (PFN_APPLY)(
-        _Record *           pRecord,
-        PVOID               pvContext
-    );
-
-public:
-    TREE_HASH_TABLE(
-        BOOL    fCaseSensitive
-    ) : _ppBuckets( NULL ),
-        _nBuckets( 0 ),
-        _nItems( 0 ),
-        _fCaseSensitive( fCaseSensitive )
-    {
-    }
-
-    virtual
-    ~TREE_HASH_TABLE();
-
-    virtual
-    VOID
-    ReferenceRecord(
-        _Record *   pRecord
-    ) = 0;
-
-    virtual
-    VOID
-    DereferenceRecord(
-        _Record *   pRecord
-    ) = 0;
-
-    virtual
-    PCWSTR
-    GetKey(
-        _Record *   pRecord
-    ) = 0;
-
-    DWORD
-    Count()
-    {
-        return _nItems;
-    }
-
-    virtual
-    VOID
-    Clear();
-
-    HRESULT
-    Initialize(
-        DWORD           nBucketSize
-    );
-
-    DWORD
-    CalcHash(
-        PCWSTR      pszKey
-    )
-    {
-        return _fCaseSensitive ? HashString(pszKey) : HashStringNoCase(pszKey);
-    }
-
-    virtual
-    VOID
-    FindKey(
-        PCWSTR      pszKey,
-        _Record **  ppRecord
-    );
-
-    virtual
-    HRESULT
-    InsertRecord(
-        _Record *   pRecord
-    );
-
-    virtual
-    VOID
-    DeleteKey(
-        PCWSTR      pszKey
-    );
-
-    virtual
-    VOID
-    DeleteIf(
-        PFN_DELETE_IF       pfnDeleteIf,
-        PVOID               pvContext
-    );
-
-    VOID
-    Apply(
-        PFN_APPLY           pfnApply,
-        PVOID               pvContext
-    );
-
-private:
-
-    BOOL
-    FindNodeInternal(
-        PCWSTR                      pszKey,
-        DWORD                       dwHash,
-        TREE_HASH_NODE<_Record> **  ppNode,
-        TREE_HASH_NODE<_Record> *** pppPreviousNodeNextPointer = NULL
-    );
-
-    HRESULT
-    AddNodeInternal(
-        PCWSTR                      pszPath,
-        DWORD                       dwHash,
-        _Record *                   pRecord,
-        TREE_HASH_NODE<_Record> *   pParentNode,
-        TREE_HASH_NODE<_Record> **  ppNewNode
-    );
-
-    HRESULT
-    AllocateNode(
-        PCWSTR                      pszPath,
-        DWORD                       dwHash,
-        _Record *                   pRecord,
-        TREE_HASH_NODE<_Record> *   pParentNode,
-        TREE_HASH_NODE<_Record> **  ppNewNode
-    );
-
-    VOID
-    DeleteNode(
-        TREE_HASH_NODE<_Record> *   pNode
-    )
-    {
-        if (pNode->_pRecord != NULL)
-        {
-            DereferenceRecord(pNode->_pRecord);
-            pNode->_pRecord = NULL;
-        }
-
-        HeapFree(GetProcessHeap(),
-                 0,
-                 pNode);
-    }
-
-    VOID
-    DeleteNodeInternal(
-        TREE_HASH_NODE<_Record> **  ppPreviousNodeNextPointer,
-        TREE_HASH_NODE<_Record> *   pNode
-    );
-
-    VOID
-    RehashTableIfNeeded(
-        VOID
-    );
-
-    TREE_HASH_NODE<_Record> **  _ppBuckets;
-    DWORD                       _nBuckets;
-    DWORD                       _nItems;
-    BOOL                        _fCaseSensitive;
-    CWSDRWLock                  _tableLock;
-};
-
-template <class _Record>
-HRESULT
-TREE_HASH_TABLE<_Record>::AllocateNode(
-    PCWSTR                      pszPath,
-    DWORD                       dwHash,
-    _Record *                   pRecord,
-    TREE_HASH_NODE<_Record> *   pParentNode,
-    TREE_HASH_NODE<_Record> **  ppNewNode
-)
-{
-    //
-    // Allocate enough extra space for pszPath
-    //
-    DWORD cchPath = (DWORD) wcslen(pszPath);
-    if (cchPath >= ((0xffffffff - sizeof(TREE_HASH_NODE<_Record>))/sizeof(WCHAR) - 1))
-    {
-        return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
-    }
-    TREE_HASH_NODE<_Record> *pNode = (TREE_HASH_NODE<_Record> *)HeapAlloc(
-            GetProcessHeap(),
-            HEAP_ZERO_MEMORY,
-            sizeof(TREE_HASH_NODE<_Record>) + (cchPath+1)*sizeof(WCHAR));
-    if (pNode == NULL)
-    {
-        return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
-    }
-
-    memcpy(pNode+1, pszPath, (cchPath+1)*sizeof(WCHAR));
-    pNode->_pszPath = (PCWSTR)(pNode+1);
-    pNode->_dwHash = dwHash;
-    pNode->_pNext = pNode->_pNextSibling = pNode->_pFirstChild = NULL;
-    pNode->_pParentNode = pParentNode;
-    pNode->_pRecord = pRecord;
-
-    *ppNewNode = pNode;
-    return S_OK;
-}
-
-template <class _Record>
-HRESULT
-TREE_HASH_TABLE<_Record>::Initialize(
-    DWORD   nBuckets
-)
-{
-    HRESULT hr = S_OK;
-
-    if ( nBuckets == 0 )
-    {
-        hr = E_INVALIDARG;
-        goto Failed;
-    }
-
-    hr = _tableLock.Init();
-    if ( FAILED( hr ) )
-    {
-        goto Failed;
-    }
-
-    if (nBuckets >= 0xffffffff/sizeof(TREE_HASH_NODE<_Record> *))
-    {
-        hr = E_INVALIDARG;
-        goto Failed;
-    }
-
-    _ppBuckets = (TREE_HASH_NODE<_Record> **)HeapAlloc(
-                            GetProcessHeap(),
-                            HEAP_ZERO_MEMORY,
-                            nBuckets*sizeof(TREE_HASH_NODE<_Record> *));
-    if (_ppBuckets == NULL)
-    {
-        hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
-        goto Failed;
-    }
-    _nBuckets = nBuckets;
-
-    return S_OK;
-
-Failed:
-
-    if (_ppBuckets)
-    {
-        HeapFree(GetProcessHeap(),
-                 0,
-                 _ppBuckets);
-        _ppBuckets = NULL;
-    }
-
-    return hr;
-}
-
-
-template <class _Record>
-TREE_HASH_TABLE<_Record>::~TREE_HASH_TABLE()
-{
-    if (_ppBuckets == NULL)
-    {
-        return;
-    }
-
-    _ASSERTE(_nItems == 0);
-
-    HeapFree(GetProcessHeap(),
-             0,
-             _ppBuckets);
-    _ppBuckets = NULL;
-    _nBuckets = 0;
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::Clear()
-{
-    TREE_HASH_NODE<_Record> *pCurrent;
-    TREE_HASH_NODE<_Record> *pNext;
-
-    _tableLock.ExclusiveAcquire();
-
-    for (DWORD i=0; i<_nBuckets; i++)
-    {
-        pCurrent = _ppBuckets[i];
-        _ppBuckets[i] = NULL;
-        while (pCurrent != NULL)
-        {
-            pNext = pCurrent->_pNext;
-            DeleteNode(pCurrent);
-            pCurrent = pNext;
-        }
-    }
-
-    _nItems = 0;
-    _tableLock.ExclusiveRelease();
-}
-
-template <class _Record>
-BOOL
-TREE_HASH_TABLE<_Record>::FindNodeInternal(
-    PCWSTR                  pszKey,
-    DWORD                   dwHash,
-    TREE_HASH_NODE<_Record> **   ppNode,
-    TREE_HASH_NODE<_Record> ***  pppPreviousNodeNextPointer
-)
-/*++
-  Return value indicates whether the item is found
-  key, dwHash - key and hash for the node to find
-  ppNode - on successful return, the node found, on failed return, the first
-  node with hash value greater than the node to be found
-  pppPreviousNodeNextPointer - the pointer to previous node's _pNext
-
-  This routine may be called under either read or write lock
---*/
-{
-    TREE_HASH_NODE<_Record> **ppPreviousNodeNextPointer;
-    TREE_HASH_NODE<_Record> *pNode;
-    BOOL fFound = FALSE;
-
-    ppPreviousNodeNextPointer = _ppBuckets + (dwHash % _nBuckets);
-    pNode = *ppPreviousNodeNextPointer;
-    while (pNode != NULL)
-    {
-        if (pNode->_dwHash == dwHash)
-        {
-            if (CompareStringOrdinal(pszKey,
-                                     -1,
-                                     pNode->_pszPath,
-                                     -1,
-                                     !_fCaseSensitive) == CSTR_EQUAL)
-            {
-                fFound = TRUE;
-                break;
-            }
-        }
-        else if (pNode->_dwHash > dwHash)
-        {
-            break;
-        }
-
-        ppPreviousNodeNextPointer = &(pNode->_pNext);
-        pNode = *ppPreviousNodeNextPointer;
-    }
-
-    *ppNode = pNode;
-    if (pppPreviousNodeNextPointer != NULL)
-    {
-        *pppPreviousNodeNextPointer = ppPreviousNodeNextPointer;
-    }
-    return fFound;
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::FindKey(
-    PCWSTR              pszKey,
-    _Record **          ppRecord
-)
-{
-    TREE_HASH_NODE<_Record> *pNode;
-
-    *ppRecord = NULL;
-
-    DWORD dwHash = CalcHash(pszKey);
-
-    _tableLock.SharedAcquire();
-
-    if (FindNodeInternal(pszKey, dwHash, &pNode) &&
-        pNode->_pRecord != NULL)
-    {
-        ReferenceRecord(pNode->_pRecord);
-        *ppRecord = pNode->_pRecord;
-    }
-
-    _tableLock.SharedRelease();
-}
-
-template <class _Record>
-HRESULT
-TREE_HASH_TABLE<_Record>::AddNodeInternal(
-    PCWSTR                      pszPath,
-    DWORD                       dwHash,
-    _Record *                   pRecord,
-    TREE_HASH_NODE<_Record> *   pParentNode,
-    TREE_HASH_NODE<_Record> **  ppNewNode
-)
-/*++
-  Return value is HRESULT indicating success or failure
-  pszPath, dwHash, pRecord - path, hash value and record to be inserted
-  pParentNode - this will be the parent of the node being inserted
-  ppNewNode - on successful return, the new node created and inserted
-
-  This function may be called under a read or write lock
---*/
-{
-    TREE_HASH_NODE<_Record> *pNewNode;
-    TREE_HASH_NODE<_Record> *pNextNode;
-    TREE_HASH_NODE<_Record> **ppNextPointer;
-    HRESULT hr;
-
-    //
-    // Ownership of pRecord is not transferred to pNewNode yet, so remember
-    // to either set it to null before deleting pNewNode or add an extra
-    // reference later - this is to make sure we do not do an extra ref/deref
-    // which users may view as getting flushed out of the hash-table
-    //
-    hr = AllocateNode(pszPath,
-                      dwHash,
-                      pRecord,
-                      pParentNode,
-                      &pNewNode);
-    if (FAILED(hr))
-    {
-        return hr;
-    }
-
-    do
-    {
-        //
-        // Find the right place to add this node
-        //
-
-        if (FindNodeInternal(pszPath, dwHash, &pNextNode, &ppNextPointer))
-        {
-            //
-            // If node already there, record may still need updating
-            //
-            if (pRecord != NULL &&
-                InterlockedCompareExchangePointer((PVOID *)&pNextNode->_pRecord,
-                                                  pRecord,
-                                                  NULL) == NULL)
-            {
-                ReferenceRecord(pRecord);
-                hr = S_OK;
-            }
-            else
-            {
-                hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
-            }
-
-            // ownership of pRecord has either passed to existing record or
-            // not to anyone at all
-            pNewNode->_pRecord = NULL;
-            DeleteNode(pNewNode);
-            *ppNewNode = pNextNode;
-            return hr;
-        }
-
-        //
-        // If another node got inserted in betwen, we will have to retry
-        //
-        pNewNode->_pNext = pNextNode;
-    } while (InterlockedCompareExchangePointer((PVOID *)ppNextPointer,
-                                               pNewNode,
-                                               pNextNode) != pNextNode);
-    // pass ownership of pRecord now
-    if (pRecord != NULL)
-    {
-        ReferenceRecord(pRecord);
-        pRecord = NULL;
-    }
-    InterlockedIncrement((LONG *)&_nItems);
-
-    //
-    // update the parent
-    //
-    if (pParentNode != NULL)
-    {
-        ppNextPointer = &pParentNode->_pFirstChild;
-        do
-        {
-            pNextNode = *ppNextPointer;
-            pNewNode->_pNextSibling = pNextNode;
-        } while (InterlockedCompareExchangePointer((PVOID *)ppNextPointer,
-                                                   pNewNode,
-                                                   pNextNode) != pNextNode);
-    }
-
-    *ppNewNode = pNewNode;
-    return S_OK;
-}
-
-template <class _Record>
-HRESULT
-TREE_HASH_TABLE<_Record>::InsertRecord(
-    _Record *           pRecord
-)
-/*++
-  This method inserts a node for this record and also empty nodes for paths
-  in the hierarchy leading upto this path
-
-  The insert is done under only a read-lock - this is possible by keeping
-  the hashes in a bucket in increasing order and using interlocked operations
-  to actually insert the item in the hash-bucket lookaside list and the parent
-  children list
-
-  Returns HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) if the record already exists.
-  Never leak this error to the end user because "*file* already exists" may be confusing.
---*/
-{
-    PCWSTR pszKey = GetKey(pRecord);
-    STACK_STRU( strPartialPath, 256);
-    PWSTR pszPartialPath;
-    DWORD dwHash;
-    DWORD cchEnd;
-    HRESULT hr;
-    TREE_HASH_NODE<_Record> *pParentNode = NULL;
-
-    hr = strPartialPath.Copy(pszKey);
-    if (FAILED(hr))
-    {
-        goto Finished;
-    }
-    pszPartialPath = strPartialPath.QueryStr();
-
-    _tableLock.SharedAcquire();
-
-    //
-    // First find the lowest parent node present
-    //
-    for (cchEnd = strPartialPath.QueryCCH() - 1; cchEnd > 0; cchEnd--)
-    {
-        if (pszPartialPath[cchEnd] == L'/' || pszPartialPath[cchEnd] == L'\\')
-        {
-            pszPartialPath[cchEnd] = L'\0';
-
-            dwHash = CalcHash(pszPartialPath);
-            if (FindNodeInternal(pszPartialPath, dwHash, &pParentNode))
-            {
-                pszPartialPath[cchEnd] = pszKey[cchEnd];
-                break;
-            }
-            pParentNode = NULL;
-        }
-    }
-
-    //
-    // Now go ahead and add the rest of the tree (including our record)
-    //
-    for (; cchEnd <= strPartialPath.QueryCCH(); cchEnd++)
-    {
-        if (pszPartialPath[cchEnd] == L'\0')
-        {
-            dwHash = CalcHash(pszPartialPath);
-            hr = AddNodeInternal(
-                    pszPartialPath,
-                    dwHash,
-                    (cchEnd == strPartialPath.QueryCCH()) ? pRecord : NULL,
-                    pParentNode,
-                    &pParentNode);
-            if (FAILED(hr) &&
-                hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS))
-            {
-                goto Finished;
-            }
-
-            pszPartialPath[cchEnd] = pszKey[cchEnd];
-        }
-    }
-
-Finished:
-    _tableLock.SharedRelease();
-
-    if (SUCCEEDED(hr))
-    {
-        RehashTableIfNeeded();
-    }
-
-    return hr;
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::DeleteNodeInternal(
-    TREE_HASH_NODE<_Record> **  ppNextPointer,
-    TREE_HASH_NODE<_Record> *   pNode
-)
-/*++
-  pNode is the node to be deleted
-  ppNextPointer is the pointer to the previous node's next pointer pointing
-  to this node
-
-  This function should be called under write-lock
---*/
-{
-    //
-    // First remove this node from hash table
-    //
-    *ppNextPointer = pNode->_pNext;
-
-    //
-    // Now fixup parent
-    //
-    if (pNode->_pParentNode != NULL)
-    {
-        ppNextPointer = &pNode->_pParentNode->_pFirstChild;
-        while (*ppNextPointer != pNode)
-        {
-            ppNextPointer = &(*ppNextPointer)->_pNextSibling;
-        }
-        *ppNextPointer = pNode->_pNextSibling;
-    }
-
-    //
-    // Now remove all children recursively
-    //
-    TREE_HASH_NODE<_Record> *pChild = pNode->_pFirstChild;
-    TREE_HASH_NODE<_Record> *pNextChild;
-    while (pChild != NULL)
-    {
-        pNextChild = pChild->_pNextSibling;
-
-        ppNextPointer = _ppBuckets + (pChild->_dwHash % _nBuckets);
-        while (*ppNextPointer != pChild)
-        {
-            ppNextPointer = &(*ppNextPointer)->_pNext;
-        }
-        pChild->_pParentNode = NULL;
-        DeleteNodeInternal(ppNextPointer, pChild);
-
-        pChild = pNextChild;
-    }
-
-    DeleteNode(pNode);
-    _nItems--;
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::DeleteKey(
-    PCWSTR      pszKey
-)
-{
-    TREE_HASH_NODE<_Record> *pNode;
-    TREE_HASH_NODE<_Record> **ppPreviousNodeNextPointer;
-
-    DWORD dwHash = CalcHash(pszKey);
-
-    _tableLock.ExclusiveAcquire();
-
-    if (FindNodeInternal(pszKey, dwHash, &pNode, &ppPreviousNodeNextPointer))
-    {
-        DeleteNodeInternal(ppPreviousNodeNextPointer, pNode);
-    }
-
-    _tableLock.ExclusiveRelease();
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::DeleteIf(
-    PFN_DELETE_IF               pfnDeleteIf,
-    PVOID                       pvContext
-)
-{
-    TREE_HASH_NODE<_Record> *pNode;
-    TREE_HASH_NODE<_Record> **ppPreviousNodeNextPointer;
-    BOOL fDelete;
-
-    _tableLock.ExclusiveAcquire();
-
-    for (DWORD i=0; i<_nBuckets; i++)
-    {
-        ppPreviousNodeNextPointer = _ppBuckets + i;
-        pNode = *ppPreviousNodeNextPointer;
-        while (pNode != NULL)
-        {
-            //
-            // Non empty nodes deleted based on DeleteIf, empty nodes deleted
-            // if they have no children
-            //
-            fDelete = FALSE;
-            if (pNode->_pRecord != NULL)
-            {
-                if (pfnDeleteIf(pNode->_pRecord, pvContext))
-                {
-                    fDelete = TRUE;
-                }
-            }
-            else if (pNode->_pFirstChild == NULL)
-            {
-                fDelete =  TRUE;
-            }
-
-            if (fDelete)
-            {
-                if (pNode->_pFirstChild == NULL)
-                {
-                    DeleteNodeInternal(ppPreviousNodeNextPointer, pNode);
-                }
-                else
-                {
-                    DereferenceRecord(pNode->_pRecord);
-                    pNode->_pRecord = NULL;
-                }
-            }
-            else
-            {
-                ppPreviousNodeNextPointer = &pNode->_pNext;
-            }
-
-            pNode = *ppPreviousNodeNextPointer;
-        }
-    }
-
-    _tableLock.ExclusiveRelease();
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::Apply(
-    PFN_APPLY                   pfnApply,
-    PVOID                       pvContext
-)
-{
-    TREE_HASH_NODE<_Record> *pNode;
-
-    _tableLock.SharedAcquire();
-
-    for (DWORD i=0; i<_nBuckets; i++)
-    {
-        pNode = _ppBuckets[i];
-        while (pNode != NULL)
-        {
-            if (pNode->_pRecord != NULL)
-            {
-                pfnApply(pNode->_pRecord, pvContext);
-            }
-
-            pNode = pNode->_pNext;
-        }
-    }
-
-    _tableLock.SharedRelease();
-}
-
-template <class _Record>
-VOID
-TREE_HASH_TABLE<_Record>::RehashTableIfNeeded(
-    VOID
-)
-{
-    TREE_HASH_NODE<_Record> **ppBuckets;
-    DWORD nBuckets;
-    TREE_HASH_NODE<_Record> *pNode;
-    TREE_HASH_NODE<_Record> *pNextNode;
-    TREE_HASH_NODE<_Record> **ppNextPointer;
-    TREE_HASH_NODE<_Record> *pNewNextNode;
-    DWORD               nNewBuckets;
-
-    //
-    // If number of items has become too many, we will double the hash table
-    // size (we never reduce it however)
-    //
-    if (_nItems <= PRIME::GetPrime(2*_nBuckets))
-    {
-        return;
-    }
-
-    _tableLock.ExclusiveAcquire();
-
-    nNewBuckets = PRIME::GetPrime(2*_nBuckets);
-
-    if (_nItems <= nNewBuckets)
-    {
-        goto Finished;
-    }
-
-    nBuckets = nNewBuckets;
-    if (nBuckets >= 0xffffffff/sizeof(TREE_HASH_NODE<_Record> *))
-    {
-        goto Finished;
-    }
-    ppBuckets = (TREE_HASH_NODE<_Record> **)HeapAlloc(
-                        GetProcessHeap(),
-                        HEAP_ZERO_MEMORY,
-                        nBuckets*sizeof(TREE_HASH_NODE<_Record> *));
-    if (ppBuckets == NULL)
-    {
-        goto Finished;
-    }
-
-    //
-    // Take out nodes from the old hash table and insert in the new one, make
-    // sure to keep the hashes in increasing order
-    //
-    for (DWORD i=0; i<_nBuckets; i++)
-    {
-        pNode = _ppBuckets[i];
-        while (pNode != NULL)
-        {
-            pNextNode = pNode->_pNext;
-
-            ppNextPointer = ppBuckets + (pNode->_dwHash % nBuckets);
-            pNewNextNode = *ppNextPointer;
-            while (pNewNextNode != NULL &&
-                   pNewNextNode->_dwHash <= pNode->_dwHash)
-            {
-                ppNextPointer = &pNewNextNode->_pNext;
-                pNewNextNode = pNewNextNode->_pNext;
-            }
-            pNode->_pNext = pNewNextNode;
-            *ppNextPointer = pNode;
-
-            pNode = pNextNode;
-        }
-    }
-
-    HeapFree(GetProcessHeap(), 0, _ppBuckets);
-    _ppBuckets = ppBuckets;
-    _nBuckets = nBuckets;
-    ppBuckets = NULL;
-
-Finished:
-
-    _tableLock.ExclusiveRelease();
-}
-