428 lines
8.4 KiB
C++
428 lines
8.4 KiB
C++
// 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 "buffer.h"
|
|
#include <strsafe.h>
|
|
|
|
class STRU
|
|
{
|
|
|
|
public:
|
|
|
|
STRU(
|
|
VOID
|
|
);
|
|
|
|
STRU(
|
|
__inout_ecount(cchInit) WCHAR* pbInit,
|
|
__in DWORD cchInit
|
|
);
|
|
|
|
BOOL
|
|
IsEmpty(
|
|
VOID
|
|
) const;
|
|
|
|
BOOL
|
|
Equals(
|
|
__in const STRU * pstrRhs,
|
|
__in BOOL fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
_ASSERTE( pstrRhs != NULL );
|
|
return Equals( pstrRhs->QueryStr(), fIgnoreCase );
|
|
}
|
|
|
|
BOOL
|
|
Equals(
|
|
__in const STRU & strRhs,
|
|
__in BOOL fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
return Equals( strRhs.QueryStr(), fIgnoreCase );
|
|
}
|
|
|
|
BOOL
|
|
Equals(
|
|
__in PCWSTR pszRhs,
|
|
__in BOOL fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
_ASSERTE( NULL != pszRhs );
|
|
if ( NULL == pszRhs )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
#if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN
|
|
|
|
return ( CSTR_EQUAL == CompareStringOrdinal( QueryStr(),
|
|
QueryCCH(),
|
|
pszRhs,
|
|
-1,
|
|
fIgnoreCase ) );
|
|
#else
|
|
|
|
if( fIgnoreCase )
|
|
{
|
|
return ( 0 == _wcsicmp( QueryStr(), pszRhs ) );
|
|
}
|
|
return ( 0 == wcscmp( QueryStr(), pszRhs ) );
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
static
|
|
BOOL
|
|
Equals(
|
|
__in PCWSTR pwszLhs,
|
|
__in PCWSTR pwszRhs,
|
|
__in bool fIgnoreCase = false
|
|
)
|
|
{
|
|
// Return FALSE if either or both strings are NULL.
|
|
if (!pwszLhs || !pwszRhs) return FALSE;
|
|
|
|
//
|
|
// This method performs a ordinal string comparison when OS is Vista or
|
|
// greater and a culture sensitive comparison if not (XP). This is
|
|
// consistent with the existing Equals implementation (see above).
|
|
//
|
|
#if defined( NTDDI_VERSION ) && NTDDI_VERSION >= NTDDI_LONGHORN
|
|
|
|
return ( CSTR_EQUAL == CompareStringOrdinal( pwszLhs,
|
|
-1,
|
|
pwszRhs,
|
|
-1,
|
|
fIgnoreCase ) );
|
|
#else
|
|
|
|
if( fIgnoreCase )
|
|
{
|
|
return ( 0 == _wcsicmp( pwszLhs, pwszRhs ) );
|
|
}
|
|
else
|
|
{
|
|
return ( 0 == wcscmp( pwszLhs, pwszRhs ) );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
VOID
|
|
Trim();
|
|
|
|
BOOL
|
|
StartsWith(
|
|
__in const STRU * pStruPrefix,
|
|
__in bool fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
_ASSERTE( pStruPrefix != NULL );
|
|
return StartsWith( pStruPrefix->QueryStr(), fIgnoreCase );
|
|
}
|
|
|
|
BOOL
|
|
StartsWith(
|
|
__in const STRU & struPrefix,
|
|
__in bool fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
return StartsWith( struPrefix.QueryStr(), fIgnoreCase );
|
|
}
|
|
|
|
BOOL
|
|
StartsWith(
|
|
__in PCWSTR pwszPrefix,
|
|
__in bool fIgnoreCase = FALSE
|
|
) const;
|
|
|
|
BOOL
|
|
EndsWith(
|
|
__in const STRU * pStruSuffix,
|
|
__in bool fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
_ASSERTE( pStruSuffix != NULL );
|
|
return EndsWith( pStruSuffix->QueryStr(), fIgnoreCase );
|
|
}
|
|
|
|
BOOL
|
|
EndsWith(
|
|
__in const STRU & struSuffix,
|
|
__in bool fIgnoreCase = FALSE
|
|
) const
|
|
{
|
|
return EndsWith( struSuffix.QueryStr(), fIgnoreCase );
|
|
}
|
|
|
|
BOOL
|
|
EndsWith(
|
|
__in PCWSTR pwszSuffix,
|
|
__in bool fIgnoreCase = FALSE
|
|
) const;
|
|
|
|
INT
|
|
IndexOf(
|
|
__in WCHAR charValue,
|
|
__in DWORD dwStartIndex = 0
|
|
) const;
|
|
|
|
INT
|
|
IndexOf(
|
|
__in PCWSTR pwszValue,
|
|
__in DWORD dwStartIndex = 0
|
|
) const;
|
|
|
|
INT
|
|
LastIndexOf(
|
|
__in WCHAR charValue,
|
|
__in DWORD dwStartIndex = 0
|
|
) const;
|
|
|
|
DWORD
|
|
QueryCB(
|
|
VOID
|
|
) const;
|
|
|
|
DWORD
|
|
QueryCCH(
|
|
VOID
|
|
) const;
|
|
|
|
DWORD
|
|
QuerySizeCCH(
|
|
VOID
|
|
) const;
|
|
|
|
__nullterminated
|
|
__ecount(this->m_cchLen)
|
|
WCHAR*
|
|
QueryStr(
|
|
VOID
|
|
) const;
|
|
|
|
VOID
|
|
Reset(
|
|
VOID
|
|
);
|
|
|
|
HRESULT
|
|
Resize(
|
|
DWORD cchSize
|
|
);
|
|
|
|
HRESULT
|
|
SyncWithBuffer(
|
|
VOID
|
|
);
|
|
|
|
template<size_t size>
|
|
HRESULT
|
|
Copy(
|
|
__in PCWSTR const (&rgpszStrings)[size]
|
|
)
|
|
//
|
|
// Copies an array of strings declared as stack array. For example:
|
|
//
|
|
// LPCWSTR rgExample[] { L"one", L"two" };
|
|
// hr = str.Copy( rgExample );
|
|
//
|
|
{
|
|
Reset();
|
|
|
|
return AuxAppend( rgpszStrings, _countof( rgpszStrings ) );
|
|
}
|
|
|
|
HRESULT
|
|
Copy(
|
|
__in PCWSTR pszCopy
|
|
);
|
|
|
|
HRESULT
|
|
Copy(
|
|
__in_ecount(cchLen)
|
|
PCWSTR pszCopy,
|
|
SIZE_T cchLen
|
|
);
|
|
|
|
HRESULT
|
|
Copy(
|
|
__in const STRU * pstrRhs
|
|
);
|
|
|
|
HRESULT
|
|
Copy(
|
|
__in const STRU & str
|
|
);
|
|
|
|
HRESULT
|
|
CopyAndExpandEnvironmentStrings(
|
|
__in PCWSTR pszSource
|
|
);
|
|
|
|
HRESULT
|
|
CopyA(
|
|
__in PCSTR pszCopyA
|
|
);
|
|
|
|
HRESULT
|
|
CopyA(
|
|
__in_bcount(cchLen)
|
|
PCSTR pszCopyA,
|
|
SIZE_T cchLen,
|
|
UINT CodePage = CP_UTF8
|
|
);
|
|
|
|
template<size_t size>
|
|
HRESULT
|
|
Append(
|
|
__in PCWSTR const (&rgpszStrings)[size]
|
|
)
|
|
//
|
|
// Appends an array of strings declared as stack array. For example:
|
|
//
|
|
// LPCWSTR rgExample[] { L"one", L"two" };
|
|
// hr = str.Append( rgExample );
|
|
//
|
|
{
|
|
return AuxAppend( rgpszStrings, _countof( rgpszStrings ) );
|
|
}
|
|
|
|
HRESULT
|
|
Append(
|
|
__in PCWSTR pszAppend
|
|
);
|
|
|
|
HRESULT
|
|
Append(
|
|
__in_ecount(cchLen)
|
|
PCWSTR pszAppend,
|
|
SIZE_T cchLen
|
|
);
|
|
|
|
HRESULT
|
|
Append(
|
|
__in const STRU * pstrRhs
|
|
);
|
|
|
|
HRESULT
|
|
Append(
|
|
__in const STRU & strRhs
|
|
);
|
|
|
|
HRESULT
|
|
AppendA(
|
|
__in PCSTR pszAppendA
|
|
);
|
|
|
|
HRESULT
|
|
AppendA(
|
|
__in_bcount(cchLen)
|
|
PCSTR pszAppendA,
|
|
SIZE_T cchLen,
|
|
UINT CodePage = CP_UTF8
|
|
);
|
|
|
|
HRESULT
|
|
CopyToBuffer(
|
|
__out_bcount(*pcb) WCHAR* pszBuffer,
|
|
PDWORD pcb
|
|
) const;
|
|
|
|
HRESULT
|
|
SetLen(
|
|
__in DWORD cchLen
|
|
);
|
|
|
|
HRESULT
|
|
SafeSnwprintf(
|
|
__in PCWSTR pwszFormatString,
|
|
...
|
|
);
|
|
|
|
HRESULT
|
|
SafeVsnwprintf(
|
|
__in PCWSTR pwszFormatString,
|
|
va_list argsList
|
|
);
|
|
|
|
static
|
|
HRESULT ExpandEnvironmentVariables(
|
|
__in PCWSTR pszString,
|
|
__out STRU * pstrExpandedString
|
|
);
|
|
|
|
private:
|
|
|
|
//
|
|
// Avoid C++ errors. This object should never go through a copy
|
|
// constructor, unintended cast or assignment.
|
|
//
|
|
STRU( const STRU & );
|
|
STRU & operator = ( const STRU & );
|
|
|
|
HRESULT
|
|
AuxAppend(
|
|
__in_ecount(cNumStrings)
|
|
PCWSTR const rgpszStrings[],
|
|
SIZE_T cNumStrings
|
|
);
|
|
|
|
HRESULT
|
|
AuxAppend(
|
|
__in_bcount(cbStr)
|
|
const WCHAR* pStr,
|
|
SIZE_T cbStr,
|
|
DWORD cbOffset
|
|
);
|
|
|
|
HRESULT
|
|
AuxAppendA(
|
|
__in_bcount(cbStr)
|
|
const CHAR* pStr,
|
|
SIZE_T cbStr,
|
|
DWORD cbOffset,
|
|
UINT CodePage
|
|
);
|
|
|
|
//
|
|
// Buffer with an inline buffer of 1,
|
|
// enough to hold null-terminating character.
|
|
//
|
|
BUFFER_T<WCHAR,1> m_Buff;
|
|
DWORD m_cchLen;
|
|
};
|
|
|
|
//
|
|
// Helps to initialize an external buffer before
|
|
// constructing the STRU object.
|
|
//
|
|
template<DWORD size>
|
|
WCHAR* InitHelper(__out WCHAR (&psz)[size])
|
|
{
|
|
psz[0] = L'\0';
|
|
return psz;
|
|
}
|
|
|
|
//
|
|
// Heap operation reduction macros
|
|
//
|
|
#define STACK_STRU(name, size) WCHAR __ach##name[size];\
|
|
STRU name(InitHelper(__ach##name), sizeof(__ach##name)/sizeof(*__ach##name))
|
|
|
|
#define INLINE_STRU(name, size) WCHAR __ach##name[size];\
|
|
STRU name;
|
|
|
|
#define INLINE_STRU_INIT(name) name(InitHelper(__ach##name), sizeof(__ach##name)/sizeof(*__ach##name))
|
|
|
|
|
|
HRESULT
|
|
MakePathCanonicalizationProof(
|
|
IN PCWSTR pszName,
|
|
OUT STRU * pstrPath
|
|
);
|