You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
536 lines
15 KiB
536 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
vs_str.hxx
|
|
|
|
Abstract:
|
|
|
|
Various defines for general usage
|
|
|
|
Author:
|
|
|
|
Adi Oltean [aoltean] 07/09/1999
|
|
|
|
Revision History:
|
|
|
|
Name Date Comments
|
|
aoltean 07/09/1999 Created
|
|
aoltean 08/11/1999 Adding throw specification
|
|
aoltean 09/03/1999 Adding DuplicateXXX functions
|
|
aoltean 09/09/1999 dss -> vss
|
|
aoltean 09/20/1999 Adding ThrowIf, Err, Msg, MsgNoCR, etc.
|
|
|
|
--*/
|
|
|
|
#ifndef __VSS_STR_HXX__
|
|
#define __VSS_STR_HXX__
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Standard foo for file name aliasing. This code block must be after
|
|
// all includes of VSS header files.
|
|
//
|
|
#ifdef VSS_FILE_ALIAS
|
|
#undef VSS_FILE_ALIAS
|
|
#endif
|
|
#define VSS_FILE_ALIAS "INCSTRH"
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Misc string routines
|
|
|
|
|
|
inline void VssDuplicateStr(
|
|
OUT LPWSTR& pwszDestination,
|
|
IN LPCWSTR pwszSource
|
|
)
|
|
{
|
|
BS_ASSERT(pwszDestination == NULL);
|
|
|
|
if (pwszSource == NULL)
|
|
pwszDestination = NULL;
|
|
else
|
|
{
|
|
pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource)));
|
|
if (pwszDestination != NULL)
|
|
::wcscpy(pwszDestination, pwszSource);
|
|
}
|
|
}
|
|
|
|
|
|
inline void VssSafeDuplicateStr(
|
|
IN CVssFunctionTracer& ft,
|
|
OUT LPWSTR& pwszDestination,
|
|
IN LPCWSTR pwszSource
|
|
) throw(HRESULT)
|
|
{
|
|
BS_ASSERT(pwszDestination == NULL);
|
|
|
|
if (pwszSource == NULL)
|
|
pwszDestination = NULL;
|
|
else
|
|
{
|
|
pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource)));
|
|
if (pwszDestination == NULL)
|
|
ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
::wcscpy(pwszDestination, pwszSource);
|
|
}
|
|
}
|
|
|
|
|
|
inline LPWSTR VssAllocString(
|
|
IN CVssFunctionTracer& ft,
|
|
IN size_t nStringLength
|
|
)
|
|
{
|
|
BS_ASSERT(nStringLength > 0);
|
|
LPWSTR pwszStr = reinterpret_cast<LPWSTR>(::CoTaskMemAlloc((nStringLength + 1) * sizeof(WCHAR)));
|
|
if (pwszStr == NULL)
|
|
ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
return pwszStr;
|
|
}
|
|
|
|
|
|
inline void VssFreeString(
|
|
IN OUT LPCWSTR& pwszString
|
|
)
|
|
{
|
|
::CoTaskMemFree(const_cast<LPWSTR>(pwszString));
|
|
pwszString = NULL;
|
|
}
|
|
|
|
|
|
inline LPWSTR VssReallocString(
|
|
IN CVssFunctionTracer& ft,
|
|
IN LPWSTR pwszString,
|
|
IN LONG lNewStrLen // Without the zero character.
|
|
)
|
|
{
|
|
LPWSTR pwszNewString = (LPWSTR)::CoTaskMemRealloc( (PVOID)(pwszString),
|
|
sizeof(WCHAR) * (lNewStrLen + 1));
|
|
if (pwszNewString == NULL)
|
|
ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
|
|
|
|
return pwszNewString;
|
|
}
|
|
|
|
|
|
inline bool VssIsStrEqual(
|
|
IN LPCWSTR wsz1,
|
|
IN LPCWSTR wsz2
|
|
)
|
|
{
|
|
if ((wsz1 == NULL) && (wsz2 == NULL))
|
|
return true;
|
|
if (wsz1 && wsz2 && (::wcscmp(wsz1, wsz2) == 0) )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
inline void VssConcatenate(
|
|
IN CVssFunctionTracer& ft,
|
|
IN OUT LPWSTR pwszDestination,
|
|
IN size_t nDestinationLength,
|
|
IN LPCWSTR wszSource1,
|
|
IN LPCWSTR wszSource2
|
|
)
|
|
{
|
|
BS_ASSERT(pwszDestination);
|
|
BS_ASSERT(wszSource1);
|
|
BS_ASSERT(wszSource2);
|
|
BS_ASSERT(nDestinationLength > 0);
|
|
|
|
// Check if the buffer is passed
|
|
if (::wcslen(wszSource1) + ::wcslen(wszSource2) > nDestinationLength ) {
|
|
BS_ASSERT(false);
|
|
ft.Throw( VSSDBG_SWPRV, E_UNEXPECTED,
|
|
L"Buffer not large enough. ( %d + %d > %d )",
|
|
::wcslen(wszSource1), ::wcslen(wszSource2), nDestinationLength);
|
|
}
|
|
|
|
::wcscpy(pwszDestination, wszSource1);
|
|
::wcscat(pwszDestination, wszSource2);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Automatic auto-string class
|
|
|
|
class CVssAutoPWSZ
|
|
{
|
|
// Constructors/destructors
|
|
private:
|
|
CVssAutoPWSZ(const CVssAutoPWSZ&);
|
|
|
|
public:
|
|
CVssAutoPWSZ(LPWSTR pwsz = NULL): m_pwsz(pwsz) {};
|
|
|
|
// Automatically closes the handle
|
|
~CVssAutoPWSZ() {
|
|
Clear();
|
|
};
|
|
|
|
// Operations
|
|
public:
|
|
|
|
void Allocate(size_t nCharCount) throw(HRESULT)
|
|
{
|
|
CVssFunctionTracer ft( VSSDBG_GEN, L"CVssAutoPWSZ::Allocate" );
|
|
|
|
Clear();
|
|
m_pwsz = ::VssAllocString(ft, nCharCount);
|
|
}
|
|
|
|
bool CopyFrom(LPCWSTR pwsz)
|
|
{
|
|
::VssFreeString(m_pwsz);
|
|
::VssDuplicateStr(m_pwsz, pwsz);
|
|
return (m_pwsz != NULL);
|
|
}
|
|
|
|
void TransferFrom(CVssAutoPWSZ& source)
|
|
{
|
|
Clear();
|
|
m_pwsz = source.Detach();
|
|
}
|
|
|
|
LPWSTR Detach()
|
|
{
|
|
LPWSTR pwsz = m_pwsz;
|
|
m_pwsz = NULL;
|
|
return pwsz;
|
|
}
|
|
|
|
// Returns the value of the actual handle
|
|
LPWSTR & GetRef() {
|
|
return m_pwsz;
|
|
}
|
|
|
|
// Clears the contents of the auto string
|
|
void Clear() {
|
|
::VssFreeString(m_pwsz);
|
|
}
|
|
|
|
// Returns the value of the actual handle
|
|
operator LPWSTR () const {
|
|
return m_pwsz;
|
|
}
|
|
|
|
// Returns the value of the actual handle
|
|
operator LPCWSTR () const {
|
|
return const_cast<LPCWSTR>(m_pwsz);
|
|
}
|
|
|
|
// Implementation
|
|
private:
|
|
LPWSTR m_pwsz;
|
|
};
|
|
|
|
|
|
|
|
class CVssComBSTR
|
|
{
|
|
public:
|
|
BSTR m_str;
|
|
CVssComBSTR()
|
|
{
|
|
m_str = NULL;
|
|
}
|
|
/*explicit*/ CVssComBSTR(int nSize)
|
|
{
|
|
m_str = ::SysAllocStringLen(NULL, nSize);
|
|
if ((m_str == NULL) && (nSize != 0))
|
|
throw(E_OUTOFMEMORY);
|
|
}
|
|
/*explicit*/ CVssComBSTR(int nSize, LPCOLESTR sz)
|
|
{
|
|
m_str = ::SysAllocStringLen(sz, nSize);
|
|
if ((m_str == NULL) && (nSize != 0))
|
|
throw(E_OUTOFMEMORY);
|
|
}
|
|
/*explicit*/ CVssComBSTR(LPCOLESTR pSrc)
|
|
{
|
|
m_str = ::SysAllocString(pSrc);
|
|
if ((m_str == NULL) && (pSrc != NULL))
|
|
throw(E_OUTOFMEMORY);
|
|
}
|
|
/*explicit*/ CVssComBSTR(const CVssComBSTR& src)
|
|
{
|
|
m_str = src.Copy();
|
|
}
|
|
/*explicit*/ CVssComBSTR(REFGUID src)
|
|
{
|
|
LPOLESTR szGuid;
|
|
HRESULT hr = StringFromCLSID(src, &szGuid);
|
|
if (hr != S_OK)
|
|
throw(hr);
|
|
m_str = ::SysAllocString(szGuid);
|
|
CoTaskMemFree(szGuid);
|
|
if (m_str == NULL)
|
|
throw(E_OUTOFMEMORY);
|
|
}
|
|
CVssComBSTR& operator=(const CVssComBSTR& src)
|
|
{
|
|
if (m_str != src.m_str)
|
|
{
|
|
if (m_str)
|
|
::SysFreeString(m_str);
|
|
m_str = src.Copy();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
CVssComBSTR& operator=(LPCOLESTR pSrc)
|
|
{
|
|
::SysFreeString(m_str);
|
|
m_str = ::SysAllocString(pSrc);
|
|
if ((m_str == NULL) && (pSrc != NULL))
|
|
throw(E_OUTOFMEMORY);
|
|
return *this;
|
|
}
|
|
|
|
~CVssComBSTR()
|
|
{
|
|
::SysFreeString(m_str);
|
|
}
|
|
unsigned int Length() const
|
|
{
|
|
return (m_str == NULL)? 0 : SysStringLen(m_str);
|
|
}
|
|
operator BSTR() const
|
|
{
|
|
return m_str;
|
|
}
|
|
BSTR* operator&()
|
|
{
|
|
return &m_str;
|
|
}
|
|
BSTR Copy() const
|
|
{
|
|
BSTR str = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
|
|
if ((str == NULL) && (m_str != NULL))
|
|
throw(E_OUTOFMEMORY);
|
|
return str;
|
|
}
|
|
HRESULT CopyTo(BSTR* pbstr)
|
|
{
|
|
ATLASSERT(pbstr != NULL);
|
|
if (pbstr == NULL)
|
|
return E_POINTER;
|
|
*pbstr = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
|
|
if (*pbstr == NULL)
|
|
return E_OUTOFMEMORY;
|
|
return S_OK;
|
|
}
|
|
void Attach(BSTR src)
|
|
{
|
|
ATLASSERT(m_str == NULL);
|
|
m_str = src;
|
|
}
|
|
BSTR Detach()
|
|
{
|
|
BSTR s = m_str;
|
|
m_str = NULL;
|
|
return s;
|
|
}
|
|
void Empty()
|
|
{
|
|
::SysFreeString(m_str);
|
|
m_str = NULL;
|
|
}
|
|
bool operator!() const
|
|
{
|
|
return (m_str == NULL);
|
|
}
|
|
HRESULT Append(const CVssComBSTR& bstrSrc)
|
|
{
|
|
return Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));
|
|
}
|
|
HRESULT Append(LPCOLESTR lpsz)
|
|
{
|
|
return Append(lpsz, ocslen(lpsz));
|
|
}
|
|
// a BSTR is just a LPCOLESTR so we need a special version to signify
|
|
// that we are appending a BSTR
|
|
HRESULT AppendBSTR(BSTR p)
|
|
{
|
|
return Append(p, SysStringLen(p));
|
|
}
|
|
HRESULT Append(LPCOLESTR lpsz, int nLen)
|
|
{
|
|
int n1 = Length();
|
|
BSTR b;
|
|
b = ::SysAllocStringLen(NULL, n1+nLen);
|
|
if (b == NULL)
|
|
return E_OUTOFMEMORY;
|
|
memcpy(b, m_str, n1*sizeof(OLECHAR));
|
|
memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));
|
|
b[n1+nLen] = NULL;
|
|
SysFreeString(m_str);
|
|
m_str = b;
|
|
return S_OK;
|
|
}
|
|
HRESULT ToLower()
|
|
{
|
|
USES_CONVERSION;
|
|
if (m_str != NULL)
|
|
{
|
|
LPTSTR psz = CharLower(OLE2T(m_str));
|
|
if (psz == NULL)
|
|
return E_OUTOFMEMORY;
|
|
BSTR b = T2BSTR(psz);
|
|
if (b == NULL)
|
|
return E_OUTOFMEMORY;
|
|
SysFreeString(m_str);
|
|
m_str = b;
|
|
}
|
|
return S_OK;
|
|
}
|
|
HRESULT ToUpper()
|
|
{
|
|
USES_CONVERSION;
|
|
if (m_str != NULL)
|
|
{
|
|
LPTSTR psz = CharUpper(OLE2T(m_str));
|
|
if (psz == NULL)
|
|
return E_OUTOFMEMORY;
|
|
BSTR b = T2BSTR(psz);
|
|
if (b == NULL)
|
|
return E_OUTOFMEMORY;
|
|
SysFreeString(m_str);
|
|
m_str = b;
|
|
}
|
|
return S_OK;
|
|
}
|
|
bool LoadString(HINSTANCE hInst, UINT nID)
|
|
{
|
|
USES_CONVERSION;
|
|
TCHAR sz[512];
|
|
UINT nLen = ::LoadString(hInst, nID, sz, 512);
|
|
ATLASSERT(nLen < 511);
|
|
SysFreeString(m_str);
|
|
m_str = (nLen != 0) ? SysAllocString(T2OLE(sz)) : NULL;
|
|
return (nLen != 0);
|
|
}
|
|
bool LoadString(UINT nID)
|
|
{
|
|
return LoadString(_pModule->m_hInstResource, nID);
|
|
}
|
|
|
|
CVssComBSTR& operator+=(const CVssComBSTR& bstrSrc)
|
|
{
|
|
AppendBSTR(bstrSrc.m_str);
|
|
return *this;
|
|
}
|
|
bool operator<(BSTR bstrSrc) const
|
|
{
|
|
if (bstrSrc == NULL && m_str == NULL)
|
|
return false;
|
|
if (bstrSrc != NULL && m_str != NULL)
|
|
return wcscmp(m_str, bstrSrc) < 0;
|
|
return m_str == NULL;
|
|
}
|
|
bool operator!=(BSTR bstrSrc) const
|
|
{
|
|
return !((*this) == bstrSrc);
|
|
}
|
|
bool operator==(BSTR bstrSrc) const
|
|
{
|
|
if (bstrSrc == NULL && m_str == NULL)
|
|
return true;
|
|
if (bstrSrc != NULL && m_str != NULL)
|
|
return wcscmp(m_str, bstrSrc) == 0;
|
|
return false;
|
|
}
|
|
bool operator<(LPCSTR pszSrc) const
|
|
{
|
|
if (pszSrc == NULL && m_str == NULL)
|
|
return false;
|
|
USES_CONVERSION;
|
|
if (pszSrc != NULL && m_str != NULL)
|
|
return wcscmp(m_str, A2W(pszSrc)) < 0;
|
|
return m_str == NULL;
|
|
}
|
|
bool operator!=(LPCSTR pszSrc) const
|
|
{
|
|
return !((*this) == pszSrc);
|
|
}
|
|
bool operator==(LPCSTR pszSrc) const
|
|
{
|
|
if (pszSrc == NULL && m_str == NULL)
|
|
return true;
|
|
USES_CONVERSION;
|
|
if (pszSrc != NULL && m_str != NULL)
|
|
return wcscmp(m_str, A2W(pszSrc)) == 0;
|
|
return false;
|
|
}
|
|
#ifndef OLE2ANSI
|
|
CVssComBSTR(LPCSTR pSrc)
|
|
{
|
|
m_str = A2WBSTR(pSrc);
|
|
}
|
|
|
|
CVssComBSTR(int nSize, LPCSTR sz)
|
|
{
|
|
m_str = A2WBSTR(sz, nSize);
|
|
}
|
|
|
|
void Append(LPCSTR lpsz)
|
|
{
|
|
USES_CONVERSION;
|
|
LPCOLESTR lpo = A2COLE(lpsz);
|
|
Append(lpo, ocslen(lpo));
|
|
}
|
|
|
|
CVssComBSTR& operator=(LPCSTR pSrc)
|
|
{
|
|
::SysFreeString(m_str);
|
|
m_str = A2WBSTR(pSrc);
|
|
return *this;
|
|
}
|
|
#endif
|
|
HRESULT WriteToStream(IStream* pStream)
|
|
{
|
|
ATLASSERT(pStream != NULL);
|
|
ULONG cb;
|
|
ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+(ULONG)sizeof(OLECHAR) : 0;
|
|
HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
|
|
}
|
|
HRESULT ReadFromStream(IStream* pStream)
|
|
{
|
|
ATLASSERT(pStream != NULL);
|
|
ATLASSERT(m_str == NULL); // should be empty
|
|
ULONG cbStrLen = 0;
|
|
HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);
|
|
if ((hr == S_OK) && (cbStrLen != 0))
|
|
{
|
|
//subtract size for terminating NULL which we wrote out
|
|
//since SysAllocStringByteLen overallocates for the NULL
|
|
m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
|
|
if (m_str == NULL)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
hr = pStream->Read((void*) m_str, cbStrLen, NULL);
|
|
}
|
|
if (hr == S_FALSE)
|
|
hr = E_FAIL;
|
|
return hr;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // __VSS_STR_HXX__
|